Skip to main content

Multi-provider LLM gateway — one interface, every provider

Project description

llmshim

One interface, every LLM provider. The proxy server starts automatically — no setup needed.

Install

pip install llmshim

Configure

import llmshim

# Set API keys (writes to ~/.llmshim/config.toml — only needed once)
llmshim.configure(
    anthropic="sk-ant-...",
    openai="sk-...",
    gemini="AIza...",
    xai="xai-...",
)

Or from the CLI: llmshim configure

Chat

import llmshim

resp = llmshim.chat("claude-sonnet-4-6", "What is Rust?")
print(resp["message"]["content"])

With options (all map to the API's provider-agnostic config):

resp = llmshim.chat(
    "openai/gpt-5.5",
    "Explain quicksort",
    max_tokens=500,
    temperature=0.7,
    top_p=0.9,
    top_k=40,
    stop=["\n\n"],
    reasoning_effort="high",
)

With message history:

resp = llmshim.chat("claude-sonnet-4-6", [
    {"role": "system", "content": "You are a pirate."},
    {"role": "user", "content": "Hello!"},
], max_tokens=500)

Streaming

for event in llmshim.stream("claude-sonnet-4-6", "Write a poem"):
    if event["type"] == "content":
        print(event["text"], end="", flush=True)
    elif event["type"] == "reasoning":
        pass  # thinking tokens
    elif event["type"] == "usage":
        print(f"\n[↑{event['input_tokens']}{event['output_tokens']}]")

Multi-Model Conversations

Switch models mid-conversation. History carries over.

messages = [{"role": "user", "content": "What is a closure?"}]

r1 = llmshim.chat("claude-sonnet-4-6", messages, max_tokens=500)
print(f"Claude: {r1['message']['content']}")

messages.append({"role": "assistant", "content": r1["message"]["content"]})
messages.append({"role": "user", "content": "Now explain differently."})

r2 = llmshim.chat("gpt-5.5", messages, max_tokens=500)
print(f"GPT: {r2['message']['content']}")

Reasoning / Thinking

resp = llmshim.chat(
    "claude-sonnet-4-6",
    "Solve: x^2 - 5x + 6 = 0",
    max_tokens=4000,
    reasoning_effort="high",
)
print(resp["reasoning"])        # thinking content
print(resp["message"]["content"])  # answer

Tool Use / Function Calling

tools = [{
    "type": "function",
    "function": {
        "name": "get_weather",
        "description": "Get current weather",
        "parameters": {
            "type": "object",
            "properties": {"city": {"type": "string"}},
            "required": ["city"],
        },
    },
}]

resp = llmshim.chat("claude-sonnet-4-6", "Weather in Tokyo?", max_tokens=500, tools=tools)
for tc in resp["message"].get("tool_calls", []):
    print(f"{tc['function']['name']}({tc['function']['arguments']})")

Tools are accepted in OpenAI Chat Completions format and auto-translated to each provider's native format.

Fallback Chains

resp = llmshim.chat(
    "anthropic/claude-sonnet-4-6",
    "Hello",
    max_tokens=100,
    fallback=["openai/gpt-5.5", "gemini/gemini-3-flash-preview"],
)

Error Handling

Non-streaming errors (bad model, unknown provider, provider failures) raise LlmShimError, which carries the API's structured error fields:

try:
    llmshim.chat("unknown/model", "hi")
except llmshim.LlmShimError as e:
    print(e.status_code)  # 400
    print(e.code)         # "bad_request"
    print(e.message)      # human-readable message

Streaming errors that occur mid-stream instead arrive as an error event (event["type"] == "error"); an HTTP error before the stream starts still raises LlmShimError.

Types

Spec-faithful TypedDict definitions are available in llmshim.types (and the common ones are re-exported at the top level) for static type-checking:

from llmshim.types import ChatResponse, StreamEvent, Message, Config

resp: ChatResponse = llmshim.chat("claude-sonnet-4-6", "hi")

Available: ChatRequest, ChatResponse, Config, Message, ToolCall, Usage, ResponseMessage, ModelEntry, ModelsResponse, HealthResponse, ErrorResponse, and the StreamEvent union (ContentEvent, ReasoningEvent, ToolCallEvent, UsageEvent, DoneEvent, ErrorEvent).

Other

llmshim.models()   # list available models
llmshim.health()   # {"status": "ok", "providers": [...]}

How It Works

On first call, the package:

  1. Finds the llmshim binary (bundled, on PATH, or in repo)
  2. Starts the proxy on a random localhost port
  3. Routes your request through it
  4. Server stops automatically when Python exits

No Docker, no background services, no manual server management.

Development

The unit tests under tests/ are fully mocked — they run a local HTTP server returning canned JSON and SSE, so they need no API keys and make no real provider calls:

pip install httpx pytest
pytest tests/

test_e2e.py is a separate LIVE suite that spawns the real binary and makes billed provider calls; run it only when you deliberately want to hit real APIs.

Supported Models

Provider Models
OpenAI gpt-5.5, gpt-5.5-pro, gpt-5.4, gpt-5.4-pro, gpt-5.4-mini, gpt-5.4-nano
Anthropic claude-opus-4-8, claude-sonnet-5, claude-opus-4-7, claude-opus-4-6, claude-sonnet-4-6, claude-haiku-4-5-20251001
Gemini gemini-3.5-flash, gemini-3.1-pro-preview, gemini-3.1-flash-lite-preview, gemini-3-flash-preview
xAI grok-4.3, grok-4.20-multi-agent-beta-0309, grok-4.20-beta-0309-reasoning, grok-4.20-beta-0309-non-reasoning, grok-4-1-fast-reasoning, grok-4-1-fast-non-reasoning

Call llmshim.models() for the live list filtered to your configured providers.

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

llmshim-0.1.26.tar.gz (160.6 kB view details)

Uploaded Source

Built Distributions

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

llmshim-0.1.26-py3-none-win_amd64.whl (3.2 MB view details)

Uploaded Python 3Windows x86-64

llmshim-0.1.26-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (3.3 MB view details)

Uploaded Python 3manylinux: glibc 2.17+ x86-64

llmshim-0.1.26-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl (3.1 MB view details)

Uploaded Python 3manylinux: glibc 2.17+ ARM64

llmshim-0.1.26-py3-none-macosx_11_0_arm64.whl (3.1 MB view details)

Uploaded Python 3macOS 11.0+ ARM64

llmshim-0.1.26-py3-none-macosx_10_12_x86_64.whl (3.2 MB view details)

Uploaded Python 3macOS 10.12+ x86-64

File details

Details for the file llmshim-0.1.26.tar.gz.

File metadata

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

File hashes

Hashes for llmshim-0.1.26.tar.gz
Algorithm Hash digest
SHA256 c8ee5e30dd33a0b1d38be5e6f1312db43db3851fddae3668799026adcad44039
MD5 c23bcc2bffbbd51e80b1f1ca3ee480e1
BLAKE2b-256 a92994ab1bf99f5fa8511771c4f499ee73ecb18f2394cbd401baa6029906bbe9

See more details on using hashes here.

Provenance

The following attestation bundles were made for llmshim-0.1.26.tar.gz:

Publisher: release.yml on sanjay920/llmshim

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

File details

Details for the file llmshim-0.1.26-py3-none-win_amd64.whl.

File metadata

  • Download URL: llmshim-0.1.26-py3-none-win_amd64.whl
  • Upload date:
  • Size: 3.2 MB
  • Tags: Python 3, Windows x86-64
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for llmshim-0.1.26-py3-none-win_amd64.whl
Algorithm Hash digest
SHA256 95c43d6395f56ad1ee6858eb1eb0bff1d60fca46927705149c3a0f86c39eaea6
MD5 cee69ef65d00b56c40a346a0095c6785
BLAKE2b-256 1c6800c850915a814777adf4506802da140a1440e1e04f913ecef2d8e375a99a

See more details on using hashes here.

Provenance

The following attestation bundles were made for llmshim-0.1.26-py3-none-win_amd64.whl:

Publisher: release.yml on sanjay920/llmshim

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

File details

Details for the file llmshim-0.1.26-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.

File metadata

File hashes

Hashes for llmshim-0.1.26-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 4e31fcfbcb5a7ccf0c94d4aa3920e70cfac554e3e20029c72fb12de4cd2fa764
MD5 5c083c33d15dcdbd0ee68087ae54ca1d
BLAKE2b-256 601904fab5ed845c8c81fbdbaede7df690f2e5471af702e83d1bb27e2694f98d

See more details on using hashes here.

Provenance

The following attestation bundles were made for llmshim-0.1.26-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl:

Publisher: release.yml on sanjay920/llmshim

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

File details

Details for the file llmshim-0.1.26-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl.

File metadata

File hashes

Hashes for llmshim-0.1.26-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
Algorithm Hash digest
SHA256 1f60582c8b21da31bf273144bef7fb5e158867747f57708cad83e22f89065b40
MD5 fecb51952deb68aa58b72410db030651
BLAKE2b-256 2f5cbbb66bbfbdd09f893f226ea0b03fa6554639a4b267a3d5f160e24c5abcf1

See more details on using hashes here.

Provenance

The following attestation bundles were made for llmshim-0.1.26-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl:

Publisher: release.yml on sanjay920/llmshim

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

File details

Details for the file llmshim-0.1.26-py3-none-macosx_11_0_arm64.whl.

File metadata

File hashes

Hashes for llmshim-0.1.26-py3-none-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 e99848b4487eb6f7f169cddc5684b267266aa47c476c7d379c26aac97b0ebb09
MD5 62ef3b27a23cad144762d7eaa14cbedb
BLAKE2b-256 009dce97f44bccd94bf9fa38f5a03f2492f6a73b1539c81969dffa7ed7015170

See more details on using hashes here.

Provenance

The following attestation bundles were made for llmshim-0.1.26-py3-none-macosx_11_0_arm64.whl:

Publisher: release.yml on sanjay920/llmshim

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

File details

Details for the file llmshim-0.1.26-py3-none-macosx_10_12_x86_64.whl.

File metadata

File hashes

Hashes for llmshim-0.1.26-py3-none-macosx_10_12_x86_64.whl
Algorithm Hash digest
SHA256 ea1503a34263e01e27a1a85428d3d2ea0a650d5b216d7b14ea374ba89ad7385c
MD5 cd4498cc88993700a7339b71b6251d40
BLAKE2b-256 a41c4de9fce51e628f87f9284ce10e667d0e4db5cc36502c0ce77ce279bff8bd

See more details on using hashes here.

Provenance

The following attestation bundles were made for llmshim-0.1.26-py3-none-macosx_10_12_x86_64.whl:

Publisher: release.yml on sanjay920/llmshim

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