A rate limiter for FastAPI without using Redis.
Project description
# FastAPI Throttle
A lightweight, in-memory rate limiter for FastAPI applications that requires no external dependencies.
Table of Contents
- Overview
- Requirements
- Installation
- Quick Start
- Features
- Usage Examples
- Configuration
- How It Works
- Limitations
- When to Use
- Testing
- Contributing
- Roadmap
- License
Overview
FastAPI Throttle helps you control API request rates without Redis or other external services. It's designed for applications where simplicity and minimal dependencies are priorities.
Requirements
- Python 3.8+
- FastAPI
Installation
pip install fastapi-throttle
Quick Start
from fastapi import FastAPI, Depends
from fastapi_throttle import RateLimiter
app = FastAPI()
# Limit to 5 requests per minute
limiter = RateLimiter(times=5, seconds=60)
@app.get("/", dependencies=[Depends(limiter)])
async def root():
return {"message": "Hello World"}
Features
- No External Dependencies: Works without Redis or other services
- Simple Configuration: Just specify request count and time window
- Route-Level Control: Apply different limits to different endpoints
- FastAPI Integration: Works with FastAPI's dependency injection system
- Custom Keying (optional): Provide a
key_func(Request) -> strto limit by user, API key, path, etc. - Proxy-Aware (optional):
trust_proxy=Trueto useX-Forwarded-Forwhen behind proxies/CDNs - Rate-Limit Headers (optional): Add
X-RateLimit-*andRetry-Afterfor clients
Usage Examples
Different Limits for Different Routes
from fastapi import FastAPI, Depends
from fastapi_throttle import RateLimiter
app = FastAPI()
# Public endpoint: 10 requests per minute
public_limit = RateLimiter(times=10, seconds=60)
# Sensitive endpoint: 2 requests per minute
strict_limit = RateLimiter(times=2, seconds=60)
@app.get("/public", dependencies=[Depends(public_limit)])
async def public_endpoint():
return {"message": "Public endpoint"}
@app.get("/sensitive", dependencies=[Depends(strict_limit)])
async def sensitive_endpoint():
return {"message": "Sensitive endpoint"}
Using with APIRouter
from fastapi import APIRouter, Depends, FastAPI
from fastapi_throttle import RateLimiter
app = FastAPI()
router = APIRouter(prefix="/api")
# Apply same rate limit to all routes in this router
api_limit = RateLimiter(times=5, seconds=30)
@router.get("/resource", dependencies=[Depends(api_limit)])
async def get_resource():
return {"data": "Resource data"}
app.include_router(router)
Custom Key Function (limit by user or path)
from fastapi import FastAPI, Depends, Request
from fastapi_throttle import RateLimiter
app = FastAPI()
def user_key(req: Request) -> str:
# Example: extract user-id from header or auth (for demo only)
return req.headers.get("x-user-id", req.client.host or "unknown")
limiter = RateLimiter(times=10, seconds=60, key_func=user_key)
@app.get("/data", dependencies=[Depends(limiter)])
async def data():
return {"ok": True}
Behind proxy/CDN (trust X-Forwarded-For)
from fastapi import FastAPI, Depends
from fastapi_throttle import RateLimiter
app = FastAPI()
proxy_limit = RateLimiter(times=5, seconds=30, trust_proxy=True)
@app.get("/proxy", dependencies=[Depends(proxy_limit)])
async def proxy_route():
return {"ok": True}
Standard rate-limit headers
from fastapi import FastAPI, Depends
from fastapi_throttle import RateLimiter
app = FastAPI()
headers_limit = RateLimiter(times=5, seconds=60, add_headers=True)
@app.get("/limited", dependencies=[Depends(headers_limit)])
async def limited():
return {"message": "Check X-RateLimit-* headers"}
Configuration
The RateLimiter class parameters:
| Parameter | Type | Description |
|---|---|---|
times |
int | Maximum number of requests allowed in the time window |
seconds |
int | Time window in seconds |
detail |
str | Optional custom detail message for 429 responses |
key_func |
Callable[[Request], str] |
Optional custom function to compute the rate-limit key |
trust_proxy |
bool | If True, tries X-Forwarded-For for client identification (default False) |
add_headers |
bool | If True, adds X-RateLimit-Limit, X-RateLimit-Remaining, and Retry-After headers |
How It Works
The rate limiter:
- Identifies clients by IP address
- Stores request timestamps in memory
- Removes timestamps outside the current time window
- Counts requests within the window
- Returns HTTP 429 when limit is exceeded
Notes
- When
add_headers=True, successful responses (2xx) includeX-RateLimit-LimitandX-RateLimit-Remaining. On 429 responses, onlyRetry-Afteris included. - Use
trust_proxy=Trueonly when running behind a trusted proxy/load balancer that correctly setsX-Forwarded-For. The first IP is treated as the client.
Limitations
- Memory Storage: Data is lost when the application restarts
- Single-Server Only: Intended for monoliths/single-worker setups (in-memory, no cross-process sync)
- IP-Based Identification (default): With shared IPs/proxies, prefer
key_funcortrust_proxy - Memory Usage: Can grow with number of unique clients
When to Use
FastAPI Throttle is ideal for:
- Small to medium applications
- Single-server deployments
- Projects where simplicity is valued over advanced features
- Development and testing environments
For high-traffic production applications or distributed systems, prefer a distributed rate limiter (e.g., Redis-backed). This package intentionally avoids Redis and focuses on simplicity.
Testing
pip install -r requirements.txt
pytest --cov=fastapi_throttle -q
Contributing
- Pull requests are welcome. For major changes, please open an issue first to discuss what you would like to change.
- Make sure tests pass and add tests for new features.
- Follow the existing code style; this repo uses flake8 and pre-commit.
Roadmap
- Middleware variant in addition to dependency-based limiter
- (Maybe) Pluggable storage interface if a second backend is introduced later
License
MIT License. See LICENSE for details.
Project details
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file fastapi_throttle-0.1.8.tar.gz.
File metadata
- Download URL: fastapi_throttle-0.1.8.tar.gz
- Upload date:
- Size: 8.0 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.1.0 CPython/3.9.23
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
b0867be26bf3335cae0ecb7069c5cb7d246e14dbbd51329050af7043435370ce
|
|
| MD5 |
cc91ed43f267b91cad339f434bce6417
|
|
| BLAKE2b-256 |
b3efb71c86ced9cabc075ed4629178960ccdaf55b56f37a5392c574b2fa4ad35
|
File details
Details for the file fastapi_throttle-0.1.8-py3-none-any.whl.
File metadata
- Download URL: fastapi_throttle-0.1.8-py3-none-any.whl
- Upload date:
- Size: 8.6 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.1.0 CPython/3.9.23
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
ba04991eae1795b13b1d3a514a6967ba4588218dc92375e4c45e12cdebe160e2
|
|
| MD5 |
87bdeb8d01ee45e02ba93c202f993ff1
|
|
| BLAKE2b-256 |
1581972fa6f3fd2b45fa11fd7269aa24a242dd51c093ed45937f201224cc7e85
|