Files
pi-qmem/gateway/state.py
T
Matteo Benedetto 4776b4b496 refactor: split gateway and pi-qmem extension into modules
- gateway: separate config, models, state, audit, guardrail, embeddings,
  store, metrics, cleanup and routes; keep main.py as FastAPI bootstrap
- extension: split client/config, six tools, config command and rules;
  preserve jiti entrypoint and registrations
- Dockerfile copies the complete gateway module set
- tests: update monkeypatch boundaries for modular config/state
2026-08-24 16:19:19 +02:00

38 lines
1.1 KiB
Python

"""Stato runtime condiviso tra bootstrap e route."""
from __future__ import annotations
import contextvars
import hashlib
import json
import time
from typing import Any
from qdrant_client import QdrantClient
from config import QDRANT_API_KEY, QDRANT_URL
qdrant = QdrantClient(url=QDRANT_URL, api_key=QDRANT_API_KEY)
request_id: contextvars.ContextVar[str] = contextvars.ContextVar("request_id", default="-")
ratelimit: dict[str, list[float]] = {}
status_ratelimit: dict[str, list[float]] = {}
idempotency: dict[str, dict[str, Any]] = {}
meta_cache: dict[str, Any] = {}
STATUS_RATE_LIMIT_PER_MIN = 30
IDEMPOTENCY_TTL_SECONDS = 24 * 3600
def payload_hash(body: Any) -> str:
canonical = json.dumps(body.model_dump(), sort_keys=True, default=str)
return hashlib.sha256(canonical.encode()).hexdigest()
def idempotency_cleanup() -> None:
now = time.time()
expired = [k for k, v in idempotency.items() if now - v["ts"] > IDEMPOTENCY_TTL_SECONDS]
for key in expired:
idempotency.pop(key, None)
def invalidate_meta() -> None:
meta_cache.clear()