mirror of
https://github.com/yogeshojha/rengine.git
synced 2026-10-20 23:31:31 +02:00
mcp/, toolbox/ and the api's rate limiter each held their own lazy Redis client, three copies of the same lru-singleton pattern reaching into api.core.ratelimit from worker-side code that has no FastAPI app. shared/redis.py is the one place that builds the async and sync clients; ratelimit, throttle, mcp/limits and toolbox/store now import from it. pyproject.toml's isort first-party list gains the packages that have shipped since it was last written (channels, connectors, interest, mcp, reports, stages, toolbox). Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01VckaDx6mBB4TsG76u61gvv
27 lines
611 B
Python
27 lines
611 B
Python
"""Per-token call ceiling."""
|
|
|
|
from __future__ import annotations
|
|
|
|
import uuid
|
|
|
|
from shared.logging import get_logger
|
|
from shared.redis import async_client
|
|
|
|
logger = get_logger(__name__)
|
|
|
|
KEY = "mcp:rate:{token_id}"
|
|
WINDOW = 60
|
|
|
|
|
|
async def exceeded(token_id: uuid.UUID, limit: int) -> bool:
|
|
key = KEY.format(token_id=token_id)
|
|
try:
|
|
redis = async_client()
|
|
used = await redis.incr(key)
|
|
if used == 1:
|
|
await redis.expire(key, WINDOW)
|
|
except Exception as exc:
|
|
logger.debug("mcp rate limit skipped", error=str(exc))
|
|
return False
|
|
return used > limit
|