rmi-backend/app/core/llm_cache.py
opencode c762564d40 style(rmi-backend): complete lint cleanup — 1175→0 ruff errors
- Fix 71 invalid-syntax files (class-body newline-broken assignments)
- Add from/None chain to 307 B904 raise-without-from sites
- Add B008 ignore to ruff.toml (already in pyproject.toml)
- Noqa F401 on __init__.py re-exports (137 sites)
- Noqa E402 on deferred imports (63 sites)
- Bulk-add stdlib/FastAPI/project imports for F821 (127 sites)
- Replace ×→x, –→-, …→... in docstrings (4093 chars)
- Manual refactor of 5 SIM103/SIM116 patterns

Tests: 791 passed (66 deselected due to pre-existing Redis issues in test_rag.py)
Co-authored-by: opencode <opencode@rugmunch.io>
2026-07-06 15:43:20 +02:00

49 lines
1.3 KiB
Python

"""Semantic LLM Cache for DataBus - caches identical + similar prompts. Redis-backed."""
import hashlib
import json
import os
REDIS_URL = os.getenv("REDIS_CACHE_URL", "redis://localhost:6379/1")
CACHE_TTL = int(os.getenv("LLM_CACHE_TTL", "3600"))
def _cache_key(prompt: str, model: str) -> str:
return f"llm_cache:{hashlib.sha256(f'{model}:{prompt}'.encode()).hexdigest()[:16]}"
def get_cached(prompt: str, model: str) -> dict | None:
"""Check if prompt+model result is cached."""
import redis
try:
r = redis.from_url(REDIS_URL, decode_responses=True)
data = r.get(_cache_key(prompt, model))
if data:
return json.loads(data)
except Exception:
pass
return None
def set_cached(prompt: str, model: str, result: dict, ttl: int = CACHE_TTL):
"""Cache a prompt result."""
import redis
try:
r = redis.from_url(REDIS_URL, decode_responses=True)
r.setex(_cache_key(prompt, model), ttl, json.dumps(result))
except Exception:
pass
def get_cache_stats() -> dict:
"""Get cache statistics."""
import redis
try:
r = redis.from_url(REDIS_URL, decode_responses=True)
keys = r.keys("llm_cache:*")
return {"cached_prompts": len(keys)}
except Exception:
return {"cached_prompts": 0, "error": "redis unavailable"}