from typing import Annotated, Any, Literal from pydantic import ( AnyUrl, BeforeValidator, PostgresDsn, computed_field ) from pydantic_core import MultiHostUrl from pydantic_settings import BaseSettings, SettingsConfigDict def parse_cors(v: Any) -> list[str] | str: if isinstance(v, str) and not v.startswith("["): return [i.strip() for i in v.split(",")] elif isinstance(v, list | str): return v raise ValueError(v) class Settings(BaseSettings): model_config = SettingsConfigDict( env_file=".env", env_ignore_empty=True, extra="ignore", ) ENVIRONMENT: Literal["local", "production"] = "local" BACKEND_CORS_ORIGINS: Annotated[ list[AnyUrl] | str, BeforeValidator(parse_cors) ] = [] @computed_field # type: ignore[prop-decorator] @property def all_cors_origins(self) -> list[str]: return [str(origin).rstrip("/") for origin in self.BACKEND_CORS_ORIGINS] PROJECT_NAME: str = "Gondul" POSTGRES_SERVER: str = "localhost" POSTGRES_PORT: int = 5432 POSTGRES_USERNAME: str = "postgres" POSTGRES_PASSWORD: str POSTGRES_DATABASE: str = "postgres" REDIS_SERVER: str = "localhost" REDIS_PORT: int = 6379 REDIS_DB: int = 0 NETBOX_URL: str = "http://localhost" NETBOX_TOKEN: str = "" @computed_field # type: ignore[prop-decorator] @property def SQLALCHEMY_DATABASE_URI(self) -> PostgresDsn: return MultiHostUrl.build( scheme="postgresql+psycopg", username=self.POSTGRES_USERNAME, password=self.POSTGRES_PASSWORD, host=self.POSTGRES_SERVER, port=self.POSTGRES_PORT, path=self.POSTGRES_DATABASE, ) settings = Settings() # type: ignore