Skip to main content

keycycle

Thread-safe key rotation and rate limiting manager for LLM API keys. Supports OpenAI-compatible providers and Agno models. Persists usage data to SQL (MySQL/TiDB).

Installation

pip install keycycle
# Optional extras
pip install keycycle[openai]
pip install keycycle[agno]
pip install keycycle[all]

Configuration

Define API keys in a .env file. Format: provider_API_KEY_index. Also specify the count with NUM_provider.

# .env
NUM_OPENAI=2
OPENAI_API_KEY_1=sk-...
OPENAI_API_KEY_2=sk-...

# Optional: DB Connection (Defaults to TIDB_DB_URL env var)
TIDB_DB_URL=mysql+pymysql://user:pass@host:port/db

Supported providers for auto-loading: OPENROUTER, GEMINI, CEREBRAS, GROQ.

Usage

OpenAI Client (Sync & Async)

Wraps the standard openai library. Drop-in replacement.

import os
from keycycle import MultiProviderWrapper

# 1. Initialize Wrapper
wrapper = MultiProviderWrapper.from_env(
    provider="openai",
    default_model_id="gpt-4o",
    db_url=os.getenv("DATABASE_URL") 
)

# 2. Get Rotating Client (Standard OpenAI Interface)
client = wrapper.get_openai_client(estimated_tokens=500)

# 3. Use standard methods
response = client.chat.completions.create(
    messages=[{"role": "user", "content": "Hello"}],
    model="gpt-4o"
)
print(response.choices[0].message.content)

# Async
async_client = wrapper.get_async_openai_client()
# await async_client.chat.completions.create(...)

Agno Integration

Wraps Agno models with rotation logic.

from keycycle import MultiProviderWrapper

wrapper = MultiProviderWrapper.from_env(provider="openai", default_model_id="gpt-4o")

# Returns a model instance with rotation mixin
model = wrapper.get_model(
    id="gpt-4o",
    instructions="You are a bot."
)

model.generate("Hello world")

Statistics

Print usage stats to console (uses rich).

wrapper.print_global_stats()
wrapper.print_key_stats(0) # Stats for key index 0
wrapper.print_model_stats("gpt-4o")

Turning usage tracking off

Usage tracking is the database half of the library: it persists every call to usage_logs and rehydrates each key's counters on start. The in-memory accounting that actually drives rotation and rate limiting is always on.

Turn tracking off and no database is required at all - no db_url, no TIDB_DB_URL.

from keycycle import MultiProviderWrapper

# No DB is constructed, no connection string needed.
wrapper = MultiProviderWrapper.from_env(
    provider="openai",
    default_model_id="gpt-4o",
    track_usage=False,
)

Flip it at runtime on the wrapper (it propagates to the managers it owns) or on a manager directly:

wrapper.track_usage = False   # stop writing from here on
wrapper.track_usage = True    # resume (raises ConfigurationError if built without a DB)

wrapper.manager.track_usage = False  # same switch, one manager

Or skip tracking for a single call - the keyword is stripped before the request reaches the underlying client:

response = client.chat.completions.create(
    model="gpt-4o",
    messages=[{"role": "user", "content": "Hello"}],
    track_usage=False,
)

track_usage=True on a call works too, and forces the write even when the wrapper's own setting is off. Asking for it with no database configured raises ConfigurationError.

Features

  • Rotation: Round-robin selection. Skips keys on cooldown.
  • Rate Limiting: Enforces RPM, TPM, RPD, TPD limits.
  • Failover: Auto-rotates on 429 Too Many Requests.
  • Persistence: Logs usage to SQL database for historical tracking.
  • Thread-Safe: Safe for concurrent usage.

Development and Publishing

The project includes scripts to automate the build and release process to PyPI.

Publishing Scripts

  • publish.sh: Bash script for Linux/macOS.
  • publish.ps1: PowerShell script for Windows.

These scripts perform the following:

  1. Load PYPI_TOKEN from the .env file.
  2. Clean dist/, build/, and *.egg-info.
  3. Build the package using python -m build.
  4. Upload to PyPI using twine.

PyPI Configuration

To publish, ensure your .env file contains your PyPI API token:

# .env
PYPI_TOKEN=pypi-AgEIcHlwaS5vcmc...

The scripts automatically map this to TWINE_PASSWORD and set TWINE_USERNAME to __token__.

Database Schema

The library uses SQLAlchemy to manage a usage_logs table. Ensure your database user has CREATE and INSERT permissions. Designed for TiDB but works with standard MySQL.

Metadata

Release files for keycycle 0.5.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 keycycle 0.5.1
File Size Uploaded
keycycle-0.5.1.tar.gz 68.6 kB Details

Built distribution (wheel)

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

Total release size: 123.0 kB

Release files / keycycle-0.5.1.tar.gz

Download URL keycycle-0.5.1.tar.gz
Size 68.6 kB
Tags Source
SHA-256 checksum
How to use checksums
b76cad34660e09cb33f246d27e34fa08060dbed1b42464baba7dda34a0395555
BLAKE2b-256 checksum
How to use checksums
23575e15427e568b6879225efa17541f2af2951405444b26b13cb8c7595ac60c
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.11.14

Release files / keycycle-0.5.1-py3-none-any.whl

Download URL keycycle-0.5.1-py3-none-any.whl
Size 54.4 kB
Tags Python 3
SHA-256 checksum
How to use checksums
cdc2fc565032262dca2c35807df4d7e8a45a2172a5adaa6d8fc906ef1338a92c
BLAKE2b-256 checksum
How to use checksums
7b65df6c6756c33466801b1aa17be16cc7f2b2f8cf918d099037524f10a3deff
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.11.14

Release history Release notifications | RSS feed

0.5.4

2 release files

0.5.3

2 release files

0.5.2

2 release files

This release

0.5.1 This release

2 release files

0.5.0

2 release files

0.4.0

2 release files

0.3.2

2 release files

0.3.1

2 release files

0.3.0

2 release files

0.2.4

2 release files

0.2.3

2 release files

0.2.2

2 release files

0.2.1

2 release files

0.2.0

2 release files

0.1.14

2 release files

0.1.13

2 release files

0.1.12

2 release files

0.1.11

2 release files

0.1.10

2 release files

0.1.9

2 release files

0.1.8

2 release files

0.1.7

2 release files

0.1.6

2 release files

0.1.5

2 release files

0.1.4

2 release files

0.1.3

2 release files

0.1.2

2 release files

0.1.1

2 release files

0.1.0

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