| | """App-level configuration and runtime loader helpers.""" |
| |
|
| | from __future__ import annotations |
| |
|
| | from dataclasses import dataclass |
| | from pathlib import Path |
| | from typing import Any, Dict, Optional |
| |
|
| | import yaml |
| |
|
| | from connectors.base import Connector |
| | from connectors.registry import ConnectorRegistry |
| | from providers.model.base import ModelProvider |
| | from providers.model.registry import ModelRegistry |
| |
|
| |
|
| | APP_CONFIG_PATH = Path("configs/app.yaml") |
| | PROVIDER_CONFIG_DIR = Path("configs/providers") |
| | CONNECTOR_CONFIG_DIR = Path("configs/connectors") |
| |
|
| |
|
| | @dataclass(frozen=True) |
| | class AppConfig: |
| | profile: Optional[str] = None |
| | profile_path: Optional[str] = None |
| | provider: Optional[str] = None |
| | connector: Optional[str] = None |
| |
|
| |
|
| | def load_app_config(path: Path = APP_CONFIG_PATH) -> AppConfig: |
| | if not path.exists(): |
| | return AppConfig() |
| | data = yaml.safe_load(path.read_text()) or {} |
| | return AppConfig( |
| | profile=data.get("profile"), |
| | profile_path=data.get("profile_path"), |
| | provider=data.get("provider"), |
| | connector=data.get("connector"), |
| | ) |
| |
|
| |
|
| | def load_provider( |
| | name: Optional[str], |
| | config_dir: Path = PROVIDER_CONFIG_DIR, |
| | ) -> Optional[ModelProvider]: |
| | if not name: |
| | return None |
| | registry = ModelRegistry() |
| | provider_cls = registry.get(name) |
| | if provider_cls is None: |
| | return None |
| | config = _load_named_config(config_dir, name) |
| | return provider_cls(**config) |
| |
|
| |
|
| | def load_connector( |
| | name: Optional[str], |
| | config_dir: Path = CONNECTOR_CONFIG_DIR, |
| | ) -> Optional[Connector]: |
| | if not name: |
| | return None |
| | config = _load_named_config(config_dir, name) |
| | if isinstance(config.get("enabled"), bool) and not config["enabled"]: |
| | return None |
| | registry = ConnectorRegistry() |
| | connector_cls = registry.get(name) |
| | if connector_cls is None: |
| | return None |
| | return connector_cls(**config) |
| |
|
| |
|
| | def _load_named_config(config_dir: Path, name: str) -> Dict[str, Any]: |
| | path = config_dir / f"{name}.yaml" |
| | if not path.exists(): |
| | return {} |
| | data = yaml.safe_load(path.read_text()) |
| | if isinstance(data, dict): |
| | return data |
| | return {} |
| |
|