""" Configuration definition. Converts per-run (environment) variables and config files into the "python world" using `pydantic`. Pydantic models might have convenience methods attached. """ from typing import Any, Optional from pydantic import BaseModel, BaseSettings, root_validator class DavSettings(BaseModel): """ Connection to a DAV server. """ protocol: Optional[str] = None host: Optional[str] = None username: Optional[str] = None password: Optional[str] = None path: Optional[str] = None @property def url(self) -> str: """ Combined DAV URL. """ return f"{self.protocol}://{self.host}{self.path}" class Settings(BaseSettings): """ Per-run settings. """ ##### # general settings ##### production_mode: bool = False log_level: str = "INFO" if production_mode else "DEBUG" ui_directory: str = "/html" cache_time: int = 30 cache_size: int = 30 # doesn't even have to be reachable ping_host: str = "10.0.0.0" ping_port: int = 1 ##### # openapi settings ##### openapi_url: str = "/openapi.json" docs_url: Optional[str] = None if production_mode else "/docs" redoc_url: Optional[str] = None if production_mode else "/redoc" ##### # webdav settings ##### webdav: DavSettings = DavSettings() webdav_disable_check: bool = False webdav_retries: int = 20 webdav_prefix: str = "/ovdashboard" config_path: str = "config.txt" ##### # caldav settings ##### caldav: DavSettings = DavSettings() class Config: env_file = ".env" env_file_encoding = "utf-8" env_nested_delimiter = "__" @root_validator(pre=True) @classmethod def validate_dav_settings(cls, values: dict[str, Any]) -> dict[str, Any]: # ensure both settings dicts are created for key in ("webdav", "caldav"): if key not in values: values[key] = {} default_dav = DavSettings( protocol="https", host="example.com", username="ovdashboard", password="secret", ).dict() for key in default_dav: # if "webdav" value is not specified, use default if key not in values["webdav"] or values["webdav"][key] is None: values["webdav"][key] = default_dav[key] # if "caldav" value is not specified, use "webdav" value if key not in values["caldav"] or values["caldav"][key] is None: values["caldav"][key] = values["webdav"][key] # add default "path"s if None if values["webdav"]["path"] is None: values["webdav"]["path"] = "/remote.php/webdav" if values["caldav"]["path"] is None: values["caldav"]["path"] = "/remote.php/dav" return values SETTINGS = Settings()