Skip to main content

LLMSwitch

Free-tier AI provider router for developers. Write AI code once; LLMSwitch handles provider fallback across Groq, OpenRouter, NVIDIA, and more.

Install

pip install ai-switch

The distribution is named ai-switch; the import stays llmswitch.

Configure

Set an API key for any provider you want LLMSwitch to use — it only tries providers with a key present:

export GROQ_API_KEY="..."
export CEREBRAS_API_KEY="..."
export GEMINI_API_KEY="..."
export OPENROUTER_API_KEY="..."
export NVIDIA_API_KEY="..."
export MISTRAL_API_KEY="..."
export HF_TOKEN="..."
Provider Env var Order
Groq GROQ_API_KEY 1
Cerebras CEREBRAS_API_KEY 2
Gemini GEMINI_API_KEY 3
OpenRouter OPENROUTER_API_KEY 4
NVIDIA NVIDIA_API_KEY 5
Mistral MISTRAL_API_KEY 6
Hugging Face HF_TOKEN 7
Ollama (local) OLLAMA_HOST 8 — last resort

Ollama as a local last resort

Ollama needs no API key and never rate-limits, so it makes a good final fallback when every cloud free tier is spent. It is opt-in — set OLLAMA_HOST to enable it, so users without a local server don't pay for a failed attempt on every request:

export OLLAMA_HOST="http://localhost:11434/v1"

Usage

from llmswitch import AIClient

client = AIClient()
response = client.chat("Write a Python web scraper")
print(response)

Providers are tried in order (Groq, OpenRouter, NVIDIA by default). If one is rate-limited, unreachable, or errors, LLMSwitch automatically falls back to the next.

Model names

model accepts either a friendly alias ("fast-model", "smart-model" — see llmswitch/registry.py) that's resolved per-provider, or a raw provider-specific model name passed straight through:

client.chat("hello", model="fast-model")
client.chat("hello", model="llama-3.1-8b-instant")  # Groq-specific name

Health tracking

LLMSwitch remembers which providers just failed, so a rate-limited provider isn't retried on every call — it's rested and moved to the back of the queue:

client.chat("hi")      # groq is rate-limited -> falls back to openrouter
client.chat("hi")      # groq skipped entirely; openrouter served directly

Cooldowns respect the provider's own Retry-After header when present, and otherwise back off exponentially (60s, 120s, 240s… capped at 15 min for rate limits; shorter for transient outages). A success clears the streak.

If every provider is resting, LLMSwitch still tries them — closest-to-recovery first — rather than failing without an attempt.

Inspect current state at any time:

client.status()
# {'groq': {'available': False, 'cooldown_remaining': 57.0, ...},
#  'openrouter': {'available': True, 'total_successes': 2, ...}}

Streaming

from llmswitch import AIClient, StreamInterrupted

with AIClient() as client:
    try:
        for token in client.stream("Write a haiku about failover"):
            print(token, end="", flush=True)
    except StreamInterrupted as exc:
        print(f"\n[broke on {exc.provider}, kept: {exc.partial!r}]")

Fallback is transparent only up to the first token. Once tokens have been handed to you they can't be un-yielded, so a later failure raises StreamInterrupted carrying the partial text rather than silently restarting the answer on another provider mid-sentence.

Async

import asyncio
from llmswitch import AsyncAIClient

async def main():
    async with AsyncAIClient() as client:
        print(await client.chat("hello"))
        async for token in client.stream("count to five"):
            print(token, end="")

asyncio.run(main())

AsyncAIClient shares the sync client's routing core, so fallback, cooldowns, and retry behave identically — only the transport differs.

Connections and cleanup

Clients pool connections per provider, so closing them matters. Use a context manager, or call close() / await aclose() yourself:

with AIClient() as client:      # closes on exit
    client.chat("hi")

Retries

A timeout usually means one unlucky request rather than a dead provider, so LLMSwitch retries the same provider once before failing over. A 429 is never retried — the provider explicitly said stop.

Choosing providers explicitly

from llmswitch import AIClient
from llmswitch.providers import GroqProvider, NVIDIAProvider

client = AIClient(providers=[GroqProvider(), NVIDIAProvider()])

See examples/ for more.

Tests

pip install -e ".[dev]"
pytest

Changelog

See CHANGELOG.md for what changed between releases.

Status

v0.4.0 on PyPI — eight providers, health tracking, streaming, async, 150 tests. Still 0.x: the API may shift before 1.0, and five of the eight adapters have verified endpoints but have not completed a request with a real key. See roadmap.md for the plan and todo.md for current progress.

Metadata

Release files for ai-switch 0.4.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for ai-switch 0.4.0
File Size Uploaded
ai_switch-0.4.0.tar.gz 23.6 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for ai-switch 0.4.0
File Interpreter ABI Platform
ai_switch-0.4.0-py3-none-any.whl Python 3 none any Details

Total release size: 44.9 kB

Release files / ai_switch-0.4.0.tar.gz

Download URL ai_switch-0.4.0.tar.gz
Size 23.6 kB
Tags Source
SHA-256 checksum
How to use checksums
9436af21aaf744bbf646c3e64c97b04c7cb370c0c919a11fbf4a4405820b6220
BLAKE2b-256 checksum
How to use checksums
2469126d7a416bc7fa34efa60c6b5ab0ebebfcd44ded549bd3d05a5958a20e34
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via ai-switch-uploader/1.0

Release files / ai_switch-0.4.0-py3-none-any.whl

Download URL ai_switch-0.4.0-py3-none-any.whl
Size 21.3 kB
Tags Python 3
SHA-256 checksum
How to use checksums
005b98d05cf7c8472634432ad74ad7948bc27161d085690fad91383698bf0a55
BLAKE2b-256 checksum
How to use checksums
5802e91920458469ddc244e3707242c5c62eb6d8f408802de427a1bbb0613dff
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via ai-switch-uploader/1.0

Release history Release notifications | RSS feed

This release

0.4.0 This release

2 release files

0.3.0

2 release files

0.2.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