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
Metadata
Release files for larzlimit 0.1.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | |
|---|---|---|---|---|
| larzlimit-0.1.0.tar.gz | 7.6 kB | Without provenance | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| larzlimit-0.1.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 15.2 kB
Release files / larzlimit-0.1.0.tar.gz
| Download URL | larzlimit-0.1.0.tar.gz |
|---|---|
| Size | 7.6 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
c18a03ca744fcb96b65f5afbb7c02b88aa219dca1cb4939a98d80dd8fc709399
|
|
BLAKE2b-256 checksum How to use checksums |
377cb4ea594efdad809f40ab655b769e281fd0ca60d568e73076aac43872a900
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.12.13
|
Release files / larzlimit-0.1.0-py3-none-any.whl
| Download URL | larzlimit-0.1.0-py3-none-any.whl |
|---|---|
| Size | 7.6 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
e435e0eb446bdca22498042e2cf7790027600e921cfd8ca8c12c2a3d2fe57909
|
|
BLAKE2b-256 checksum How to use checksums |
458ceaa67a745974da51ce7bd2131bd04e613b567b0b2fcdce8846bd6022c5d1
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.12.13
|
Security for larzlimit 0.1.0
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
No provenance found
None of the files in this release were uploaded with provenance metadata.
A note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.
To learn more about protecting yourself from malicious actors, visit our package security documentation.