A request rate limiter for fastapi
Project description
fastapi-limiter-valkey
Introduction
FastAPI-Limiter-Valkey is a rate limiting tool for fastapi routes with lua script.
It is a friendly fork from FastAPI-Limiter and adapted to use Valkey
.
Requirements
Install
Just install from pypi
> pip install fastapi-limiter-valkey
Quick Start
FastAPI-Limiter-Valkey is simple to use, which just provide a dependency RateLimiter
, the following example allow 2
times
request per 5
seconds in route /
.
import valkey.asyncio as valkey
import uvicorn
from contextlib import asynccontextmanager
from fastapi import Depends, FastAPI
from fastapi_limiter import FastAPILimiter
from fastapi_limiter.depends import RateLimiter
@asynccontextmanager
async def lifespan(_: FastAPI):
valkey_connection = valkey.from_url("valkey://localhost:6379", encoding="utf8")
await FastAPILimiter.init(valkey_connection)
yield
await FastAPILimiter.close()
app = FastAPI(lifespan=lifespan)
@app.get("/", dependencies=[Depends(RateLimiter(times=2, seconds=5))])
async def index():
return {"msg": "Hello World"}
if __name__ == "__main__":
uvicorn.run("main:app", debug=True, reload=True)
Usage
There are some config in FastAPILimiter.init
.
valkey
The async valkey
instance.
prefix
Prefix of valkey key.
identifier
Identifier of route limit, default is ip
, you can override it such as userid
and so on.
async def default_identifier(request: Request):
forwarded = request.headers.get("X-Forwarded-For")
if forwarded:
return forwarded.split(",")[0]
return request.client.host + ":" + request.scope["path"]
callback
Callback when access is forbidden, default is raise HTTPException
with 429
status code.
async def default_callback(request: Request, response: Response, pexpire: int):
"""
default callback when too many requests
:param request:
:param pexpire: The remaining milliseconds
:param response:
:return:
"""
expire = ceil(pexpire / 1000)
raise HTTPException(
HTTP_429_TOO_MANY_REQUESTS, "Too Many Requests", headers={"Retry-After": str(expire)}
)
Multiple limiters
You can use multiple limiters in one route.
@app.get(
"/multiple",
dependencies=[
Depends(RateLimiter(times=1, seconds=5)),
Depends(RateLimiter(times=2, seconds=15)),
],
)
async def multiple():
return {"msg": "Hello World"}
Not that you should note the dependencies orders, keep lower of result of seconds/times
at the first.
Rate limiting within a websocket.
While the above examples work with rest requests, FastAPI also allows easy usage of websockets, which require a slightly different approach.
Because websockets are likely to be long lived, you may want to rate limit in response to data sent over the socket.
You can do this by rate limiting within the body of the websocket handler:
@app.websocket("/ws")
async def websocket_endpoint(websocket: WebSocket):
await websocket.accept()
ratelimit = WebSocketRateLimiter(times=1, seconds=5)
try:
while True:
try:
data = await websocket.receive_text()
await ratelimit(websocket, context_key=data) # NB: context_key is optional
await websocket.send_text("Hello, world")
except HTTPException:
await websocket.send_text("Hello again")
except WebSocketDisconnect:
print("Client disconnected")
finally:
await websocket.close()
Lua script
The lua script used.
local key = KEYS[1]
local limit = tonumber(ARGV[1])
local expire_time = ARGV[2]
local current = tonumber(server.call('get', key) or "0")
if current > 0 then
if current + 1 > limit then
return server.call("PTTL", key)
else
server.call("INCR", key)
return 0
end
else
server.call("SET", key, 1, "px", expire_time)
return 0
end
License
This project is licensed under the Apache-2.0 License.
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
File details
Details for the file fastapi_limiter_valkey-0.1.1.tar.gz
.
File metadata
- Download URL: fastapi_limiter_valkey-0.1.1.tar.gz
- Upload date:
- Size: 8.2 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/5.1.1 CPython/3.12.7
File hashes
Algorithm | Hash digest | |
---|---|---|
SHA256 | 9ca885fc60849fd507788c92dcc948764199ee9712d507bf54b953d3f0702f5e |
|
MD5 | c890247a48654c59ef061b1be5c15d71 |
|
BLAKE2b-256 | 5bb25e4043c063d4d0a1a1c65181f9d31455edf636ac2df86f2a37b68e810680 |
File details
Details for the file fastapi_limiter_valkey-0.1.1-py3-none-any.whl
.
File metadata
- Download URL: fastapi_limiter_valkey-0.1.1-py3-none-any.whl
- Upload date:
- Size: 15.8 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/5.1.1 CPython/3.12.7
File hashes
Algorithm | Hash digest | |
---|---|---|
SHA256 | 7bd0f368e8fa406852af52faffbdbfa5e8349e66c39f0d3fb4d6cfa7abd680fa |
|
MD5 | 07ed05c523f3740c16f4103943bdb589 |
|
BLAKE2b-256 | 28adeada690fce4ec4673465e8085282807a7542c2f7d380c36c4e283882c413 |