Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-08-12 08:24:56

0001 """Configuration loader wrappers for AID2E.
0002 
0003 These helpers provide section-level loading APIs on top of the existing
0004 ``load_config`` flow so callers can load canonical config sections directly.
0005 """
0006 
0007 from __future__ import annotations
0008 
0009 import json
0010 from pathlib import Path
0011 from typing import Any, Dict, Optional
0012 
0013 import yaml
0014 
0015 from .full_config import _normalize_full_config_data
0016 from .optimizer_config import OptimizerConfiguration
0017 from .problem_config import ProblemConfiguration
0018 from .scheduler_config import SchedulerConfigLoader, SchedulerConfiguration
0019 from .workflow_config import WorkflowDefinition, WorkflowsConfiguration
0020 
0021 
0022 def load_raw_config(config_file: str) -> Dict[str, Any]:
0023     """Load raw YAML/JSON configuration content from disk.
0024 
0025     Args:
0026         config_file: Path to YAML or JSON config.
0027 
0028     Returns:
0029         Raw top-level configuration dictionary.
0030 
0031     Raises:
0032         FileNotFoundError: If the config file does not exist.
0033         ValueError: If the extension is unsupported.
0034     """
0035     path = Path(config_file)
0036     if not path.exists():
0037         raise FileNotFoundError(f"Config file not found: {config_file}")
0038 
0039     text = path.read_text(encoding="utf-8")
0040     suffix = path.suffix.lower()
0041     if suffix in {".yaml", ".yml"}:
0042         return yaml.safe_load(text) or {}
0043     if suffix == ".json":
0044         return json.loads(text)
0045 
0046     raise ValueError(
0047         f"Unsupported config extension '{suffix}'. "
0048         "Use .yaml, .yml, or .json."
0049     )
0050 
0051 
0052 def _normalize_sections(config_file: str) -> Dict[str, Any]:
0053     """Normalize full config content into canonical sections."""
0054     path = Path(config_file)
0055     raw = load_raw_config(config_file)
0056     return _normalize_full_config_data(raw, path)
0057 
0058 
0059 def load_problem_config(config_file: str) -> ProblemConfiguration:
0060     """Load only the problem section from a full config file."""
0061     normalized = _normalize_sections(config_file)
0062     return normalized["problem"]
0063 
0064 
0065 def load_optimizer_config(config_file: str) -> OptimizerConfiguration:
0066     """Load only the optimizer section from a full config file."""
0067     normalized = _normalize_sections(config_file)
0068     return normalized["optimizer"]
0069 
0070 
0071 def load_scheduler_config(config_file: str) -> Optional[SchedulerConfiguration]:
0072     """Load only the scheduler section from a full config file.
0073 
0074     Accepts only canonical scheduler payloads with ``parameters``.
0075     """
0076     path = Path(config_file)
0077     raw = load_raw_config(config_file)
0078     scheduler_raw = raw.get("scheduler")
0079     if not scheduler_raw:
0080         normalized = _normalize_full_config_data(raw, path)
0081         return normalized.get("scheduler")
0082 
0083     if not isinstance(scheduler_raw, dict):
0084         raise ValueError("'scheduler' section must be a mapping")
0085 
0086     return SchedulerConfigLoader.from_dict(scheduler_raw, base_dir=str(path.parent))
0087 
0088 
0089 def load_workflow_config(config_file: str) -> Optional[WorkflowsConfiguration]:
0090     """Load workflow configuration from full config if present.
0091 
0092     Accepted layout:
0093         - ``workflows: {workflows: [...]}``
0094     """
0095     normalized = _normalize_sections(config_file)
0096     return normalized.get("workflows")