"""Centralized application configuration via pydantic-settings.This module defines the single source of truth for runtime configuration.Values are loaded from process environment variables and an optional ``.env``file, validated with Pydantic, and exposed through a module-level``Settings`` instance. This consolidation avoids ad-hoc ``os.getenv`` callsacross the codebase and improves type safety and discoverability.See Also--------app.database : Engine/session factories that consume ``settings.DATABASE_URL``.app.utils : Logging helpers and general utilities that may use config values.Notes------ Primary role: provide a validated ``Settings`` model and a ready-to-use ``settings`` instance consumed throughout the application.- Key dependencies: ``pydantic_settings.BaseSettings``, process environment, and an optional ``.env`` file at the project root.- Invariants: ``DATABASE_URL`` must be present; extra environment variables are ignored to minimize coupling; sensible defaults exist for non-critical options.Examples-------->>> from app.config import settings>>> isinstance(settings.DATABASE_URL, str)True>>> # Override via environment or instantiate directly for tests>>> from app.config import SettingsTrue"""importloggingfrompathlibimportPathfromtypingimportOptionalfrompydanticimportExtra,Fieldfrompydantic_settingsimportBaseSettings# ConstantsENV_FILE:Path=Path(".env")ENV_FILE_ENCODING:str="utf-8"POLLING_INTERVAL_MINUTES_DEFAULT:int=10DATA_INGEST_INTERVAL_MINUTES_DEFAULT:int=1USER_AGENT_DEFAULT:str="SkolDataApp/1.0 (kontakt@skoldata.se)"DOCUMENTATION_URL_DEFAULT:str="http://localhost:8001"logger=logging.getLogger(__name__)classSettings(BaseSettings):"""Application configuration loaded from environment variables. The settings object is the single source of truth for runtime configuration across the application. It is based on ``pydantic-settings`` to provide type checking, default values, and ``.env`` support. Parameters ---------- DATABASE_URL : str Connection string for the database. This field is required. polling_interval_minutes : int, optional Interval for polling jobs, in minutes. Defaults to ``10``. data_ingest_interval_minutes : int, optional Interval for data ingestion, in minutes. Defaults to ``1``. user_agent : str, optional User-Agent header for outbound HTTP requests. Defaults to a project specific value. my_lat : float, optional Optional latitude used for a central point in weather queries. my_long : float, optional Optional longitude used for a central point in weather queries. Attributes ---------- DATABASE_URL : str Connection string for the database. Required (no default). polling_interval_minutes : int Interval for polling jobs, in minutes. data_ingest_interval_minutes : int Interval for data ingestion, in minutes. user_agent : str User-Agent header for outbound HTTP requests. my_lat : float | None Optional latitude used for a central point in weather queries. my_long : float | None Optional longitude used for a central point in weather queries. Raises ------ pydantic.ValidationError If required values are missing or invalid when the model is instantiated (including at import time for the module-level ``settings`` instance). Examples -------- >>> from app.config import Settings >>> s = Settings(DATABASE_URL="sqlite:///:memory:") >>> isinstance(s.polling_interval_minutes, int) True See Also -------- - app.database: Consumers of ``Settings`` values for engine/session setup. Notes ----- - Extra environment variables are ignored (``extra=ignore``). - Values are read at import time when ``settings = Settings()`` is executed. """DATABASE_URL:str=Field(...,description="Connection string for the database")polling_interval_minutes:int=POLLING_INTERVAL_MINUTES_DEFAULTdata_ingest_interval_minutes:int=DATA_INGEST_INTERVAL_MINUTES_DEFAULTuser_agent:str=USER_AGENT_DEFAULTmy_lat:Optional[float]=Nonemy_long:Optional[float]=Nonedocumentation_url:str=Field(DOCUMENTATION_URL_DEFAULT,description="URL where the project's rendered documentation is hosted (Sphinx)",)classConfig:"""Pydantic configuration for environment file settings. Notes ----- - ``env_file`` points to the project ``.env`` to simplify local runs. - Encoding is set explicitly to avoid platform-specific defaults. - Extra variables are ignored to prevent accidental coupling. """env_file=ENV_FILEenv_file_encoding=ENV_FILE_ENCODINGextra=Extra.ignore# Instantiate Settings, loading from environment variables or the `.env` file.settings=Settings()__all__=["settings","Settings"]