from __future__ import annotations import json from dataclasses import dataclass from datetime import datetime, timezone from pathlib import Path from typing import Any def now_iso() -> str: return datetime.now(timezone.utc).isoformat() @dataclass(frozen=True) class CachedSnapshot: provider_key: str updated_at: str data: dict[str, Any] class SnapshotCache: def __init__(self, cache_dir: Path) -> None: self.cache_dir = cache_dir def path_for(self, provider_key: str) -> Path: return self.cache_dir / f"{provider_key}.json" def write(self, provider_key: str, data: dict[str, Any]) -> Path: self.cache_dir.mkdir(parents=True, exist_ok=True) payload = { "provider_key": provider_key, "updated_at": now_iso(), "data": data, } path = self.path_for(provider_key) path.write_text(json.dumps(payload, indent=2, ensure_ascii=False) + "\n", encoding="utf-8") return path def read(self, provider_key: str) -> CachedSnapshot | None: path = self.path_for(provider_key) if not path.exists(): return None payload = json.loads(path.read_text(encoding="utf-8")) return CachedSnapshot( provider_key=payload["provider_key"], updated_at=payload["updated_at"], data=payload["data"], )