Skip to main content

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-limiter stack — 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_limit decorator and a drop-in RateLimitMiddleware (returns 429 + 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)

Source distribution for larzlimit 0.1.0
File Size Uploaded Provenance
larzlimit-0.1.0.tar.gz 7.6 kB Without provenance Details

Built distribution (wheel)

Table of built distributions (wheels) for larzlimit 0.1.0
File Interpreter ABI Platform
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.

Release history Release notifications | RSS feed

This release

0.1.0 This release

2 release files No provenance

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page