FastAPI Limiter
fastapi-limiter is a Python library that provides robust request rate limiting capabilities for FastAPI applications. It integrates with Redis as a backend to store and manage rate limit counters. Currently at version 0.2.0, it's an early-stage project with releases driven by feature additions and bug fixes, and primarily supports Python 3.9 and above.
Warnings
- gotcha You must explicitly call `await FastAPILimiter.init(redis_client)` during your FastAPI application's startup event (e.g., in `@app.on_event('startup')`). Failing to do so will result in the rate limiter not being initialized and will cause errors when endpoints attempt to use it.
- gotcha For async FastAPI applications, always use `redis.asyncio.Redis` (or methods like `Redis.from_url` from `redis.asyncio`) for your Redis client. Using the synchronous `redis.Redis` directly in an `async def` context will block the event loop, leading to performance degradation and concurrency issues.
- breaking As a 0.x.x version library, `fastapi-limiter` may introduce breaking changes in minor or patch releases without strictly adhering to semantic versioning. The API surface may evolve rapidly.
- gotcha The `redis` library, which provides the Redis client, is a peer dependency and not automatically installed alongside `fastapi-limiter`. You must install it separately for the library to function.
Install
-
pip install fastapi-limiter redis
Imports
- FastAPILimiter
from fastapi_limiter import FastAPILimiter
- RateLimiter
from fastapi_limiter.depends import RateLimiter
- Redis
from redis.asyncio import Redis
Quickstart
import os
from fastapi import FastAPI, Depends
from fastapi_limiter import FastAPILimiter
from fastapi_limiter.depends import RateLimiter
from redis.asyncio import Redis # Use asyncio for FastAPI
app = FastAPI()
# Configure Redis URL via environment variable or default to localhost
REDIS_URL = os.environ.get('REDIS_URL', 'redis://localhost:6379')
@app.on_event('startup')
async def startup():
redis_client = Redis.from_url(REDIS_URL, encoding='utf8', decode_responses=True)
await FastAPILimiter.init(redis_client)
print("FastAPILimiter initialized.")
@app.get('/', dependencies=[Depends(RateLimiter(times=2, seconds=5))])
async def homepage():
return {'message': 'Hello world!'}
@app.get('/limited', dependencies=[Depends(RateLimiter(times=1, seconds=10))])
async def limited_endpoint():
return {'message': 'This endpoint is more limited!'}
# To run this example:
# 1. Install uvicorn: pip install uvicorn
# 2. Run Redis locally (e.g., via Docker: docker run --name some-redis -p 6379:6379 -d redis)
# 3. Save the code as main.py
# 4. Execute: uvicorn main:app --reload