"""应用配置(env 解析)。提供商注册/档位默认见后续阶段。""" from __future__ import annotations from functools import lru_cache from pydantic import SecretStr, field_validator from pydantic_settings import BaseSettings, SettingsConfigDict class Settings(BaseSettings): model_config = SettingsConfigDict(env_file=".env", extra="ignore") app_env: str = "dev" log_json: bool = False database_url: str = "postgresql+asyncpg://writer:writer@localhost:5432/writer" database_url_sync: str = "postgresql+psycopg://writer:writer@localhost:5432/writer" # 提供商凭据对称加密 key(Fernet)。用 SecretStr 防误序列化/误入日志; # 取明文须显式 `.get_secret_value()`。启动校验见 `main._lifespan`。 credential_enc_key: SecretStr = SecretStr("") # 浏览器端跨源访问(前端 :3000 → API :8000)放行的来源;env `CORS_ORIGINS` 逗号分隔覆盖。 cors_origins: list[str] = [ "http://localhost:3000", "http://127.0.0.1:3000", ] @field_validator("cors_origins", mode="before") @classmethod def _split_csv_origins(cls, v: object) -> object: if isinstance(v, str): return [s.strip() for s in v.split(",") if s.strip()] return v # 档位默认(writer/analyst/light)——具体 provider:model 经 tier_routing 覆盖 tier_defaults: dict[str, str] = { "writer": "deepseek:deepseek-chat", "analyst": "deepseek:deepseek-chat", "light": "deepseek:deepseek-chat", } @lru_cache def get_settings() -> Settings: return Settings()