PMFlow/backend/app/core/config.py

100 lines
4.0 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

"""
核心配置
集中管理环境变量和应用配置,遵循 12-factor 原则。
"""
import os
from pathlib import Path
from typing import Optional
try:
from dotenv import load_dotenv
except ModuleNotFoundError: # pragma: no cover - optional dependency in lightweight envs
def load_dotenv(*_args, **_kwargs):
return False
# 仅从项目根目录 .env 加载,作为唯一配置源
BACKEND_DIR = Path(__file__).resolve().parents[2]
PROJECT_ROOT = BACKEND_DIR.parent
load_dotenv(PROJECT_ROOT / ".env", override=False)
# 默认数据库固定到 Docker PostgreSQL,不再提供 SQLite 回落
DEFAULT_DB_HOST = os.getenv("DB_HOST", "127.0.0.1")
DEFAULT_DB_PORT = os.getenv("DB_PORT", "5435")
DEFAULT_DB_NAME = os.getenv("POSTGRES_DB", "pmflow")
DEFAULT_DB_USER = os.getenv("POSTGRES_USER", "pmflow")
DEFAULT_DB_PASSWORD = os.getenv("POSTGRES_PASSWORD", "pmflow_pass")
DEFAULT_DATABASE_URL = (
f"postgresql+asyncpg://{DEFAULT_DB_USER}:{DEFAULT_DB_PASSWORD}"
f"@{DEFAULT_DB_HOST}:{DEFAULT_DB_PORT}/{DEFAULT_DB_NAME}"
)
TRUE_VALUES = {"true", "1", "yes", "on"}
DEBUG_ENABLED = os.getenv("DEBUG", "false").lower() in TRUE_VALUES
def _env_flag(name: str, default: bool) -> bool:
raw = os.getenv(name)
if raw is None:
return default
return raw.strip().lower() in TRUE_VALUES
def _env_csv(name: str) -> tuple[str, ...]:
raw = os.getenv(name, "")
return tuple(item.strip() for item in raw.split(",") if item.strip())
class Settings:
"""应用配置(从环境变量读取)"""
# 应用
app_name: str = os.getenv("APP_NAME", "Neural Sync API")
debug: bool = DEBUG_ENABLED
startup_model_probe_enabled: bool = _env_flag("STARTUP_MODEL_PROBE_ENABLED", not DEBUG_ENABLED)
feishu_long_connection_enabled: bool = _env_flag("FEISHU_LONG_CONNECTION_ENABLED", not DEBUG_ENABLED)
world_model_warmup_enabled: bool = _env_flag("STARTUP_WORLD_MODEL_WARMUP_ENABLED", not DEBUG_ENABLED)
schedulers_enabled: bool = _env_flag("STARTUP_SCHEDULERS_ENABLED", True)
background_workers_enabled: bool = _env_flag("STARTUP_BACKGROUND_WORKERS_ENABLED", True)
api_route_profile: str = os.getenv("API_ROUTE_PROFILE", "full").strip().lower() or "full"
api_optional_route_groups: tuple[str, ...] = _env_csv("API_OPTIONAL_ROUTE_GROUPS")
# 数据库
database_url: str = os.getenv("DATABASE_URL", DEFAULT_DATABASE_URL)
db_pool_size: int = int(os.getenv("DB_POOL_SIZE", "20"))
db_max_overflow: int = int(os.getenv("DB_MAX_OVERFLOW", "40"))
db_pool_timeout: int = int(os.getenv("DB_POOL_TIMEOUT", "30"))
db_pool_recycle: int = int(os.getenv("DB_POOL_RECYCLE", "1800"))
# JWT
secret_key: str = os.getenv("SECRET_KEY", "your-secret-key-change-in-production")
algorithm: str = os.getenv("JWT_ALGORITHM", "HS256")
access_token_expire_minutes: int = int(os.getenv("ACCESS_TOKEN_EXPIRE_MINUTES", str(60 * 24 * 7)))
# CORS
cors_origins: str = os.getenv("CORS_ORIGINS", "*")
# LLM
llm_provider: str = os.getenv("LLM_PROVIDER", "ollama").lower()
ollama_host: str = os.getenv("OLLAMA_HOST", "http://127.0.0.1:11434")
business_context: Optional[str] = os.getenv("BUSINESS_CONTEXT")
# Redis(可选,用于 AI 结果缓存)
redis_url: Optional[str] = os.getenv("REDIS_URL")
# 多租户(预留)
default_tenant_id: str = os.getenv("DEFAULT_TENANT_ID", "default")
# GitHub App
github_app_slug: Optional[str] = os.getenv("GITHUB_APP_SLUG")
github_app_install_url: Optional[str] = os.getenv("GITHUB_APP_INSTALL_URL")
github_app_callback_url: Optional[str] = os.getenv("GITHUB_APP_CALLBACK_URL")
github_app_webhook_secret: Optional[str] = os.getenv("GITHUB_APP_WEBHOOK_SECRET")
github_app_sync_endpoint: Optional[str] = os.getenv("GITHUB_APP_SYNC_ENDPOINT")
github_app_sync_token: Optional[str] = os.getenv("GITHUB_APP_SYNC_TOKEN")
github_app_installations_fixture: Optional[str] = os.getenv("GITHUB_APP_INSTALLATIONS_FIXTURE")
# 全局配置实例
settings = Settings()