suvradeepp's picture
Publish Tiny Hinglish Turn Detector development preview
35d483e verified
Raw
History Blame Contribute Delete
1.61 kB
"""Small configuration loader with JSON fallback and dotted overrides."""
from __future__ import annotations
import json
from collections.abc import Iterable
from pathlib import Path
from typing import Any
def load_config(path: str | Path) -> dict[str, Any]:
path = Path(path)
text = path.read_text(encoding="utf-8")
if path.suffix.lower() == ".json":
loaded = json.loads(text)
else:
try:
import yaml
except ImportError as exc:
raise ImportError(
"YAML config requires PyYAML; alternatively pass a .json config"
) from exc
loaded = yaml.safe_load(text)
if not isinstance(loaded, dict):
raise ValueError("top-level config must be a mapping")
return loaded
def apply_overrides(config: dict[str, Any], overrides: Iterable[str]) -> dict[str, Any]:
"""Apply ``section.key=<JSON value>`` updates in place."""
for override in overrides:
if "=" not in override:
raise ValueError(f"override must be KEY=VALUE, got {override!r}")
dotted_key, raw_value = override.split("=", 1)
try:
value = json.loads(raw_value)
except json.JSONDecodeError:
value = raw_value
keys = dotted_key.split(".")
cursor: dict[str, Any] = config
for key in keys[:-1]:
child = cursor.setdefault(key, {})
if not isinstance(child, dict):
raise ValueError(f"cannot descend into non-mapping config key {key!r}")
cursor = child
cursor[keys[-1]] = value
return config