chto-ty-takoe-na-baze-kakih/src/cache.py
Elshat 6c890fa20a v2: Python MVP — price pipeline + analytics + FastAPI dashboard + digest + tests
- pipeline: fetch/extract/normalize/categorize/validate/llm_extract/raw/orchestrator
- analytics: dynamics, spreads/arbitrage, seasonality, anomalies, alerts, forecast
- dashboard: FastAPI + Plotly (overview/products/product/countries/alerts/quality/sources)
- scheduler (APScheduler 07:30), digest (Telegram/SMTP dry-run), demo_data
- SQLite (PORTABLE) with idempotent upserts, quarantine, alerts dedup
- truthfulness: LLM quote-verified, source link + date on every price
- tests: 13 passed, 1 skipped (robots port)
2026-09-24 07:07:32 +00:00

47 lines
1.1 KiB
Python

"""Simple JSON file cache for LLM outputs. Keyed by sha256; avoids paying twice."""
from __future__ import annotations
import json
import hashlib
import json
from pathlib import Path
from . import config
cache_dir: Path | None = None
def _dir() -> Path:
global cache_dir
if cache_dir is None:
cache_dir = config.RAW_DIR / "llm_cache"
cache_dir.mkdir(parents=True, exist_ok=True)
return cache_dir
def llm_cache_get(key: str):
"""Return cached value or None."""
p = _dir() / f"{key}.json"
if not p.exists():
return None
try:
return json.loads(p.read_text("utf-8"))
except Exception:
return None
def llm_cache_put(key: str, value) -> None:
p = _dir() / f"{key}.json"
try:
p.write_text(json.dumps(value, ensure_ascii=False, default=str), "utf-8")
except Exception:
pass
def clear() -> None:
global cache_dir
if cache_dir and cache_dir.exists():
for f in cache_dir.iterdir():
try:
f.unlink()
except Exception:
pass