"""Daemon configuration resolution (REQ-005, REQ-010).""" from __future__ import annotations import os from dataclasses import dataclass def _load_dotenv() -> None: """Best-effort load of a .env file into os.environ (REQ-010). Real OS environment variables take precedence over .env (override=False), matching 12-factor expectations. If python-dotenv is not installed or no .env exists, this is a no-op (no regression). """ try: from dotenv import find_dotenv, load_dotenv except ImportError: # pragma: no cover - optional at runtime return load_dotenv(find_dotenv(usecwd=True), override=False) @dataclass(frozen=True) class DaemonConfig: dsn: str total_slots: int host: str port: int @staticmethod def from_env() -> "DaemonConfig": _load_dotenv() dsn = os.environ.get("TREX_POSTGRESQL_DSN") if not dsn: raise RuntimeError( "TREX_POSTGRESQL_DSN is required to start the slot-core daemon." ) return DaemonConfig( dsn=dsn, total_slots=int(os.environ.get("TREX_TOTAL_SLOTS", "10")), host=os.environ.get("TREX_API_HOST", "127.0.0.1"), port=int(os.environ.get("TREX_API_PORT", "8080")), )