#!/usr/bin/env python3 """ 项目配置管理模块 从环境变量 (.env) 文件中安全地加载配置和密钥。 """ import os from typing import Optional, Dict, Any from pathlib import Path # 确保 .env 文件在项目根目录被加载 try: from dotenv import load_dotenv # 构建到项目根目录的路径 (假设此文件在 config/ 目录下) env_path = Path(__file__).resolve().parents[1] / '.env' if env_path.exists(): load_dotenv(dotenv_path=env_path) else: print("Warning: .env file not found at project root. Relying on system environment variables.") except ImportError: print("Warning: python-dotenv not installed. Relying on system environment variables.") pass def get_secret(key: str, default: Optional[str] = None) -> str: """ 从环境变量获取密钥。 Args: key: 密钥名称 default: 如果未找到密钥,则返回的默认值 Returns: 密钥值 Raises: ValueError: 如果密钥未找到且没有提供默认值。 """ value = os.getenv(key) if value is not None: return value if default is not None: return default raise ValueError(f"Required secret '{key}' not found in environment variables. " "Please ensure it is set in your .env file or system environment.") def get_rapidapi_key() -> str: return get_secret('RAPIDAPI_KEY') def get_openrouter_key() -> str: return get_secret('OPENROUTER_API_KEY_1') def get_google_api_key() -> str: return get_secret('GOOGLE_API_KEY') def get_google_genai_config() -> Dict[str, Any]: """ 获取Google GenAI完整配置 """ use_vertex_ai = get_secret('GOOGLE_GENAI_USE_VERTEXAI', 'FALSE').upper() == 'TRUE' return { 'api_key': get_secret('GOOGLE_API_KEY', '') if not use_vertex_ai else '', 'use_vertex_ai': use_vertex_ai, 'project_id': get_secret('GOOGLE_CLOUD_PROJECT_ID', ''), 'location': get_secret('GOOGLE_CLOUD_LOCATION', 'us-central1'), 'memory_bank_enabled': get_secret('VERTEX_MEMORY_BANK_ENABLED', 'TRUE').upper() == 'TRUE', 'service_account_key': get_secret('GOOGLE_SERVICE_ACCOUNT_KEY', '') } def get_cloudflare_config() -> Dict[str, str]: """ 获取Cloudflare配置 """ return { 'account_id': get_secret('CLOUDFLARE_ACCOUNT_ID', ''), 'api_token': get_secret('CLOUDFLARE_API_TOKEN', ''), 'vectorize_index': 'autorag-shy-cherry-f1fb', 'embed_model': '@cf/baai/bge-m3', 'autorag_domain': 'autorag.seekkey.tech' } def get_database_config() -> Dict[str, str]: """ 获取数据库配置 """ return { 'postgres_url': get_secret('POSTGRES_URL', ''), 'mongodb_url': get_secret('MONGODB_URL', ''), 'zilliz_url': get_secret('ZILLIZ_URL', ''), 'zilliz_token': get_secret('ZILLIZ_TOKEN', '') } def validate_config(mode: str = "hybrid") -> bool: """ 验证必要的配置是否存在 """ print(f"🔧 Validating configuration for mode: {mode}") try: if mode == "openrouter": get_openrouter_key() print("✅ OpenRouter configuration is valid.") elif mode == "google_adk": config = get_google_genai_config() if not config['use_vertex_ai']: get_google_api_key() else: if not config['project_id']: raise ValueError("GOOGLE_CLOUD_PROJECT_ID is required for Vertex AI") print("✅ Google ADK configuration is valid.") elif mode == "hybrid": # In hybrid, we just need at least one to be available key_found = False try: get_openrouter_key() print("✅ OpenRouter key found.") key_found = True except ValueError: pass # It's ok if this one is missing try: google_config = get_google_genai_config() if not google_config['use_vertex_ai']: get_google_api_key() print("✅ Google ADK key found.") key_found = True except ValueError: pass # It's ok if this one is missing if not key_found: raise ValueError("In hybrid mode, at least one AI provider key (OpenRouter or Google) must be configured.") print("✅ Hybrid mode configuration is valid.") return True except ValueError as e: print(f"❌ Configuration validation failed: {e}") return False if __name__ == "__main__": print("🔧 Running configuration validation...") validate_config()