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-flash-preview
xAI grok-4.5, grok-4.3, grok-4.20-multi-agent-beta-0309, grok-4.20-beta-0309-reasoning, grok-4.20-beta-0309-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.2.2.tar.gz (984.4 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.2.2-py3-none-win_amd64.whl (3.2 MB view details)

Uploaded Python 3Windows x86-64

llmshim-0.2.2-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.2.2-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl (3.1 MB view details)

Uploaded Python 3manylinux: glibc 2.17+ ARM64

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

Uploaded Python 3macOS 11.0+ ARM64

llmshim-0.2.2-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.2.2.tar.gz.

File metadata

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

File hashes

Hashes for llmshim-0.2.2.tar.gz
Algorithm Hash digest
SHA256 770410f55466cbc1d8cacc7265c07040db986c62f2cf0897322ee7535de6c9e0
MD5 490f40fba6c4085e522b3688f4598a10
BLAKE2b-256 a4d855c951530e3e9c1e485e434038d73eff1c4ecca4ec3c2ab1cd29f534b253

See more details on using hashes here.

Provenance

The following attestation bundles were made for llmshim-0.2.2.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.2.2-py3-none-win_amd64.whl.

File metadata

  • Download URL: llmshim-0.2.2-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.2.2-py3-none-win_amd64.whl
Algorithm Hash digest
SHA256 42cdf35826d317473a80c31fd8156bca7c6d89eab0241ab1b498fba5e3f26faf
MD5 0220c12da7ccac9c1dc0178d8539c20b
BLAKE2b-256 63d175356f0bfaf788269000fb5df35a0eec5d3c6637f9f7892bb41c2fe7d215

See more details on using hashes here.

Provenance

The following attestation bundles were made for llmshim-0.2.2-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.2.2-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.

File metadata

File hashes

Hashes for llmshim-0.2.2-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 df8abe2f156ecec5cd62a1c08fc9a0941f7887a78564cc225efad280445488d4
MD5 c58b08201b9def808f670cd50683f3bc
BLAKE2b-256 f81ecb77171bb2c18f226c0a697d3b0b26229bdf5f536bde1cb153f5490fb6f4

See more details on using hashes here.

Provenance

The following attestation bundles were made for llmshim-0.2.2-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.2.2-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl.

File metadata

File hashes

Hashes for llmshim-0.2.2-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
Algorithm Hash digest
SHA256 fb886fd8a79dd977e4c969596333ed7182683d0548a9ddb1913e9b53c7151436
MD5 04eb0ca6d6dd54b71535620bb462a6d1
BLAKE2b-256 d107ee1e9ce608ab83cae44e387b2d865ee25e954eeae271a7f6f05e3f8ab59a

See more details on using hashes here.

Provenance

The following attestation bundles were made for llmshim-0.2.2-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.2.2-py3-none-macosx_11_0_arm64.whl.

File metadata

File hashes

Hashes for llmshim-0.2.2-py3-none-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 43369b4220cd9afcd2cb5f051d189c14be8fd1c2ec757c254a9c207a667b1748
MD5 f353d32250f0da5cd72f5464cde97904
BLAKE2b-256 e7dc43209efccced53de5a9f5831cb67b233d012065474fd751033152912b684

See more details on using hashes here.

Provenance

The following attestation bundles were made for llmshim-0.2.2-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.2.2-py3-none-macosx_10_12_x86_64.whl.

File metadata

File hashes

Hashes for llmshim-0.2.2-py3-none-macosx_10_12_x86_64.whl
Algorithm Hash digest
SHA256 b64fe50123c623fa206a2a96333224e505b00f9349282d52dd60fa53aed25b84
MD5 c90a0d162dc0ab691028f024e05e3691
BLAKE2b-256 2dbf41cf379fa8925235619e9418fb2edb8f4289fb79c8de801be3cd2f2d1591

See more details on using hashes here.

Provenance

The following attestation bundles were made for llmshim-0.2.2-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