from __future__ import annotations import os from dataclasses import dataclass from pathlib import Path def _bool(name: str, default: bool = False) -> bool: return os.getenv(name, str(default)).strip().lower() in {"1", "true", "yes", "on"} def _int(name: str, default: int) -> int: try: return int(os.getenv(name, str(default))) except ValueError: return default @dataclass(frozen=True) class Settings: app_name: str = os.getenv("MAESTER_APP_NAME", "Maester Enterprise") environment: str = os.getenv("MAESTER_ENV", "production") base_dir: Path = Path(os.getenv("MAESTER_BASE_DIR", Path(__file__).resolve().parents[1])) data_dir: Path = Path(os.getenv("MAESTER_DATA_DIR", "/app/data")) api_key: str = os.getenv("MAESTER_API_KEY", "") cpu_safe_mode: bool = _bool("MAESTER_CPU_SAFE_MODE", False) allow_dev_without_api_key: bool = _bool("MAESTER_ALLOW_DEV_NO_API_KEY", False) mount_services: bool = _bool("MAESTER_MOUNT_SERVICES", True) request_body_limit_bytes: int = _int("MAESTER_REQUEST_BODY_LIMIT_BYTES", 1024 * 1024 * 1024) rate_limit_per_minute: int = _int("MAESTER_RATE_LIMIT_PER_MINUTE", 120) service_timeout_seconds: int = _int("MAESTER_SERVICE_TIMEOUT_SECONDS", 1800) allow_public_docs: bool = _bool("MAESTER_ALLOW_PUBLIC_DOCS", False) job_max_attempts: int = _int("MAESTER_JOB_MAX_ATTEMPTS", 3) job_worker_enabled: bool = _bool("MAESTER_JOB_WORKER_ENABLED", True) provider_timeout_seconds: int = _int("MAESTER_PROVIDER_TIMEOUT_SECONDS", 60) max_asset_bytes: int = _int("MAESTER_MAX_ASSET_BYTES", 512 * 1024 * 1024) @property def services_dir(self) -> Path: return self.base_dir / "services" @property def api_key_required(self) -> bool: if self.api_key: return True return not (self.environment == "development" and self.allow_dev_without_api_key) def ensure_runtime_dirs(self) -> None: for path in ( self.data_dir, self.data_dir / "uploads", self.data_dir / "exports", self.data_dir / "jobs", self.data_dir / "logs", self.data_dir / "models", self.data_dir / "temp", self.data_dir / "automation", self.data_dir / "assets", ): path.mkdir(parents=True, exist_ok=True) settings = Settings()