Skip to main content

rateflow

Lightweight, decorator-based rate limiting for Python

View rateflow on PyPI

PyPI version Python versions Build License Redis

A lightweight, decorator-based rate limiter for Python applications.

rateflow protects synchronous functions, asynchronous functions, Flask routes, and FastAPI endpoints with four algorithms:

  • Fixed window
  • Sliding window
  • Token bucket
  • Leaky bucket

It supports process-local in-memory state and Redis-backed shared state.

Requirements

  • Python 3.10 or newer
  • Redis 6 or newer when using Redis storage

The current package release includes the Redis, Flask, FastAPI, Uvicorn, and pytest dependencies declared in the project metadata.

Installation

python -m pip install rateflow

Quick start

Configure a storage backend before defining decorated functions:

from rateflow import Algorithm, Configure, Storage, rate_limit
from rateflow.exceptions import RateLimitExceed

Configure.configure(Storage.MEMORY)


@rate_limit({
    "algorithm": Algorithm.FIXED_WINDOW,
    "calls": 5,
    "period": 60,
})
def get_data():
    return {"status": "ok"}


try:
    get_data()
except RateLimitExceed:
    print("rate limit exceeded")

The limiter consumes a permit before calling the wrapped function. A failed wrapped function still consumes the permit.

Configuration

The algorithm field is required. Required fields depend on the algorithm:

Algorithm Required fields Description
Algorithm.FIXED_WINDOW calls, period Allows a fixed number of calls during each period.
Algorithm.SLIDING_WINDOW calls, period Tracks permitted request timestamps over a rolling period.
Algorithm.TOKEN_BUCKET capacity, refill_rate Consumes tokens and replenishes them continuously.
Algorithm.LEAKY_BUCKET capacity, leak_rate Accepts requests while the bucket has capacity and drains continuously.

Invalid or incomplete configuration raises ValueError. The legacy refill_bucket field is accepted as an alias for refill_rate.

Token bucket

@rate_limit({
    "algorithm": Algorithm.TOKEN_BUCKET,
    "capacity": 20,
    "refill_rate": 2,  # tokens per second
})
def send_request():
    return {"status": "sent"}

Token buckets start full, refill continuously, and consume one token per permitted request.

Keys and shared limits

By default, each decorated function uses its qualified name as its storage key. A custom key can be supplied in the configuration or with the decorator's keyword argument:

@rate_limit(
    {"algorithm": Algorithm.FIXED_WINDOW, "calls": 10, "period": 60},
    key="api:search",
)
def search(query: str):
    return query

When both key forms are provided, the decorator argument takes precedence. Functions using the same key share rate-limit state, so keys should be stable and unique within the selected storage backend.

Storage backends

In-memory

Use in-memory storage for tests, local development, or a single-process application:

Configure.configure(Storage.MEMORY)

State is process-local and is lost when the process exits. If no backend is configured, the first decorator currently selects in-memory storage automatically; explicit configuration is recommended.

Redis

Use Redis when state must be shared between workers, containers, or hosts:

Configure.configure(
    Storage.REDIS,
    {
        "url": "redis://localhost:6379/0",
        "ttl": 3600,
        "socket_connect_timeout": 5,
    },
)

Redis must be running before application startup. Stored keys use a configurable TTL. Redis acquisition uses an optimistic transaction, but applications should still test their required concurrency guarantees under production load.

Async usage

The decorator supports coroutine functions and checks the limit before awaiting the endpoint:

from rateflow import Algorithm, Configure, Storage, rate_limit

Configure.configure(Storage.MEMORY)


@rate_limit({
    "algorithm": Algorithm.SLIDING_WINDOW,
    "calls": 10,
    "period": 60,
})
async def async_endpoint():
    return {"status": "ok"}

With Redis storage, the current check uses synchronous Redis I/O and may block the event loop during network or Redis delays.

Framework usage

The decorator can be applied to Flask and FastAPI endpoints in the same way as ordinary functions:

@app.get("/items")
@rate_limit({"algorithm": Algorithm.FIXED_WINDOW, "calls": 10, "period": 60})
def items():
    return {"status": "ok"}

Errors

  • ValueError is raised for missing or invalid rate-limit configuration.
  • RateLimitExceed is raised when a permitted request would exceed its limit.

License

MIT License: LICENSE

Download files

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

Source Distribution

rateflow-1.0.1.tar.gz (17.8 kB view details)

Uploaded Source

Built Distribution

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

rateflow-1.0.1-py3-none-any.whl (20.1 kB view details)

Uploaded Python 3

File details

Details for the file rateflow-1.0.1.tar.gz.

File metadata

  • Download URL: rateflow-1.0.1.tar.gz
  • Upload date:
  • Size: 17.8 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.12.3 {"installer":{"name":"uv","version":"0.12.3","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

File hashes

Hashes for rateflow-1.0.1.tar.gz
Algorithm Hash digest
SHA256 f2f4346cb0fa6450bbc184585a7c92b52668721fdbfa0ddf6b8ee74d88c8ccd4
MD5 abf2796a8aa5b73631bca4e2112f7bd9
BLAKE2b-256 552c076ccc48cf90af9f4986a6ec1b55ac6a8403bd1ecd8f87ee87d9e350a31c

See more details on using hashes here.

File details

Details for the file rateflow-1.0.1-py3-none-any.whl.

File metadata

  • Download URL: rateflow-1.0.1-py3-none-any.whl
  • Upload date:
  • Size: 20.1 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.12.3 {"installer":{"name":"uv","version":"0.12.3","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

File hashes

Hashes for rateflow-1.0.1-py3-none-any.whl
Algorithm Hash digest
SHA256 6b7d43c2c5c1c868fbc708d9d2a0f55e370229707db60754e73b05040293bbbf
MD5 92049c7a28eec4f1919f4eb9a75e1435
BLAKE2b-256 b7bf1852be9c89a0057d64205930fef19e9ae88d836413b242a9e5183f7e1a0b

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page