cache.py 1.4 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849
  1. from __future__ import annotations
  2. import json
  3. from dataclasses import dataclass
  4. from datetime import datetime, timezone
  5. from pathlib import Path
  6. from typing import Any
  7. def now_iso() -> str:
  8. return datetime.now(timezone.utc).isoformat()
  9. @dataclass(frozen=True)
  10. class CachedSnapshot:
  11. provider_key: str
  12. updated_at: str
  13. data: dict[str, Any]
  14. class SnapshotCache:
  15. def __init__(self, cache_dir: Path) -> None:
  16. self.cache_dir = cache_dir
  17. def path_for(self, provider_key: str) -> Path:
  18. return self.cache_dir / f"{provider_key}.json"
  19. def write(self, provider_key: str, data: dict[str, Any]) -> Path:
  20. self.cache_dir.mkdir(parents=True, exist_ok=True)
  21. payload = {
  22. "provider_key": provider_key,
  23. "updated_at": now_iso(),
  24. "data": data,
  25. }
  26. path = self.path_for(provider_key)
  27. path.write_text(json.dumps(payload, indent=2, ensure_ascii=False) + "\n", encoding="utf-8")
  28. return path
  29. def read(self, provider_key: str) -> CachedSnapshot | None:
  30. path = self.path_for(provider_key)
  31. if not path.exists():
  32. return None
  33. payload = json.loads(path.read_text(encoding="utf-8"))
  34. return CachedSnapshot(
  35. provider_key=payload["provider_key"],
  36. updated_at=payload["updated_at"],
  37. data=payload["data"],
  38. )