diff --git a/backend/app/config.py b/backend/app/config.py new file mode 100644 index 0000000..dce4191 --- /dev/null +++ b/backend/app/config.py @@ -0,0 +1,42 @@ +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()