SlowAPI Rate Limit Redis Backend
Throttle FastAPI endpoints with SlowAPI using a Redis backend, per-user limits, custom headers, and exempted internal callers.
Code
from fastapi import FastAPI, Request
from slowapi import Limiter, _rate_limit_exceeded
from slowapi.errors import RateLimitExceeded
from slowapi.util import get_remote_address
from starlette.responses import JSONResponse
limiter = Limiter(
key_func=get_remote_address,
storage_uri='redis://localhost:6379/2',
default_limits=['300/minute'],
headers_enabled=True,
)
app = FastAPI()
app.state.limiter = limiter
app.add_exception_handler(RateLimitExceeded, _rate_limit_exceeded)
def user_key(request: Request) -> str:
api_key = request.headers.get('x-api-key')
if api_key:
return f'key:{api_key}'
if request.client and request.client.host.startswith('10.'):
return 'internal' # 内部调用统一低配额
return f'ip:{get_remote_address(request)}'
@app.get('/search')
@limiter.limit('60/minute', key_func=user_key)
async def search(request: Request, q: str = ''):
return {'query': q, 'results': 12}
@app.get('/report')
@limiter.limit('10/hour', key_func=user_key, cost=2)
async def report(request: Request):
return {'generated': True}
@app.get('/healthz')
async def healthz():
return {'status': 'up'} # 未加装饰器:探针不限流Report a problem with this exampleOpens a pre-filled issue on GitHub.