05f07ee544
Simplify runtime configuration and remove legacy database and settings surface so new installs are easier to operate. Refresh deployment assets, docs, and order execution behavior to keep the packaged app aligned with the current backend. Made-with: Cursor
113 lines
3.9 KiB
Python
113 lines
3.9 KiB
Python
"""
|
|
API key configuration.
|
|
All third-party keys should be provided via environment variables (recommended: backend_api_python/.env).
|
|
"""
|
|
import os
|
|
|
|
class MetaAPIKeys(type):
|
|
"""API Keys 元类,用于支持类属性的动态获取"""
|
|
|
|
@property
|
|
def FINNHUB_API_KEY(cls):
|
|
from app.utils.config_loader import load_addon_config
|
|
val = load_addon_config().get('finnhub', {}).get('api_key')
|
|
return val if val else os.getenv('FINNHUB_API_KEY', '')
|
|
|
|
@property
|
|
def TIINGO_API_KEY(cls):
|
|
from app.utils.config_loader import load_addon_config
|
|
val = load_addon_config().get('tiingo', {}).get('api_key')
|
|
return val if val else os.getenv('TIINGO_API_KEY', '')
|
|
|
|
@property
|
|
def OPENROUTER_API_KEY(cls):
|
|
# Always check env var first to avoid stale cache issues
|
|
env_val = os.getenv('OPENROUTER_API_KEY', '').strip()
|
|
if env_val:
|
|
return env_val
|
|
from app.utils.config_loader import load_addon_config
|
|
val = load_addon_config().get('openrouter', {}).get('api_key')
|
|
return val if val else ''
|
|
|
|
@property
|
|
def OPENAI_API_KEY(cls):
|
|
"""OpenAI direct API key"""
|
|
env_val = os.getenv('OPENAI_API_KEY', '').strip()
|
|
if env_val:
|
|
return env_val
|
|
from app.utils.config_loader import load_addon_config
|
|
val = load_addon_config().get('openai', {}).get('api_key')
|
|
return val if val else ''
|
|
|
|
@property
|
|
def GOOGLE_API_KEY(cls):
|
|
"""Google Gemini API key"""
|
|
env_val = os.getenv('GOOGLE_API_KEY', '').strip()
|
|
if env_val:
|
|
return env_val
|
|
from app.utils.config_loader import load_addon_config
|
|
val = load_addon_config().get('google', {}).get('api_key')
|
|
return val if val else ''
|
|
|
|
@property
|
|
def DEEPSEEK_API_KEY(cls):
|
|
"""DeepSeek API key"""
|
|
env_val = os.getenv('DEEPSEEK_API_KEY', '').strip()
|
|
if env_val:
|
|
return env_val
|
|
from app.utils.config_loader import load_addon_config
|
|
val = load_addon_config().get('deepseek', {}).get('api_key')
|
|
return val if val else ''
|
|
|
|
@property
|
|
def GROK_API_KEY(cls):
|
|
"""xAI Grok API key"""
|
|
env_val = os.getenv('GROK_API_KEY', '').strip()
|
|
if env_val:
|
|
return env_val
|
|
from app.utils.config_loader import load_addon_config
|
|
val = load_addon_config().get('grok', {}).get('api_key')
|
|
return val if val else ''
|
|
|
|
@property
|
|
def TAVILY_API_KEYS(cls):
|
|
"""Tavily Search API keys (comma-separated for rotation)"""
|
|
env_val = os.getenv('TAVILY_API_KEYS', '').strip()
|
|
if env_val:
|
|
return [k.strip() for k in env_val.split(',') if k.strip()]
|
|
from app.utils.config_loader import load_addon_config
|
|
val = load_addon_config().get('tavily', {}).get('api_keys', '')
|
|
if val:
|
|
return [k.strip() for k in val.split(',') if k.strip()]
|
|
return []
|
|
|
|
@property
|
|
def SERPAPI_KEYS(cls):
|
|
"""SerpAPI keys (comma-separated for rotation)"""
|
|
env_val = os.getenv('SERPAPI_KEYS', '').strip()
|
|
if env_val:
|
|
return [k.strip() for k in env_val.split(',') if k.strip()]
|
|
from app.utils.config_loader import load_addon_config
|
|
val = load_addon_config().get('serpapi', {}).get('api_keys', '')
|
|
if val:
|
|
return [k.strip() for k in val.split(',') if k.strip()]
|
|
return []
|
|
|
|
|
|
class APIKeys(metaclass=MetaAPIKeys):
|
|
"""API 密钥配置类"""
|
|
|
|
@classmethod
|
|
def get(cls, key_name: str, default: str = '') -> str:
|
|
"""获取 API 密钥"""
|
|
# 尝试从类属性获取
|
|
if hasattr(cls, key_name):
|
|
return getattr(cls, key_name)
|
|
return default
|
|
|
|
@classmethod
|
|
def is_configured(cls, key_name: str) -> bool:
|
|
"""检查 API 密钥是否已配置"""
|
|
value = cls.get(key_name)
|
|
return bool(value and value.strip())
|