"""Shared utilities for webui data modules.""" from __future__ import annotations import sys import time from pathlib import Path # Ensure project src is on path _project_root = Path(__file__).resolve().parent.parent.parent.parent if str(_project_root) not in sys.path: sys.path.insert(0, str(_project_root / "src")) from ietf_analyzer.config import Config from ietf_analyzer.db import Database from ietf_analyzer.readiness import compute_readiness, compute_readiness_batch # Simple TTL cache for expensive computations (t-SNE, clustering, similarity) _cache: dict[str, tuple[float, object]] = {} _CACHE_TTL = 300 # 5 minutes def _extract_month(time_str: str | None) -> str: """Normalize a date string to YYYY-MM format.""" if not time_str: return "unknown" if len(time_str) >= 7 and time_str[4] == '-': return time_str[:7] # Already YYYY-MM-DD if len(time_str) >= 6 and time_str[:4].isdigit(): return time_str[:4] + '-' + time_str[4:6] # YYYYMMDD → YYYY-MM return time_str[:7] def _cached(key: str, fn, ttl: float = _CACHE_TTL): """Return cached result or compute and cache it.""" now = time.monotonic() if key in _cache: ts, val = _cache[key] if now - ts < ttl: return val val = fn() _cache[key] = (now, val) return val def get_db() -> Database: """Get a Database instance using default config.""" config = Config.load() return Database(config)