"""Shared configuration loader for all services.""" import os from dataclasses import dataclass, field from typing import Optional @dataclass class PostgresConfig: host: str = "localhost" port: int = 5432 database: str = "stonks" user: str = "stonks" password: str = "stonks_dev" @property def dsn(self) -> str: return f"postgresql://{self.user}:{self.password}@{self.host}:{self.port}/{self.database}" @dataclass class RedisConfig: host: str = "localhost" port: int = 6379 db: int = 0 password: Optional[str] = None @property def url(self) -> str: auth = f":{self.password}@" if self.password else "" return f"redis://{auth}{self.host}:{self.port}/{self.db}" @dataclass class MinioConfig: endpoint: str = "localhost:9000" access_key: str = "minioadmin" secret_key: str = "minioadmin" secure: bool = False @dataclass class OllamaConfig: base_url: str = "http://localhost:11434" model: str = "llama3.1:8b" timeout: int = 120 @dataclass class TrinoConfig: host: str = "localhost" port: int = 8080 catalog: str = "lakehouse" schema: str = "stonks" @dataclass class BrokerConfig: mode: str = "paper" # paper | live api_key: Optional[str] = None api_secret: Optional[str] = None base_url: Optional[str] = None @dataclass class AppConfig: postgres: PostgresConfig = field(default_factory=PostgresConfig) redis: RedisConfig = field(default_factory=RedisConfig) minio: MinioConfig = field(default_factory=MinioConfig) ollama: OllamaConfig = field(default_factory=OllamaConfig) trino: TrinoConfig = field(default_factory=TrinoConfig) broker: BrokerConfig = field(default_factory=BrokerConfig) log_level: str = "INFO" def load_config() -> AppConfig: """Load configuration from environment variables with sensible defaults.""" return AppConfig( postgres=PostgresConfig( host=os.getenv("POSTGRES_HOST", "localhost"), port=int(os.getenv("POSTGRES_PORT", "5432")), database=os.getenv("POSTGRES_DB", "stonks"), user=os.getenv("POSTGRES_USER", "stonks"), password=os.getenv("POSTGRES_PASSWORD", "stonks_dev"), ), redis=RedisConfig( host=os.getenv("REDIS_HOST", "localhost"), port=int(os.getenv("REDIS_PORT", "6379")), db=int(os.getenv("REDIS_DB", "0")), password=os.getenv("REDIS_PASSWORD", None), ), minio=MinioConfig( endpoint=os.getenv("MINIO_ENDPOINT", "localhost:9000"), access_key=os.getenv("MINIO_ACCESS_KEY", "minioadmin"), secret_key=os.getenv("MINIO_SECRET_KEY", "minioadmin"), secure=os.getenv("MINIO_SECURE", "false").lower() == "true", ), ollama=OllamaConfig( base_url=os.getenv("OLLAMA_BASE_URL", "http://localhost:11434"), model=os.getenv("OLLAMA_MODEL", "llama3.1:8b"), timeout=int(os.getenv("OLLAMA_TIMEOUT", "120")), ), trino=TrinoConfig( host=os.getenv("TRINO_HOST", "localhost"), port=int(os.getenv("TRINO_PORT", "8080")), catalog=os.getenv("TRINO_CATALOG", "lakehouse"), schema=os.getenv("TRINO_SCHEMA", "stonks"), ), broker=BrokerConfig( mode=os.getenv("BROKER_MODE", "paper"), api_key=os.getenv("BROKER_API_KEY", None), api_secret=os.getenv("BROKER_API_SECRET", None), base_url=os.getenv("BROKER_BASE_URL", None), ), log_level=os.getenv("LOG_LEVEL", "INFO"), )