import pathlib from typing import Literal, Any from pydantic_core._pydantic_core import ValidationError from pydantic_settings import BaseSettings, SettingsConfigDict from sqlalchemy import URL from fansifter_common.utils.functional import lazy_proxy class Settings(BaseSettings): # Directories base_dir: pathlib.Path = pathlib.Path(__file__).resolve().parent root_dir: pathlib.Path = base_dir.parent model_config = SettingsConfigDict(env_file=root_dir / ".env") # Postgres postgres_user: str = "postgres" postgres_password: str = "postgres" postgres_host: str = "localhost" postgres_port: int = 5433 postgres_name: str = "streamlit_db" postgres_echo: bool = False postgres_pool_size: int = 10 postgres_pool_max_overflow: int = 20 postgres_pool_recycle: int = 4 * 60 * 60 # ~4 hours postgres_pool_pre_ping: bool = False postgres_pool_reset_on_return: Literal["commit", "rollback"] | None = None postgres_connect_args: dict[str, Any] = { "keepalives": 1, "keepalives_idle": 60, "keepalives_interval": 10, "keepalives_count": 5, } @property def postgres_url(self) -> URL: return URL.create( drivername="postgresql+psycopg", username=self.postgres_user, password=self.postgres_password, host=self.postgres_host, port=self.postgres_port, database=self.postgres_name, ) assets_cdn_domain: str assets_bucket_name: str aws_region_name: str = "us-east-1" opus_clip_api_token: str jinja2sql_template_searchpath: list[pathlib.Path] = [ base_dir / "opus_clip" / "sql", ] def setup_settings(**defaults: Any) -> Settings: """Setup the application settings.""" try: return Settings(**defaults) except ValidationError as exc: errors = "\n".join( [ f" * {'.'.join(map(str, error['loc']))} - {error['msg']}" for error in exc.errors() ] ) raise RuntimeError(f"Failed to initialize settings:\n {errors}") from exc # Lazy proxy for settings settings = lazy_proxy(setup_settings)