"""全局配置。 用 pydantic-settings 从环境变量 + .env 文件加载。所有可调参数集中在这里, 业务代码通过 `from app.core.config import settings` 引用,不再读 os.environ。 """ from __future__ import annotations from functools import lru_cache from typing import Literal from pydantic import Field from pydantic_settings import BaseSettings, SettingsConfigDict class Settings(BaseSettings): model_config = SettingsConfigDict( env_file=".env", env_file_encoding="utf-8", case_sensitive=False, extra="ignore", ) # ===== 环境 ===== APP_ENV: Literal["dev", "prod"] = "dev" APP_NAME: str = "shaguabijia-app-server" APP_DEBUG: bool = True # ===== 数据库 ===== DATABASE_URL: str = "sqlite:///./data/app.db" # ===== JWT ===== JWT_SECRET_KEY: str = "change-me" JWT_ALGORITHM: str = "HS256" JWT_ACCESS_TOKEN_EXPIRE_MINUTES: int = 120 JWT_REFRESH_TOKEN_EXPIRE_DAYS: int = 30 # ===== 极光 ===== JG_APP_KEY: str = "" JG_MASTER_SECRET: str = "" JG_PRIVATE_KEY_PATH: str = "./secrets/jverify_rsa_private.pem" JG_VERIFY_ENDPOINT: str = "https://api.verification.jpush.cn/v1/web/loginTokenVerify" JG_REQUEST_TIMEOUT_SEC: int = 15 # ===== 短信 ===== SMS_MOCK: bool = True SMS_CODE_TTL_SEC: int = 300 SMS_SEND_INTERVAL_SEC: int = 60 # ===== CORS ===== CORS_ALLOW_ORIGINS: str = "" @property def cors_origins_list(self) -> list[str]: if not self.CORS_ALLOW_ORIGINS.strip(): return [] return [o.strip() for o in self.CORS_ALLOW_ORIGINS.split(",") if o.strip()] @property def is_prod(self) -> bool: return self.APP_ENV == "prod" @lru_cache(maxsize=1) def get_settings() -> Settings: return Settings() settings = get_settings()