Add rate limiting to /process endpoint

- Uses slowapi for rate limiting
- Default: 10 requests/minute per IP
- Configurable via RATE_LIMIT env var
- Returns HTTP 429 when limit exceeded
This commit is contained in:
egregore 2026-02-02 12:58:33 +00:00
parent 5710c44821
commit ebd78cf88e

22
main.py
View file

@ -1,6 +1,6 @@
#!/usr/bin/env python3
"""
Egregore Brain Service - AI reasoning API
Egregore Reason Service - AI reasoning API
Provides HTTP API for conversation processing with Claude.
Runs on port 8081.
@ -9,9 +9,12 @@ Runs on port 8081.
import os
from typing import Optional
from fastapi import FastAPI, HTTPException
from fastapi import FastAPI, HTTPException, Request
from pydantic import BaseModel
from dotenv import load_dotenv
from slowapi import Limiter, _rate_limit_exceeded_handler
from slowapi.util import get_remote_address
from slowapi.errors import RateLimitExceeded
import anthropic
from tools import TOOLS, execute_tool
@ -25,7 +28,15 @@ ANTHROPIC_API_KEY = os.getenv("ANTHROPIC_API_KEY")
if not ANTHROPIC_API_KEY:
raise ValueError("ANTHROPIC_API_KEY not set")
app = FastAPI(title="Egregore Brain Service", docs_url="/docs")
# Rate limiting configuration
RATE_LIMIT = os.getenv("RATE_LIMIT", "10/minute")
# Initialize rate limiter
limiter = Limiter(key_func=get_remote_address)
app = FastAPI(title="Egregore Reason Service", docs_url="/docs")
app.state.limiter = limiter
app.add_exception_handler(RateLimitExceeded, _rate_limit_exceeded_handler)
# Initialize Anthropic client
client = anthropic.AsyncAnthropic(api_key=ANTHROPIC_API_KEY)
@ -45,7 +56,8 @@ class ToolRequest(BaseModel):
# Endpoints
@app.post("/process")
async def api_process(req: ProcessRequest):
@limiter.limit(RATE_LIMIT)
async def api_process(request: Request, req: ProcessRequest):
"""Process a conversation with tool use loop"""
try:
response_blocks = await process_conversation(
@ -82,7 +94,7 @@ async def api_get_prompt():
@app.get("/health")
async def health():
"""Health check endpoint"""
return {"status": "ok", "service": "brain"}
return {"status": "ok", "service": "reason"}
if __name__ == "__main__":