"""Runtime configuration for Flowers. Secrets are read from the git-ignored ``secrets.yaml`` file. Environment variables take precedence, which is useful for container deployments. """ import os import secrets from pathlib import Path import yaml BASE_DIR = Path(__file__).resolve().parent SECRETS_FILE = Path( os.getenv("FLOWERS_SECRETS_FILE", str(BASE_DIR / "secrets.yaml")) ) def _load_secrets(path: Path) -> dict: try: data = yaml.safe_load(path.read_text(encoding="utf-8")) or {} except FileNotFoundError: return {} except (OSError, yaml.YAMLError) as exc: raise RuntimeError(f"Could not read Flowers secrets file: {path}") from exc if not isinstance(data, dict): raise RuntimeError(f"Flowers secrets file must contain a mapping: {path}") return data _SECRETS = _load_secrets(SECRETS_FILE) _FLASK_SECRETS = _SECRETS.get("flask", {}) _DATABASE_SECRETS = _SECRETS.get("database", {}) if not isinstance(_FLASK_SECRETS, dict) or not isinstance(_DATABASE_SECRETS, dict): raise RuntimeError("The flask and database secrets sections must be mappings") LOGFILE = os.getenv("FLOWERS_LOG_FILE", "/tmp/wsgi_flowers.log") DEBUG = os.getenv("FLOWERS_DEBUG", "0") == "1" INFO = os.getenv("FLOWERS_INFO", "1") == "1" MAXTEXTLEN = int(os.getenv("FLOWERS_MAX_TEXT_LENGTH", "70")) MINFIELDLEN = int(os.getenv("FLOWERS_MIN_FIELD_LENGTH", "3")) DONOTSETFILTER = "DoNotSetFilterinCookie" ACCESSFILE = os.getenv("FLOWERS_ACCESS_FILE", "/tmp/wsgi_flower_accessfile") URLPREFIX = os.getenv("FLOWERS_URL_PREFIX", "").rstrip("/") DB_HOST = os.getenv("FLOWERS_DB_HOST", "localhost") DB_PORT = int(os.getenv("FLOWERS_DB_PORT", "3306")) DB_NAME = os.getenv("FLOWERS_DB_NAME", "Flowers") DB_ADMIN_USER = os.getenv("FLOWERS_DB_ADMIN_USER", "flower") DB_ADMIN_PASSWORD = os.getenv( "FLOWERS_DB_ADMIN_PASSWORD", str(_DATABASE_SECRETS.get("admin_password", "")) ) SESSION_MINUTES = int(os.getenv("FLOWERS_SESSION_MINUTES", "10")) SECRET_KEY = ( os.getenv("FLOWERS_SECRET_KEY") or str(_FLASK_SECRETS.get("secret_key", "")) or secrets.token_hex(32) ) COOKIE_SECURE = os.getenv("FLOWERS_COOKIE_SECURE", "0") == "1"