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

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

larzlimit-0.1.0.tar.gz (7.6 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

larzlimit-0.1.0-py3-none-any.whl (7.6 kB view details)

Uploaded Python 3

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

Hashes for larzlimit-0.1.0.tar.gz
Algorithm Hash digest
SHA256 c18a03ca744fcb96b65f5afbb7c02b88aa219dca1cb4939a98d80dd8fc709399
MD5 5d91f8e0b88cff3eca1e28e30090cdce
BLAKE2b-256 377cb4ea594efdad809f40ab655b769e281fd0ca60d568e73076aac43872a900

See more details on using hashes here.

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

Hashes for larzlimit-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 e435e0eb446bdca22498042e2cf7790027600e921cfd8ca8c12c2a3d2fe57909
MD5 15c688f3fe8136dd92b46db36073550e
BLAKE2b-256 458ceaa67a745974da51ce7bd2131bd04e613b567b0b2fcdce8846bd6022c5d1

See more details on using hashes here.

Release history Release notifications | RSS feed

This release

0.1.0 This release

2 files

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