75 lines
2.2 KiB
Python
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
|