Files
wehub-resource-sync 7a0da7932b
Backwards Compatibility / Verify Encryption Constants (push) Waiting to run
Backwards Compatibility / PyPI Version Compatibility (push) Waiting to run
Backwards Compatibility / Database Migration Tests (push) Waiting to run
CodeQL Advanced / Analyze (javascript-typescript) (push) Waiting to run
CodeQL Advanced / Analyze (python) (push) Waiting to run
Docker Tests (Consolidated) / UI Tests (Puppeteer) [research-form] (push) Blocked by required conditions
Docker Tests (Consolidated) / UI Tests (Puppeteer) [research-metrics] (push) Blocked by required conditions
Docker Tests (Consolidated) / UI Tests (Puppeteer) [research-workflow] (push) Blocked by required conditions
Docker Tests (Consolidated) / UI Tests (Puppeteer) [settings-core] (push) Blocked by required conditions
Docker Tests (Consolidated) / UI Tests (Puppeteer) [settings-pages] (push) Blocked by required conditions
Docker Tests (Consolidated) / UI Tests (Puppeteer) [history-news] (push) Blocked by required conditions
Docker Tests (Consolidated) / UI Tests (Puppeteer) [library] (push) Blocked by required conditions
Docker Tests (Consolidated) / UI Tests (Puppeteer) [link-analytics] (push) Blocked by required conditions
Docker Tests (Consolidated) / UI Tests (Puppeteer) [mobile] (push) Blocked by required conditions
Docker Tests (Consolidated) / detect-changes (push) Waiting to run
Docker Tests (Consolidated) / Build Test Image (push) Waiting to run
Docker Tests (Consolidated) / All Pytest Tests + Coverage (push) Blocked by required conditions
Docker Tests (Consolidated) / UI Tests (Puppeteer) [accessibility] (push) Blocked by required conditions
Docker Tests (Consolidated) / UI Tests (Puppeteer) [api-crud] (push) Blocked by required conditions
Docker Tests (Consolidated) / UI Tests (Puppeteer) [auth-login] (push) Blocked by required conditions
Docker Tests (Consolidated) / UI Tests (Puppeteer) [auth-pages] (push) Blocked by required conditions
Docker Tests (Consolidated) / UI Tests (Puppeteer) [auth-register] (push) Blocked by required conditions
Docker Tests (Consolidated) / UI Tests (Puppeteer) [chat-core] (push) Blocked by required conditions
Docker Tests (Consolidated) / UI Tests (Puppeteer) [chat-lifecycle] (push) Blocked by required conditions
Docker Tests (Consolidated) / UI Tests (Puppeteer) [error-benchmark] (push) Blocked by required conditions
Docker Tests (Consolidated) / UI Tests (Puppeteer) (push) Blocked by required conditions
Docker Tests (Consolidated) / Accessibility Tests (push) Blocked by required conditions
Docker Tests (Consolidated) / LLM Unit Tests (push) Blocked by required conditions
Docker Tests (Consolidated) / LLM Example Tests (push) Blocked by required conditions
Docker Tests (Consolidated) / Production Image Smoke Test (push) Blocked by required conditions
Docker Tests (Consolidated) / Infrastructure Tests (push) Blocked by required conditions
OSSF Scorecard / OSSF Security Scorecard Analysis (push) Waiting to run
OSV-Scanner (Scheduled) / scan-scheduled (push) Failing after 0s
Create Release / test-gate (push) Has been cancelled
Create Release / release-gate (push) Has been cancelled
Create Release / ci-gate (push) Has been cancelled
Create Release / version-check (push) Has been cancelled
Create Release / e2e-test-gate (push) Has been cancelled
Create Release / responsive-test-gate (push) Has been cancelled
Create Release / compat-test-gate (push) Has been cancelled
Create Release / compose-integration-gate (push) Has been cancelled
Create Release / vulture-gate (push) Has been cancelled
Create Release / build (push) Has been cancelled
Create Release / provenance (push) Has been cancelled
Create Release / prerelease-docker (push) Has been cancelled
Create Release / publish-docker (push) Has been cancelled
Create Release / create-release (push) Has been cancelled
Create Release / cleanup-changelog (push) Has been cancelled
Create Release / trigger-pypi (push) Has been cancelled
Create Release / monitor-pypi (push) Has been cancelled
Create Release / Clean up orphan prerelease tags and signatures (push) Has been cancelled
chore: import upstream snapshot with attribution
2026-07-13 13:08:55 +08:00

264 lines
9.0 KiB
Python
Executable File

#!/usr/bin/env python3
"""
pytest: skip
This is an end-to-end test script, not a pytest test.
End-to-end test script for verifying OpenAI API key configuration.
This script helps users verify that their OpenAI API key is properly configured
and working with Local Deep Research.
Usage:
python tests/test_openai_api_key_e2e.py --username YOUR_USERNAME --password YOUR_PASSWORD --api-key YOUR_LDR_LLM_OPENAI_API_KEY
Or set environment variables:
export LDR_USERNAME=your_username
export LDR_PASSWORD=your_password
export LDR_LLM_OPENAI_API_KEY=your_api_key
python tests/test_openai_api_key_e2e.py
"""
import argparse
import os
import sys
from pathlib import Path
from typing import Optional
# Add project root to path
sys.path.insert(0, str(Path(__file__).parent.parent.resolve()))
from local_deep_research.database.session_context import get_user_db_session
from local_deep_research.config.llm_config import get_llm
from local_deep_research.api.research_functions import quick_summary
from local_deep_research.settings import SettingsManager
from loguru import logger
import pytest
# Skip this entire module in pytest
pytestmark = pytest.mark.skip(
reason="End-to-end test script, not a pytest test"
)
def test_openai_api_key_e2e(
username: str, password: str, api_key: Optional[str] = None
) -> bool:
"""
Test OpenAI API key configuration and usage.
Args:
username: LDR username
password: LDR password
api_key: OpenAI API key (optional, can use env var)
Returns:
bool: True if test passed, False otherwise
"""
# audit: PUNCHLIST reviewed 2026-05 — issue resolved by prior PR (recommendation: rename file out of test_ prefix).
print("=" * 60)
print("OpenAI API Key Configuration Test")
print("=" * 60)
try:
# Step 1: Authenticate
print("\n1. Authenticating with LDR...")
with get_user_db_session(
username=username, password=password
) as session:
print(" ✓ Authentication successful")
# Step 2: Configure settings
print("\n2. Configuring OpenAI settings...")
settings_manager = SettingsManager(session)
# Set OpenAI as provider
settings_manager.set_setting("llm.provider", "openai")
print(" ✓ Set provider to OpenAI")
# Set API key if provided
if api_key:
settings_manager.set_setting("llm.openai.api_key", api_key)
print(" ✓ Set OpenAI API key")
else:
# Check if API key exists in settings or environment
existing_key = settings_manager.get_setting(
"llm.openai.api_key"
)
env_key = os.getenv("LDR_LLM_OPENAI_API_KEY")
if not existing_key and not env_key:
print(" ✗ No API key found in settings or environment")
print(
" Please provide --api-key or set LDR_LLM_OPENAI_API_KEY environment variable"
)
return False
if existing_key:
print(" ✓ Using existing API key from settings")
else:
print(" ✓ Using API key from environment variable")
# Set model
settings_manager.set_setting("llm.model", "gpt-3.5-turbo")
print(" ✓ Set model to gpt-3.5-turbo")
# Get settings snapshot
settings_snapshot = settings_manager.get_all_settings()
# Step 3: Test LLM initialization
print("\n3. Testing LLM initialization...")
try:
llm = get_llm(settings_snapshot=settings_snapshot)
print(" ✓ LLM initialized successfully")
except Exception as e:
print(f" ✗ Failed to initialize LLM: {str(e)}")
if "api key" in str(e).lower():
print(" This appears to be an API key issue")
return False
# Step 4: Test simple LLM call
print("\n4. Testing LLM response...")
try:
from langchain_core.messages.human import HumanMessage
response = llm.invoke(
[
HumanMessage(
content="Say 'Hello, LDR!' in 5 words or less"
)
]
)
print(f" ✓ LLM responded: {response.content}")
except Exception as e:
print(f" ✗ Failed to get LLM response: {str(e)}")
if "401" in str(e) or "unauthorized" in str(e).lower():
print(" API key appears to be invalid")
elif "429" in str(e):
print(
" Rate limit exceeded - API key is valid but quota exhausted"
)
return False
# Step 5: Test research functionality
print("\n5. Testing research functionality...")
try:
result = quick_summary(
query="What is the capital of France?",
settings_snapshot=settings_snapshot,
iterations=1,
questions_per_iteration=1,
search_tool="wikipedia", # Use Wikipedia to avoid web search rate limits
)
print(" ✓ Research completed successfully")
print(f" Research ID: {result.get('research_id', 'N/A')}")
print(
f" Summary preview: {result.get('summary', '')[:100]}..."
)
if "paris" in result.get("summary", "").lower():
print(" ✓ Result contains expected content")
else:
print(" ⚠ Result may not contain expected content")
except Exception as e:
print(f" ✗ Failed to complete research: {str(e)}")
return False
# Success!
print("\n" + "=" * 60)
print(
"✅ All tests passed! Your OpenAI API key is configured correctly."
)
print("=" * 60)
# Show configuration summary
print("\nCurrent Configuration:")
print(
f" Provider: {settings_snapshot.get('llm.provider', {}).get('value', 'Not set')}"
)
print(
f" Model: {settings_snapshot.get('llm.model', {}).get('value', 'Not set')}"
)
print(f" API Key: {'*' * 20} (hidden)")
return True
except Exception as e:
print(f"\n✗ Unexpected error: {str(e)}")
logger.exception("Test failed with exception")
return False
def main():
"""Main entry point for the test script."""
parser = argparse.ArgumentParser(
description="Test OpenAI API key configuration with Local Deep Research",
formatter_class=argparse.RawDescriptionHelpFormatter,
epilog="""
Examples:
# With command line arguments
python test_openai_api_key_e2e.py --username myuser --password mypass --api-key sk-...
# With environment variables
export LDR_USERNAME=myuser
export LDR_PASSWORD=mypass
export LDR_LLM_OPENAI_API_KEY=sk-...
python test_openai_api_key_e2e.py
Note: The LDR server must be running and you must have a user account created.
""",
)
parser.add_argument(
"--username",
default=os.getenv("LDR_USERNAME"),
help="LDR username (or set LDR_USERNAME env var)",
)
parser.add_argument(
"--password",
default=os.getenv("LDR_PASSWORD"),
help="LDR password (or set LDR_PASSWORD env var)",
)
parser.add_argument(
"--api-key",
default=os.getenv("LDR_LLM_OPENAI_API_KEY"),
help="OpenAI API key (or set LDR_LLM_OPENAI_API_KEY env var)",
)
parser.add_argument(
"--verbose", action="store_true", help="Enable verbose logging"
)
args = parser.parse_args()
# Validate required arguments
if not args.username or not args.password:
print("Error: Username and password are required")
print(
"Provide them via --username/--password or LDR_USERNAME/LDR_PASSWORD env vars"
)
parser.print_help()
sys.exit(1)
# Configure logging
if not args.verbose:
logger.remove() # Remove default handler
# diagnose=False: this e2e harness passes args.api_key and
# args.password into the test function — both end up as frame locals
# that loguru's default diagnose=True would dump into error tracebacks
# (#4185 / #4384).
logger.add(sys.stderr, level="ERROR", diagnose=False)
# Run the test
success = test_openai_api_key_e2e(
username=args.username, password=args.password, api_key=args.api_key
)
# Exit with appropriate code
sys.exit(0 if success else 1)
if __name__ == "__main__":
main()