from typing import List, Dict, Any, Optional, Union import yaml from pydantic import BaseModel import logging import os # Setup logging # Note: library modules should not configure basicConfig. class ModelConfig(BaseModel): name: str license: str description: str tags: List[str] class DataConfig(BaseModel): features: List[str] target: str archive_path: str store_path: Optional[str] = None class FeatureEngineeringStepConfig(BaseModel): strategy: str features: Optional[List[str]] = None period: Optional[float] = None order: Optional[int] = None class PipelineConfig(BaseModel): enable_tuning: bool feature_engineering: List[FeatureEngineeringStepConfig] class ModelParams(BaseModel): xgboost: Dict[str, Any] class Config(BaseModel): enable_cache: bool model: ModelConfig data: DataConfig pipeline: PipelineConfig model_params: ModelParams def load_config(config_path: str = "config.yaml") -> Config: """Loads and validates the configuration from a YAML file.""" try: # Support running from root or src if not os.path.exists(config_path): # Check if it exists one level up (if running from src) alt_path = os.path.join("..", config_path) if os.path.exists(alt_path): config_path = alt_path with open(config_path, "r") as f: raw_config = yaml.safe_load(f) config = Config(**raw_config) return config except FileNotFoundError: logging.error(f"Config file not found: {config_path}") raise except Exception as e: logging.error(f"Error loading config: {e}") raise # Singleton instance for easy import try: global_config = load_config() except Exception: logging.warning("Could not load global config immediately. Ensure config.yaml exists.") global_config = None