Rate-limiter for FastAPI with the possibility of user-based rate limits
Project description
FastAPI rate limiter
This package adds a rate limiter to FastAPI using Redis.
Installation
First install Redis, then install the package using:
pip install fastapi-user-limiter
Usage
All the examples below can be found in example.py
(use uvicorn example:app --reload
to run).
Single and multiple rate limiters
You can use the rate_limit
function as a FastAPI Dependency to add one or several rate limiters to an endpoint:
from fastapi_user_limiter.limiter import RateLimiterConnection, rate_limiter
from fastapi import FastAPI, Depends
app = FastAPI()
# Max 2 requests per 5 seconds
@app.get("/single",
dependencies=[Depends(rate_limiter(RateLimiterConnection(), 2, 5))])
async def read_single():
return {"Hello": "World"}
# Max 1 requests per second and max 3 requests per 10 seconds
@app.get("/multi/{some_param}", dependencies=[
Depends(rate_limiter(RateLimiterConnection(), 1, 1)),
Depends(rate_limiter(RateLimiterConnection(), 3, 10))
])
async def read_multi(some_param: str):
return {"Hello": f"There {some_param}"}
Router/API-wide rate limits
You can also add a router-wide (or even API-wide) rate limiter that applies to all endpoints taken together, rather than per-endpoint:
from fastapi_user_limiter.limiter import RateLimiterConnection, rate_limiter
from fastapi import Depends, APIRouter
# The rate limiter in the router applies to the two endpoints together.
# If a request is made to /single, a request to /single2 within the next
# 3 seconds will result in a "Too many requests" error.
# This rate limiter must have a custom path value, preferably
# the same as the router's prefix value.
router = APIRouter(
prefix='/router',
dependencies=[Depends(rate_limiter(RateLimiterConnection(), 1, 3,
path='/router'))]
)
# Each endpoint also has its own, separate rate limiter
@router.get("/single",
dependencies=[Depends(rate_limiter(RateLimiterConnection(), 3, 20))])
async def read_single_router():
return {"Hello": "World"}
@router.get("/single2",
dependencies=[Depends(rate_limiter(RateLimiterConnection(), 5, 60))])
async def read_single2_router():
return {"Hello": "There"}
Per-user rate limits
By default, rate limits are applied per host (i.e. per IP address). However,
you may want to apply the rate limits on a per-user basis, especially if your
API has authentication. To do so, you can pass a custom async callable to the
user
argument of rate_limiter
, which extracts the username from the request
headers:
from fastapi_user_limiter.limiter import RateLimiterConnection, rate_limiter
from fastapi import Depends, FastAPI
app = FastAPI()
def get_user(headers):
# The username is assumed to be a bearer token,
# contained in the 'authorization' header.
username = headers['authorization'].strip('Bearer ')
return username
# 3 requests max per 20 seconds, per user
@app.post("/auth",
dependencies=[Depends(rate_limiter(RateLimiterConnection(), 3, 20,
user=get_user))])
async def read_with_auth(data: dict):
return {'input': data}
Future features
The package will soon have the additional feature of allowing each user account to have a different window size and max request count for each endpoint.
Project details
Release history Release notifications | RSS feed
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
Hashes for fastapi_user_limiter-0.6.0.tar.gz
Algorithm | Hash digest | |
---|---|---|
SHA256 | dee4e0a398c6e368be5cc1a58d4fbd7b3011e25ca4f2c88853d2d6d281a2194b |
|
MD5 | a9228d0b7ea996a1cb011c0d9861bbe1 |
|
BLAKE2b-256 | 8ab8d13d6eab230376627264267f62b88ca460f17ade1248717ece436b3dcefc |
Hashes for fastapi_user_limiter-0.6.0-py3-none-any.whl
Algorithm | Hash digest | |
---|---|---|
SHA256 | 49794d13123b18576383ddab69556e8ce79144d2a86c7dec0775f47049af9bab |
|
MD5 | d08c3f11375131f1057bf6c25496476c |
|
BLAKE2b-256 | 81b6436880778de458408b7855ddff4932d8be90f5681c9ea42a5bd65c29ca2c |