from functools import lru_cache from pydantic import Field, SecretStr, field_validator from pydantic_settings import BaseSettings, SettingsConfigDict class Settings(BaseSettings): """Конфигурация приложения с обязательными production-секретами.""" database_url: str secret_key: SecretStr = Field(min_length=32) access_token_expire_minutes: int = Field(default=30, ge=5, le=1440) allow_origins: str = "" pve_host: str pve_node: str = "pve" pve_token_name: str pve_token_value: SecretStr pve_verify_ssl: bool = True environment: str = "production" model_config = SettingsConfigDict( env_file=".env", env_file_encoding="utf-8", extra="ignore", ) @field_validator("secret_key") @classmethod def reject_placeholder_secret(cls, value: SecretStr) -> SecretStr: """Запрещает запуск с очевидным демонстрационным секретом.""" if value.get_secret_value() in {"change-me", "generate-a-long-random-value"}: raise ValueError("SECRET_KEY must be replaced") return value @lru_cache def get_settings() -> Settings: """Возвращает единый экземпляр конфигурации.""" return Settings() settings = get_settings()