from pydantic import Field, field_validator 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_name: str = "VPN Control Panel" debug: bool = False port: int = 8000 postgres_user: str = Field(default="vpn", alias="POSTGRES_USER") postgres_password: str = Field(default="vpn_secret", alias="POSTGRES_PASSWORD") postgres_db: str = Field(default="vpn_control", alias="POSTGRES_DB") postgres_host: str = Field(default="localhost", alias="POSTGRES_HOST") postgres_port: int = Field(default=5432, alias="POSTGRES_PORT") @property def database_url(self) -> str: return ( f"postgresql+asyncpg://{self.postgres_user}:{self.postgres_password}" f"@{self.postgres_host}:{self.postgres_port}/{self.postgres_db}" ) @property def database_url_sync(self) -> str: return ( f"postgresql://{self.postgres_user}:{self.postgres_password}" f"@{self.postgres_host}:{self.postgres_port}/{self.postgres_db}" ) redis_url: str = "redis://localhost:6379/0" bot_token: str = "" admin_ids: list[int] = Field(default_factory=list) admin_group_id: int = 0 admin_group_thread_id: int | None = None jwt_secret: str = "change_me" jwt_algorithm: str = "HS256" jwt_access_expire_minutes: int = 30 jwt_refresh_expire_days: int = 30 outline_api_prefix: str = "" outline_cert_sha256: str = "" @field_validator("admin_group_thread_id", mode="before") @classmethod def _parse_admin_thread(cls, v): if v == "" or v is None: return None return int(v) settings = Settings()