""" L1 Server Configuration. Environment-based configuration with sensible defaults. All config should go through this module - no direct os.environ calls elsewhere. """ import os import sys from pathlib import Path from dataclasses import dataclass, field from typing import Optional @dataclass class Settings: """Application settings loaded from environment.""" # Server host: str = field(default_factory=lambda: os.environ.get("HOST", "0.0.0.0")) port: int = field(default_factory=lambda: int(os.environ.get("PORT", "8000"))) debug: bool = field(default_factory=lambda: os.environ.get("DEBUG", "").lower() == "true") # Cache (use /data/cache in Docker via env var, ~/.artdag/cache locally) cache_dir: Path = field( default_factory=lambda: Path(os.environ.get("CACHE_DIR", str(Path.home() / ".artdag" / "cache"))) ) # Redis redis_url: str = field( default_factory=lambda: os.environ.get("REDIS_URL", "redis://localhost:6379/5") ) # Database database_url: str = field( default_factory=lambda: os.environ.get("DATABASE_URL", "") ) # IPFS ipfs_api: str = field( default_factory=lambda: os.environ.get("IPFS_API", "/dns/localhost/tcp/5001") ) ipfs_gateway_url: str = field( default_factory=lambda: os.environ.get("IPFS_GATEWAY_URL", "https://ipfs.io/ipfs") ) # L2 Server l2_server: Optional[str] = field( default_factory=lambda: os.environ.get("L2_SERVER") ) l2_domain: Optional[str] = field( default_factory=lambda: os.environ.get("L2_DOMAIN") ) # GPU/Streaming settings streaming_gpu_persist: bool = field( default_factory=lambda: os.environ.get("STREAMING_GPU_PERSIST", "0") == "1" ) ipfs_gateways: str = field( default_factory=lambda: os.environ.get( "IPFS_GATEWAYS", "https://ipfs.io,https://cloudflare-ipfs.com,https://dweb.link" ) ) # Derived paths @property def plan_cache_dir(self) -> Path: return self.cache_dir / "plans" @property def analysis_cache_dir(self) -> Path: return self.cache_dir / "analysis" def ensure_dirs(self) -> None: """Create required directories.""" self.cache_dir.mkdir(parents=True, exist_ok=True) self.plan_cache_dir.mkdir(parents=True, exist_ok=True) self.analysis_cache_dir.mkdir(parents=True, exist_ok=True) def log_config(self, logger=None) -> None: """Log all configuration values for debugging.""" output = logger.info if logger else lambda x: print(x, file=sys.stderr) output("=" * 60) output("CONFIGURATION") output("=" * 60) output(f" cache_dir: {self.cache_dir}") output(f" redis_url: {self.redis_url}") output(f" database_url: {self.database_url[:50]}...") output(f" ipfs_api: {self.ipfs_api}") output(f" ipfs_gateway_url: {self.ipfs_gateway_url}") output(f" ipfs_gateways: {self.ipfs_gateways[:50]}...") output(f" streaming_gpu_persist: {self.streaming_gpu_persist}") output(f" l2_server: {self.l2_server}") output("=" * 60) # Singleton settings instance settings = Settings() # Log config on import if DEBUG or SHOW_CONFIG is set if os.environ.get("DEBUG") or os.environ.get("SHOW_CONFIG"): settings.log_config()