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

Metadata

Release files for rateflow 1.0.1

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for rateflow 1.0.1
File Size Uploaded
rateflow-1.0.1.tar.gz 17.8 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for rateflow 1.0.1
File Interpreter ABI Platform
rateflow-1.0.1-py3-none-any.whl Python 3 none any Details

Total release size: 37.8 kB

Release files / rateflow-1.0.1.tar.gz

Download URL rateflow-1.0.1.tar.gz
Size 17.8 kB
Tags Source
SHA-256 checksum
How to use checksums
f2f4346cb0fa6450bbc184585a7c92b52668721fdbfa0ddf6b8ee74d88c8ccd4
BLAKE2b-256 checksum
How to use checksums
552c076ccc48cf90af9f4986a6ec1b55ac6a8403bd1ecd8f87ee87d9e350a31c
Upload date
Uploaded using Trusted Publishing?
What is 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}

Release files / rateflow-1.0.1-py3-none-any.whl

Download URL rateflow-1.0.1-py3-none-any.whl
Size 20.1 kB
Tags Python 3
SHA-256 checksum
How to use checksums
6b7d43c2c5c1c868fbc708d9d2a0f55e370229707db60754e73b05040293bbbf
BLAKE2b-256 checksum
How to use checksums
b7bf1852be9c89a0057d64205930fef19e9ae88d836413b242a9e5183f7e1a0b
Upload date
Uploaded using Trusted Publishing?
What is 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}

Release history Release notifications | RSS feed

This release

1.0.1 This release

2 release 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