from __future__ import annotations from pathlib import Path 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", extra="ignore") app_name: str = "Walkup API" backend_host: str = "0.0.0.0" backend_port: int = 8000 backend_cors_origins_raw: str = "https://kif.local.ascorrea.com" session_cookie_name: str = "walkup_session" session_cookie_secure: bool = False auth_return_cookie_name: str = "walkup_auth_return_to" session_secret: str = "change-me" local_admin_username: str = "admin" local_admin_password: str = "admin" teamsnap_client_id: str = "" teamsnap_client_secret: str = "" teamsnap_client_id_file: Path | None = None teamsnap_client_secret_file: Path | None = None teamsnap_auth_url: str = "https://auth.teamsnap.com/oauth/authorize" teamsnap_token_url: str = "https://auth.teamsnap.com/oauth/token" teamsnap_api_root: str = "https://apiv3.teamsnap.com" teamsnap_redirect_uri: str = "https://kif.local.ascorrea.com/api/auth/teamsnap/callback" teamsnap_scope: str = "read" media_root: Path = Path("./storage") database_url: str = "sqlite+pysqlite:///./walkup.db" @property def backend_cors_origins(self) -> list[str]: return [item.strip() for item in self.backend_cors_origins_raw.split(",") if item.strip()] def _read_secret_file(path: Path | None) -> str: if path is None or not path.exists(): return "" return path.read_text(encoding="utf-8").strip() settings = Settings() settings.teamsnap_client_id = settings.teamsnap_client_id or _read_secret_file(settings.teamsnap_client_id_file) settings.teamsnap_client_secret = settings.teamsnap_client_secret or _read_secret_file(settings.teamsnap_client_secret_file)