Source code for astrosylva.config
"""YAML configuration loading and validation."""
from __future__ import annotations
from pathlib import Path
from typing import Any
import yaml
from pydantic import BaseModel, ConfigDict, Field
from astrosylva.exceptions import ConfigError
[docs]
class ReaderConfig(BaseModel):
model_config = ConfigDict(extra="forbid")
name: str
source: dict[str, Any] = Field(default_factory=dict)
options: dict[str, Any] = Field(default_factory=dict)
[docs]
class WriterConfig(BaseModel):
model_config = ConfigDict(extra="forbid")
output_path: Path
options: dict[str, Any] = Field(default_factory=dict)
[docs]
class Config(BaseModel):
model_config = ConfigDict(extra="forbid")
reader: ReaderConfig
writer: WriterConfig
metadata: MetadataConfig = Field(default_factory=MetadataConfig)
[docs]
def load_config(path: str | Path) -> Config:
"""Load and validate a YAML config file."""
path = Path(path)
if not path.is_file():
raise ConfigError(f"Config file does not exist: {path}")
try:
raw = yaml.safe_load(path.read_text())
except yaml.YAMLError as exc:
raise ConfigError(f"Failed to parse YAML config {path}: {exc}") from exc
if not isinstance(raw, dict):
raise ConfigError(f"Config root must be a mapping, got {type(raw).__name__}")
try:
return Config.model_validate(raw)
except Exception as exc:
raise ConfigError(f"Invalid config {path}: {exc}") from exc