larzlimit
Rate limiting in pure Python. Zero dependencies.
Enforce "at most N events per T seconds" — per IP, per user, per API token, or globally — with three strategies, a decorator, and WSGI middleware. No Redis, no server, nothing to install.
from larzlimit import RateLimiter
limiter = RateLimiter(limit=100, window=60) # 100 requests/minute per key
d = limiter.hit("user:42")
if not d.allowed:
retry_after = d.retry_after # seconds until allowed again
Why
- Zero dependencies, in-process. No Redis, no
flask-limiterstack — just the standard library, thread-safe. - Three strategies, one API. Pick what fits:
- sliding window (default) — accurate, no burst at window edges;
- fixed window — cheapest, allows edge bursts;
- token bucket — smooth average rate with a configurable burst.
- Per-key. Bucket by any string — IP, user id, API key — or use one global limit. Keys are independent.
- Batteries included. A
@rate_limitdecorator and a drop-inRateLimitMiddleware(returns429+Retry-After). - Tells you
retry_after. Every decision carries how long to wait, so you can set headers or back off precisely.
Install
pip install larzlimit
The limiter
from larzlimit import RateLimiter, RateLimitExceeded
limiter = RateLimiter(limit=5, window=60, strategy="sliding") # or "fixed" / "token"
limiter.allow("ip:1.2.3.4") # True/False (consumes on True)
d = limiter.hit("ip:1.2.3.4") # Decision(allowed, remaining, retry_after, limit)
limiter.check("ip:1.2.3.4") # raises RateLimitExceeded when over
limiter.reset("ip:1.2.3.4")
# token bucket with a burst of 20 but ~5/sec sustained
RateLimiter(limit=5, window=1, strategy="token", capacity=20)
Decorator
from larzlimit import rate_limit
@rate_limit(5, 60) # 5 calls/minute, global
def send_email():
...
@rate_limit(100, 60, key=lambda uid: uid) # 100/min per user
def api(uid):
...
@rate_limit(1, 10, on_limited=lambda d: {"error": "slow down"}) # handle instead of raise
def poll():
...
WSGI middleware
from larzlimit import RateLimitMiddleware
app = RateLimitMiddleware(app, limit=60, window=60) # 60/min per client IP
# over the limit -> 429 Too Many Requests + Retry-After header
Bucket by something other than IP with key=lambda environ: ... (an API key
header, a session id, …).
Scope
larzlimit is an in-process limiter — perfect for a single service, a worker, or behind a load balancer with sticky routing. For a limit shared across many machines you'd back it with shared storage; the strategy classes give you the correct algorithms to build on.
Tests
python -m unittest discover -s tests -v # 16 tests, zero deps
The Larz stack
Pure-Python, zero-dependency building blocks: larz · larzchain · larzmoney · larzcrypt · larzdb · larzagent · larzchart · larzmark · larztask · larzvault · larzvm · larzcache · larzvalidate · larzid · larzrpc · larzstate · larzhttp · larzconf · larzcron · larzlimit
License
MIT © larz-scripter
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 larzlimit-0.1.0.tar.gz.
File metadata
- Download URL: larzlimit-0.1.0.tar.gz
- Upload date:
- Size: 7.6 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via:
twine/7.0.0 CPython/3.12.13
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
c18a03ca744fcb96b65f5afbb7c02b88aa219dca1cb4939a98d80dd8fc709399
|
|
| MD5 |
5d91f8e0b88cff3eca1e28e30090cdce
|
|
| BLAKE2b-256 |
377cb4ea594efdad809f40ab655b769e281fd0ca60d568e73076aac43872a900
|
File details
Details for the file larzlimit-0.1.0-py3-none-any.whl.
File metadata
- Download URL: larzlimit-0.1.0-py3-none-any.whl
- Upload date:
- Size: 7.6 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via:
twine/7.0.0 CPython/3.12.13
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
e435e0eb446bdca22498042e2cf7790027600e921cfd8ca8c12c2a3d2fe57909
|
|
| MD5 |
15c688f3fe8136dd92b46db36073550e
|
|
| BLAKE2b-256 |
458ceaa67a745974da51ce7bd2131bd04e613b567b0b2fcdce8846bd6022c5d1
|