Skip to main content

Unified LLM client with key rotation, health-aware failover, and multi-provider orchestration.

Project description

llm-rotate

llm-rotate is a Python library for resilient LLM calls across providers. It provides API key rotation, health-aware selection, retry/failover, and a unified chat interface.

What it does

  • Unified API for OpenAI, Anthropic, Google AI Studio, Vertex AI, and OpenRouter
  • Automatic key rotation on rate-limit/auth/transient failures
  • Provider fallback chains
  • Streaming and sync/async chat support
  • Structured per-call usage logging

Quickstart

llm-rotate ships a built-in provider catalog covering all five supported backends. Configure it programmatically with a plain Python dict before your first lm call — no env var registry blob required.

from llm_rotate import configure, lm

configure(
    registry={
        "keys": [
            {
                "key_id": "openai-1",
                "provider": "openai",
                "secret_ref": "env://OPENAI_API_KEY",
                "models": ["gpt-4o-mini"],
            },
            {
                "key_id": "gemini-1",
                "provider": "google_ai_studio",
                "secret_ref": "env://GOOGLE_API_KEY",
                "models": ["gemini-2.0-flash"],
            },
        ]
    },
    use_keys=["openai-1", "gemini-1"],
)

response = await lm.chat("gpt-4o-mini", [{"role": "user", "content": "Hello"}])
print(response.content)

configure() must be called before the first use of lm. Using lm without prior configure() raises ConfigurationError.

Required fields per key entry

Field Description
key_id Unique name for this credential (used in logs and use_keys=[...])
provider One of: openai, anthropic, google_ai_studio, google_vertex, openrouter
secret_ref env://VAR_NAME — resolved at runtime, never stored
models List of model IDs this key may serve (used for routing and inference)

Overriding built-in provider settings (optional)

If you need custom cooldown/quarantine values for a specific provider, add a providers key containing only the entries you want to override — the rest keep their built-in defaults:

configure(
    registry={
        "providers": {
            "openai": {
                "provider_type": "direct",
                "display_name": "OpenAI",
                "default_cooldown_seconds": 10,
            }
        },
        "keys": [...],
    },
    use_keys=[...],
)

Provider fallback chains

When all keys for a model's native provider are exhausted (rate-limited, quarantined, or auth-failed), llm-rotate can transparently re-try the same request against another provider. Configure named chains via fallback_chains on configure():

configure(
    registry={
        "keys": [
            {"key_id": "anthropic-1", "provider": "anthropic",
             "secret_ref": "env://ANTHROPIC_API_KEY",
             "models": ["claude-haiku-4-5-20251001"]},
            {"key_id": "openrouter-1", "provider": "openrouter",
             "secret_ref": "env://OPENROUTER_API_KEY",
             "models": ["anthropic/claude-haiku-4.5"]},
        ]
    },
    use_keys=["anthropic-1", "openrouter-1"],
    fallback_chains={
        "anthropic": [{"provider": "openrouter"}],
        "openai":    [{"provider": "openrouter"}],
    },
)

# No explicit `provider=` → provider is inferred from the model, then the
# chain registered under that provider name is walked in order on exhaustion.
response = await lm.chat(
    "claude-haiku-4-5-20251001",
    [{"role": "user", "content": "Hello"}],
)

Resolution rules:

  • Explicit provider= argument → only that provider's keys are tried; the chain is not consulted.
  • No provider= → provider is inferred from the model name; on exhaustion the chain keyed by that provider name is walked in order.
  • No provider= and no chain configured for the inferred provider → ConfigurationError.
  • Each entry is {"provider": "<name>", "upstream": "<optional>"}; upstream is used by aggregators like OpenRouter to pin a backend.
  • Model-ID compatibility on the fallback provider is the caller's responsibility (e.g. OpenRouter uses anthropic/claude-haiku-4.5, not the native Anthropic model ID).

Merge rules

  1. Built-in providers (openai, anthropic, google_ai_studio, google_vertex, openrouter) are always the base layer.
  2. Any provider entry in the registry dict's "providers" block replaces the corresponding built-in entry by name; providers not mentioned keep their built-in values.
  3. "keys" always come from the caller-supplied dict — the package ships no keys, credentials, or secret_ref values.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

llm_rotate-0.3.3.tar.gz (31.1 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

llm_rotate-0.3.3-py3-none-any.whl (46.5 kB view details)

Uploaded Python 3

File details

Details for the file llm_rotate-0.3.3.tar.gz.

File metadata

  • Download URL: llm_rotate-0.3.3.tar.gz
  • Upload date:
  • Size: 31.1 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for llm_rotate-0.3.3.tar.gz
Algorithm Hash digest
SHA256 aa8ef3163389c9fe23dcad2049d42cfe416c7a0d075449380c32155af4bfe3d2
MD5 1e9427b1ed82176f6328230058934d1c
BLAKE2b-256 402a1f9a86116de2b1dc3956e180e574d76a5ebbdad0379164531af036035a86

See more details on using hashes here.

Provenance

The following attestation bundles were made for llm_rotate-0.3.3.tar.gz:

Publisher: publish.yml on Research-Commons/llm-rotate

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file llm_rotate-0.3.3-py3-none-any.whl.

File metadata

  • Download URL: llm_rotate-0.3.3-py3-none-any.whl
  • Upload date:
  • Size: 46.5 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for llm_rotate-0.3.3-py3-none-any.whl
Algorithm Hash digest
SHA256 b5e0f3fb67ccfaa6e7f7f1369e57c104db2cd16302fd0e77007e877d8a5f236c
MD5 40846cac82857299effa2f4237597d9e
BLAKE2b-256 3f2b872bba6511039cb695f15e65bfe8c8474ed3a9923af7c9fe15058703b4e0

See more details on using hashes here.

Provenance

The following attestation bundles were made for llm_rotate-0.3.3-py3-none-any.whl:

Publisher: publish.yml on Research-Commons/llm-rotate

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page