Files
amb_rag/backend/app/core/config.py
T
2026-09-02 11:19:49 +08:00

75 lines
2.2 KiB
Python

"""全局配置:pydantic-settings,全部来自环境变量 / .env。
规则:
- 密钥不得硬编码;SECRET_KEY 缺失或仍为模板值时,生产环境拒绝启动。
- DATABASE_URL 支持 MySQL / SQLite。
"""
from functools import lru_cache
from pathlib import Path
from pydantic import Field
from pydantic_settings import BaseSettings, SettingsConfigDict
_TEMPLATE_MARKERS = ("change-me",)
class Settings(BaseSettings):
model_config = SettingsConfigDict(env_file=".env", env_file_encoding="utf-8", extra="ignore")
# --- 基础 ---
environment: str = "local" # local / production
secret_key: str = Field(min_length=16)
# --- 数据库 ---
database_url: str = "mysql+pymysql://admin:Lzcc6-01@47.109.98.44:33306/amb_rag?charset=utf8mb4"
# --- 文件存储 ---
storage_root: str = "./data"
# --- 套餐 ---
default_storage_quota: int = 104_857_600 # 100 MB
default_max_file_size: int = 20_971_520 # 20 MB
# --- 限流 ---
rate_limit_per_token_per_min: int = 60
rate_limit_per_ip_per_min: int = 30
# --- CORS ---
frontend_origin: str = "http://localhost:5173"
@property
def is_production(self) -> bool:
return self.environment == "production"
@property
def is_mysql(self) -> bool:
return "mysql" in self.database_url
@property
def is_sqlite(self) -> bool:
return "sqlite" in self.database_url
@property
def storage_root_path(self) -> Path:
return Path(self.storage_root).resolve()
def validate_secrets(self) -> None:
"""生产环境禁止携带模板密钥启动。"""
if not self.is_production:
return
for field_name in ("secret_key",):
value = getattr(self, field_name).lower()
if any(marker in value for marker in _TEMPLATE_MARKERS):
raise RuntimeError(
f"配置错误:{field_name} 仍为模板值,生产环境禁止启动。"
"请运行: python -c \"import secrets; print(secrets.token_urlsafe(48))\""
)
@lru_cache
def get_settings() -> Settings:
s = Settings() # type: ignore[call-arg]
s.validate_secrets()
return s