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-5, 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.3.0.tar.gz (1.0 MB view details)

Uploaded Source

Built Distributions

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

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

Uploaded Python 3Windows x86-64

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

Uploaded Python 3manylinux: glibc 2.17+ ARM64

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

Uploaded Python 3macOS 11.0+ ARM64

llmshim-0.3.0-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.3.0.tar.gz.

File metadata

  • Download URL: llmshim-0.3.0.tar.gz
  • Upload date:
  • Size: 1.0 MB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.14

File hashes

Hashes for llmshim-0.3.0.tar.gz
Algorithm Hash digest
SHA256 a52a1e6ad170c46f661ace6802f49e8c2c8c132536c2eb2546a17befd5ad4f96
MD5 23bb7d78a54953f7e065d3c142db1002
BLAKE2b-256 4ad7f9ff0e3104c06f162d2c2902ec9e8204ad36870c9694a7bad14870ad4f2e

See more details on using hashes here.

Provenance

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

File metadata

  • Download URL: llmshim-0.3.0-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.14

File hashes

Hashes for llmshim-0.3.0-py3-none-win_amd64.whl
Algorithm Hash digest
SHA256 29986edd8ef1e12a803e18c6986ad7b58cf31d814421b5e191b48cce276162a8
MD5 b637757fdde4cb0e91c4edc8eb6d4fd2
BLAKE2b-256 b5e1a18e05fd5688b42a312035eb265e9014c4647a7344e2fb8c34b4cd7164b3

See more details on using hashes here.

Provenance

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

File metadata

File hashes

Hashes for llmshim-0.3.0-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 b8ce041ba0bb6493a708837fc322dadc9f01d7c1e0528bf067a121c5cbc158dd
MD5 b4d882aad45bf1a28b3f909d8f1e5dcc
BLAKE2b-256 99352c13154b641d983671ace3e555befb6622f13c26a1351731305548eddec5

See more details on using hashes here.

Provenance

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

File metadata

File hashes

Hashes for llmshim-0.3.0-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
Algorithm Hash digest
SHA256 9bda70f1aa1edd2bd050c75775af8a34b8c03c79593bbb96a604985ce8c2e151
MD5 c5fdb948885e67ede3b60051907d8819
BLAKE2b-256 533327468a0248a50055d5d172960bcc6c20c91d21a6f6d7f1076819b2b6db2b

See more details on using hashes here.

Provenance

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

File metadata

File hashes

Hashes for llmshim-0.3.0-py3-none-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 6e380da902dce52ebf8bd76b980c7d8a4f330337e21673290fcadc3ed102dbbe
MD5 73232f70b3796f35a547138d282be152
BLAKE2b-256 07ed41bab87a182c2335420e7d35de0ccee58c9a854564b1b460d732c4c9cdb6

See more details on using hashes here.

Provenance

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

File metadata

File hashes

Hashes for llmshim-0.3.0-py3-none-macosx_10_12_x86_64.whl
Algorithm Hash digest
SHA256 b72b79a2600d416d414d90cd77a448bb78ec96ce4fe80b7f44100d81cca72d1d
MD5 861d8815a31b4edc4867a8a6c77a1fe0
BLAKE2b-256 d6df99f80300b8252b787518fb33b9b8cd6e380d5e53d8dc977754e96a950b1e

See more details on using hashes here.

Provenance

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