A Python library for rate limiting using the Token Bucket algorithm
Project description
BucketFlow
A Python library for rate limiting using the Token Bucket algorithm, with support for hierarchical rate limiting.
Installation
pip install bucketflow
For distributed rate limiting with Redis:
pip install bucketflow[distributed]
What is Token Bucket?
The Token Bucket algorithm works by having a bucket that is filled with tokens at a constant rate. Each request consumes one or more tokens. If there are enough tokens, the request is allowed; otherwise, it's either blocked or rejected.
Key features:
- Controls the average rate of requests
- Allows for bursts of traffic up to a configurable limit
- Simple to understand and implement
Basic Usage
from bucketflow import TokenBucket
# Create a token bucket with capacity of 10 tokens, filling at 2 tokens per second
bucket = TokenBucket(capacity=10, fill_rate=2)
# Consume a token (returns True if successful, False if not enough tokens)
if bucket.consume():
# Perform rate-limited operation
process_request()
else:
# Handle rate limit exceeded
return_rate_limit_error()
# Consume multiple tokens
bucket.consume(5)
# Block until tokens are available
bucket.consume(3, block=True)
Decorator Usage
from bucketflow import rate_limit
import time
# Allow 2 calls per second with a burst capacity of 5
@rate_limit(tokens_per_second=2, capacity=5)
def api_request():
# This function can only be called at the specified rate
return fetch_data_from_api()
# Non-blocking behavior (raises RateLimitExceeded if exceeded)
@rate_limit(tokens_per_second=1, block=False)
def limited_function():
pass
Async Support
from bucketflow.async_token_bucket import AsyncTokenBucket, async_rate_limit
import asyncio
async def example():
# Create an async token bucket
bucket = AsyncTokenBucket(capacity=10, fill_rate=2)
# Consume tokens asynchronously
if await bucket.consume(5):
await process_request()
# Decorate async functions
@async_rate_limit(tokens_per_second=2)
async def rate_limited_api_call():
response = await make_http_request()
return response
Hierarchical Rate Limiting
BucketFlow supports hierarchical rate limiting, where tokens must be consumed from multiple buckets in a parent-child relationship:
from bucketflow.hierarchical import HierarchicalTokenBucket
# Create a root bucket with 100 tokens, filling at 10 tokens per second
root = HierarchicalTokenBucket(capacity=100, fill_rate=10, name="root")
# Create child buckets
user1 = HierarchicalTokenBucket(capacity=20, fill_rate=2, parent=root, name="user1")
user2 = HierarchicalTokenBucket(capacity=30, fill_rate=3, parent=root, name="user2")
# Create a nested child bucket
api1 = HierarchicalTokenBucket(capacity=10, fill_rate=1, parent=user2, name="api1")
# When consuming from api1, tokens are also consumed from user2 and root
api1.consume(5) # Takes 5 tokens from api1, user2, and root
Creating a Bucket Hierarchy from Configuration
You can define and create an entire hierarchy from a dictionary configuration:
from bucketflow.hierarchical import create_bucket_hierarchy
# Define the hierarchy
config = {
"name": "global",
"capacity": 100,
"fill_rate": 10,
"children": [
{
"name": "service1",
"capacity": 40,
"fill_rate": 4,
"children": [
{
"name": "endpoint1",
"capacity": 15,
"fill_rate": 1.5
}
]
}
]
}
# Create all buckets
buckets = create_bucket_hierarchy(config)
# Access buckets by name
buckets["endpoint1"].consume(5)
Benefits of Hierarchical Rate Limiting
- Multi-level rate limiting: Enforce limits at multiple levels of granularity
- Resource allocation: Divide resources among users, services, or endpoints
- Priority-based access: Allocate more resources to critical services
- Easy configuration: Create complex hierarchies from dictionary configurations
- Organizational structure mapping: Model company → department → team → user hierarchies
Distributed Rate Limiting
For rate limiting across multiple processes or servers, use the Redis-backed implementation:
import redis
from bucketflow.distributed import RedisTokenBucket
# Connect to Redis
redis_client = redis.Redis(host='localhost', port=6379, db=0)
# Create a distributed token bucket
bucket = RedisTokenBucket(
redis_client=redis_client,
key="api-rate-limit", # Unique key for this rate limiter
capacity=10,
fill_rate=2
)
# Use it just like a regular token bucket
if bucket.consume():
# Process the request
pass
License
MIT
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file bucketflow-0.1.0.tar.gz.
File metadata
- Download URL: bucketflow-0.1.0.tar.gz
- Upload date:
- Size: 13.9 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.0.1 CPython/3.12.2
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
6a815d5e913501b188a44332e2afd8dad6e2ea867be2ce1d10627737014c2dcd
|
|
| MD5 |
844cbf0f0178b33e64cc539d485edd3d
|
|
| BLAKE2b-256 |
cdf453ee8aea66649fc2730306a1163e7704d7445c4af6582f9fde4e373ca457
|
File details
Details for the file bucketflow-0.1.0-py3-none-any.whl.
File metadata
- Download URL: bucketflow-0.1.0-py3-none-any.whl
- Upload date:
- Size: 11.8 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.0.1 CPython/3.12.2
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
25fdcf9f6b339ca0401e9947016e5aa7a0d52f9861051cfeb1aacb0e2c3fc4f9
|
|
| MD5 |
aea0783604c55ba958312fd9d2f6108f
|
|
| BLAKE2b-256 |
43135f1df3736881901dc9ffbeb85346b94495f5eb190dfbac19c27260bd7539
|