#!/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()