Rust-powered rate limiting SDK for Python
Project description
Pace Python SDK
Pace is a Rust-powered Python SDK for rate limiting, request protection, and lightweight traffic control. It exposes a small Python API backed by the native engine in pace_sdk.pace_native, so you can apply protection logic with minimal overhead.
The SDK is designed for two common use cases:
- Direct checks in application code.
- Framework integration for FastAPI and Django.
Features
- Native Rust execution for the core rate-limiting logic.
- Multiple algorithms: token bucket, sliding window, fixed window, and leaky bucket.
- Protection modes for active enforcement, shadow evaluation, and disablement.
- Structured results via Python dataclasses.
- Optional helpers for FastAPI and Django.
- Debug logging with compact or pretty output.
Installation
Install the package from PyPI:
pip install pace-python
Optional framework extras:
pip install "pace-python[fastapi]"
pip install "pace-python[flask]"
Quick Start
The main entrypoint is pace_sdk.Pace.
from pace_sdk import Algorithm, Pace, PaceConfig, ProtectionMode
pace = Pace(
PaceConfig(
mode=ProtectionMode.ACTIVE,
algorithm=Algorithm.TOKEN_BUCKET,
capacity=100,
refill_rate=10,
debug="compact",
)
)
result = pace.check(ip="203.0.113.10", route="/api/login")
if result.allowed:
print("Request permitted")
else:
print(f"Blocked: {result.reason}")
How It Works
At a high level, Pace follows this flow:
- You create a
PaceConfigdescribing algorithm, capacity, refill rate, mode, and debug behavior. Paceconverts that configuration into a Rust-native engine instance.- Each call to
check(...)delegates to the native engine. - The Rust result is normalized into a Python
CheckResultobject. - Logging is emitted when debug mode is enabled.
This keeps the Python surface small while moving the heavy lifting into Rust.
Public API
Import the public symbols from pace_sdk:
from pace_sdk import (
Algorithm,
Pace,
PaceConfig,
PaceFastAPI,
ProtectionMode,
pace_django,
)
Pace
Create the engine with Pace(config: PaceConfig).
Methods:
check(ip, route="/", key=None)check_detailed(ip, route="/", key=None)check_with_key(key, ip, route="/")
Notes:
check_detailed(...)is currently an alias forcheck(...).check_with_key(...)is a convenience wrapper for multi-tenant or user-scoped throttling.
CheckResult
check(...) returns a CheckResult dataclass with these fields:
allowed: final allow/block decision.would_block: whether the request would be blocked in non-enforcing modes.reason: short string reason from the engine.decision: structuredCanonicalDecisiondata.
PaceConfig
PaceConfig controls the engine behavior.
| Field | Type | Default | Purpose |
|---|---|---|---|
api_key |
`str | None` | None |
mode |
ProtectionMode |
ACTIVE |
Enforcement mode. |
algorithm |
Algorithm |
TOKEN_BUCKET |
Rate-limiting algorithm. |
capacity |
int |
100 |
Burst capacity or token pool size. |
refill_rate |
int |
10 |
Refill rate for token-based algorithms. |
debug |
`bool | str` | False |
identity_header |
`str | None` | None |
backend_url |
str |
"http://localhost:4000" |
Backend endpoint for telemetry and ingestion. |
rules |
Rules |
default factory | Rule configuration container. |
thresholds |
Thresholds |
default factory | Threshold and block-duration configuration. |
Enums
ProtectionMode:ACTIVE,SHADOW,DISABLEDAlgorithm:TOKEN_BUCKET,SLIDING_WINDOW,FIXED_WINDOW,LEAKY_BUCKETTrafficDecision:ALLOW,BLOCK,WOULD_BLOCKDecisionReason:WITHIN_LIMIT,LIMIT_EXCEEDED,TOKEN_EXHAUSTED
Framework Integrations
FastAPI
Use PaceFastAPI to create a dependency that protects a route:
from fastapi import FastAPI
from pace_sdk import Algorithm, Pace, PaceConfig, PaceFastAPI
app = FastAPI()
pace = Pace(PaceConfig(algorithm=Algorithm.SLIDING_WINDOW, capacity=50, refill_rate=5))
rate_limit = PaceFastAPI(pace)
@app.get("/login")
def login(_: None = rate_limit.limit("/login")):
return {"ok": True}
For middleware-style integration, the package also includes FastAPIMiddleware in pace_sdk.middleware.
Django
Wrap a Django view with pace_django(...):
from pace_sdk import Pace, PaceConfig, pace_django
pace = Pace(PaceConfig())
@pace_django(pace, route="/login")
def login_view(request):
...
Flask
The middleware module also exposes flask_middleware(...) for Flask decorators:
from pace_sdk.middleware import flask_middleware
protected_view = flask_middleware(pace)(view_func)
Logging and Debugging
Set debug on PaceConfig to control console output:
False: no decision logging.True: compact logging."compact": compact logging."pretty": multi-line, human-readable logging.
The runtime also respects the PACE_DEBUG=true environment variable and prints a native-engine load message.
Result Structure
The decision field on CheckResult contains structured metadata such as:
decisionreasonalgorithmrouteipkeyremaininglatency_msmode
This is useful when you want to inspect enforcement behavior without parsing logs.
Common Usage Patterns
Route-specific throttling
Call check(ip, route="/path") for path-aware protection.
User-scoped throttling
Call check_with_key("user-id", ip, route) to group requests by account or session.
Shadow mode rollout
Use ProtectionMode.SHADOW when you want to observe what would be blocked before enforcing it.
Identity headers
Set identity_header in PaceConfig when your framework integration should read a user or tenant key from headers.
Example
from pace_sdk import Algorithm, Pace, PaceConfig, ProtectionMode
pace = Pace(
PaceConfig(
mode=ProtectionMode.SHADOW,
algorithm=Algorithm.FIXED_WINDOW,
capacity=20,
refill_rate=5,
debug="pretty",
)
)
result = pace.check("127.0.0.1", "/api/payments", key="tenant-42")
print(result.allowed)
print(result.would_block)
print(result.decision.reason)
Project Layout
pace_sdk/client.py: mainPaceengine wrapper.pace_sdk/core.py: thread-safe engine variant.pace_sdk/types.py: enums, configuration objects, and result dataclasses.pace_sdk/helpers.py: FastAPI and Django helpers.pace_sdk/middleware.py: Flask and FastAPI middleware adapters.pace_sdk/telemetry.py: queued telemetry delivery.pace_sdk/logger.py: debug formatting and decision logging.
Notes
- The package name on PyPI is
pace-python. - The import namespace used by the SDK is
pace_sdk. - The native module is built by Maturin and loaded as
pace_sdk.pace_native.
License
Add your license information here if the project is distributed publicly.
Project details
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distributions
Built Distributions
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 pace_python-1.0.3-cp38-abi3-win_amd64.whl.
File metadata
- Download URL: pace_python-1.0.3-cp38-abi3-win_amd64.whl
- Upload date:
- Size: 244.6 kB
- Tags: CPython 3.8+, Windows x86-64
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
0336361b59b2643c3e25d7beb6ced926d1732f3689d9783294645a9629d7c583
|
|
| MD5 |
ee2896fd24e0b3c2f5fab1b58ac9524c
|
|
| BLAKE2b-256 |
456eb79adf76faf86775d578d27084e938e4e74ad0b286069dc0e1faa1f8aad0
|
File details
Details for the file pace_python-1.0.3-cp38-abi3-manylinux_2_34_x86_64.whl.
File metadata
- Download URL: pace_python-1.0.3-cp38-abi3-manylinux_2_34_x86_64.whl
- Upload date:
- Size: 403.8 kB
- Tags: CPython 3.8+, manylinux: glibc 2.34+ x86-64
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
583cd397d6fde4f0c3552a33bdaa777a038dee079ebedceec812b20aa9307c13
|
|
| MD5 |
b86f29099e568c949e34ea72be1b68ba
|
|
| BLAKE2b-256 |
021656de419746effd1e652d2d23a31edfe20736cadcf323103e1ffc68c3e799
|
File details
Details for the file pace_python-1.0.3-cp38-abi3-macosx_11_0_arm64.whl.
File metadata
- Download URL: pace_python-1.0.3-cp38-abi3-macosx_11_0_arm64.whl
- Upload date:
- Size: 347.5 kB
- Tags: CPython 3.8+, macOS 11.0+ ARM64
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
17558748c5bebcd544f5a8c5a18c97882d3dc0128223b3615ed6d50591bafffd
|
|
| MD5 |
326e7cb63906bfd7d8c834f213880e41
|
|
| BLAKE2b-256 |
52c537f7e9942c2919ca186650e56d0e30da40da833d66ec965c61eba09b5984
|