cache.py
1 """ 2 dashboard_cache table reader. 3 4 The precompute-dashboard.js cron populates this table every 10 minutes. 5 FastAPI reads it first; falls back to live queries on miss. 6 """ 7 8 import json 9 from db import fetchone 10 11 12 async def get_cached(key: str) -> dict | list | None: 13 """Return parsed JSON from dashboard_cache if fresh, else None.""" 14 row = await fetchone( 15 "SELECT cache_value FROM dashboard_cache " 16 "WHERE cache_key = $1 AND expires_at > NOW()", 17 key, 18 ) 19 if row and row.get("cache_value"): 20 return json.loads(row["cache_value"]) 21 return None 22 23 24 async def get_many(keys: list[str]) -> dict: 25 """Fetch multiple cache keys in one call. Returns {key: value} for hits.""" 26 if not keys: 27 return {} 28 from db import fetchall 29 placeholders = ", ".join(f"${i+1}" for i in range(len(keys))) 30 rows = await fetchall( 31 f"SELECT cache_key, cache_value FROM dashboard_cache " 32 f"WHERE cache_key IN ({placeholders}) AND expires_at > NOW()", 33 *keys, 34 ) 35 return {r["cache_key"]: json.loads(r["cache_value"]) for r in rows}