Projects open_keypool v0.1.0
PyPI Library Python 3.10+ Thread-Safe Doppler Sync

open_keypool

A lightweight, thread-safe Python library for pooling and rotating API keys to completely avoid HTTP 429 rate-limit errors. Automatically handles cooldown timers on rate limits and permanently disables invalid keys.

$ pip install open-keypool

Installation #

Install the official package from PyPI using pip:

bash
pip install open-keypool

Quickstart — Local Keys Array #

Instantiate KeyPool with a list of API key strings and rotate through them inside your API call loop:

python
from open_keypool import KeyPool, AllKeysExhaustedError

# Initialize key pool with Round-Robin strategy
pool = KeyPool(
    keys=["sk-key1", "sk-key2", "sk-key3"], 
    strategy="round_robin",
    cooldown_seconds=60
)

for attempt in range(pool.max_retries):
    try:
        key = pool.get_key()
        response = call_your_api(key)

        if response.status_code == 429:
            retry_after = float(response.headers.get("Retry-After", 0))
            pool.mark_rate_limited(key, retry_after=retry_after or None)
        elif response.status_code in (401, 403):
            pool.mark_invalid(key)
        else:
            pool.mark_success(key)
            break
    except AllKeysExhaustedError:
        print("All API keys are currently cooling down or disabled!")
        break

Quickstart — Doppler Sync Integration #

Pull keys dynamically from Doppler secrets manager with in-memory TTL caching:

python
import os
from open_keypool import KeyPool

DOPPLER_TOKEN = os.getenv("DOPPLER_TOKEN", "dp.st.YOUR_SERVICE_TOKEN")

# Load all secrets matching prefix 'MY_APP_' into an LRU pool
pool = KeyPool.from_doppler(
    token=DOPPLER_TOKEN,
    project="refactor-ai",
    config="dev",
    key_prefix="MY_APP_",
    strategy="lru",
)

# Get next active key
api_key = pool.get_key()

Interactive Live Playground #

Test rotation strategies, simulate HTTP 429 rate-limits, invalid 401 credentials, and watch live state recovery:

Live KeyPool Simulator

Strategy: Round-Robin
[System] Initialized KeyPool with 3 active keys ("sk-key1", "sk-key2", "sk-key3").

API Reference Specification #

Complete class methods, signature details, parameters, and exceptions for open_keypool:

class KeyPool

Core Class

A thread-safe pool of API keys with automatic cooldown and configurable rotation strategies (Round-Robin or LRU).

__init__(keys=None, max_retries=3, cooldown_seconds=60, strategy="round_robin")

Initializes a new KeyPool instance.

Parameter Type Default Description
keys list[str] | None None Initial list of API key strings. Must not be empty.
max_retries int 3 Reference maximum retry count for caller.
cooldown_seconds int 60 Duration in seconds a key stays in COOLDOWN state after rate limit.
strategy str "round_robin" Rotation strategy: "round_robin" or "lru".

@classmethod KeyPool.from_doppler(...)

Factory Method

Creates a KeyPool by fetching API keys from Doppler Secrets Manager via REST API. Caches keys in an in-memory 1-hour TTL cache.

Parameter Type Description
token str Doppler service token (e.g. "dp.st.YOUR_TOKEN").
project str Doppler project name.
config str Doppler config name (e.g. "dev", "prd").
key_prefix str | None Optional prefix filter for secret names.

@classmethod KeyPool.from_env(suffix, env_file=None, ...)

Factory Method

Creates a KeyPool from environment variables ending with the specified suffix. Automatically calls load_dotenv() if a .env file is present.

KeyPool.get_key() -> str

Method

Returns the next available ACTIVE API key. Automatically flips expired COOLDOWN keys back to ACTIVE before selection.

Raises AllKeysExhaustedError if no active keys are available in the pool.

KeyPool.handle_response(key, response, retry_after=None)

Method

Convenience helper method that inspects an HTTP response object or integer status code and automatically marks the key status accordingly (429 -> Cooldown, 401/403 -> Invalid, 2xx -> Success).

enum KeyState

Enum
  • ACTIVE — Key is healthy and ready for requests.
  • COOLDOWN — Key hit rate limit (429) and is temporarily paused.
  • DISABLED — Key failed authentication (401/403) and is permanently disabled.

class AllKeysExhaustedError(Exception)

Exception

Raised when get_key() is invoked but all keys in the pool are either on COOLDOWN or DISABLED.