rotapool
Async resource pool with inline health feedback, automatic cooldown, and retry -- for API keys, proxies, GPU workers, or anything that can rate-limit you or go down.
rotapool is designed for resources where every call is also useful health evidence. Instead of relying on a separate prober, callers signal whether the selected resource should stay healthy, cool down temporarily, or be disabled.
| Signal | Meaning |
|---|---|
| normal return / any other exception | Resource is healthy |
CooldownResource |
Temporarily overloaded, e.g. HTTP 429 |
DisableResource |
Permanently unusable, e.g. revoked key |
Designed for AI coding agents.
rotapoolexposes machine-readable usage notes via agent-readable, including operation contracts, do/don't rules, anti-patterns, and failure modes.npx skills add zydo/skills --skill agent-readable
Install
pip install rotapool
# or
uv add rotapool
Requires Python 3.10+. Zero runtime dependencies. Optional extras: pip install "rotapool[agent]" for agent-readable, pip install "rotapool[prometheus]" for a Prometheus collector over pool.stats(). A runnable scrape is in examples/prometheus_pool.py.
Quick Start
import httpx
from rotapool import CooldownResource, DisableResource, Pool, Resource
pool = Pool(
resources=[
Resource(resource_id="key-1", value="sk-aaa"),
Resource(resource_id="key-2", value="sk-bbb"),
Resource(resource_id="key-3", value="sk-ccc"),
],
max_attempts=3,
cooldown_table=(30.0, 120.0, 300.0, 600.0),
)
@pool.use()
async def call_upstream(resource, url, payload):
async with httpx.AsyncClient() as client:
resp = await client.post(
url,
headers={"Authorization": f"Bearer {resource.value}"},
json=payload,
)
if resp.status_code == 429:
raise CooldownResource(reason="rate limited")
if resp.status_code == 401:
raise DisableResource(reason="invalid key")
return resp.json()
result = await call_upstream("https://api.example.com/v1/chat", {"prompt": "hi"})
Runnable versions of this (no httpx) and of the Prometheus extra live in examples/.
Documentation
- Usage guide covers pool initialization,
@pool.use(), directpool.run(), resource types, accepted operation shapes, and observability. - Behavior guide explains selection strategies, cooldown escalation, retry behavior, in-flight cancellation, cancellation discrimination, admin control, and metrics (
snapshot(),stats(), optional Prometheus collector). - API reference documents
Pool,Resource,snapshot(),stats(), admin methods, exceptions, and the optional Prometheus collector. - Pitfalls and testing lists common anti-patterns, cancellation gotchas, test commands, and license information.
- Changelog lists released versions.
examples/has runnable scripts:basic_usage.py(use()/run()),prometheus_pool.py(optional scrape).
Core Concepts
- Each
Poolowns a set ofResource[T]objects.Tcan be a bearer token, proxy URL, browser session, GPU worker, client object, or any other value. - Each
run()attempt receives one selectedResource. - Raising
CooldownResourcemarks that resource temporarily unavailable and retries elsewhere when possible. - Raising
DisableResourceremoves that resource from selection untilenable()is called. - Any other exception is treated as caller or business failure, not resource failure, and propagates.
@pool.use()is a decorator convenience overpool.run().
Testing
uv sync --all-extras
uv run pytest --cov
See pitfalls and testing for pip-based setup and additional notes.
License
MIT
Release files for rotapool 0.4.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| rotapool-0.4.0.tar.gz | 79.8 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| rotapool-0.4.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 107.0 kB
Release files / rotapool-0.4.0.tar.gz
| Download URL | rotapool-0.4.0.tar.gz |
|---|---|
| Size | 79.8 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
2e0a1eabe1f201629bd5e8155fe4b83b3f944efc20d808605b17354e56d30c12
|
|
BLAKE2b-256 checksum How to use checksums |
dc5386ff60fe0a889e4459085b4bfa13b39a6c3edb2afe98fcd25c36c46fc269
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Sep 3, 2026.
Transparency logRelease files / rotapool-0.4.0-py3-none-any.whl
| Download URL | rotapool-0.4.0-py3-none-any.whl |
|---|---|
| Size | 27.1 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
70b79b8138762e9f3ba83ebef3b1cb05a0f0e4ae512665eac5b7742b4f55d275
|
|
BLAKE2b-256 checksum How to use checksums |
904cf5fbd8a8aaca3f87553a7a25d42c1298706955aaf8377a5e5b343a10b2df
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Sep 3, 2026.
Transparency log