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.2.3.tar.gz (994.7 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.3-py3-none-win_amd64.whl (3.2 MB view details)

Uploaded Python 3Windows x86-64

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

Uploaded Python 3manylinux: glibc 2.17+ ARM64

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

Uploaded Python 3macOS 11.0+ ARM64

llmshim-0.2.3-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.3.tar.gz.

File metadata

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

File hashes

Hashes for llmshim-0.2.3.tar.gz
Algorithm Hash digest
SHA256 d4ac81b49ab4fb1fa6fc2e32cef2aa413827d69bf18626b829211a3a1e1513c3
MD5 2ffe84d3afcecb0005870a0e7c2b0525
BLAKE2b-256 3901e5ab8e21e7b4b205c43a518387d3a2cb57efedf50772e9f33bdacc13b92c

See more details on using hashes here.

Provenance

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

File metadata

  • Download URL: llmshim-0.2.3-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.2.3-py3-none-win_amd64.whl
Algorithm Hash digest
SHA256 65b2b2de8b15832b0662cfb37e1cc401b5d18c158c11660fc449d1735072826b
MD5 a5be675716ae0e3628991acb94216d4a
BLAKE2b-256 af11096bd49d438c87a474ff0bd782d03703ba3814a1b339e14108f7cff47410

See more details on using hashes here.

Provenance

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

File metadata

File hashes

Hashes for llmshim-0.2.3-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 a68d87d9561ddc21457fccc6c8d4c1a7a7d2c3a9355db4c9f22066a95f8deadc
MD5 36f829add3f1531b4b90309ae7549937
BLAKE2b-256 8ac730e4ea56798986fae3014fd6344863b48c18f8e64efe26706862550a00e2

See more details on using hashes here.

Provenance

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

File metadata

File hashes

Hashes for llmshim-0.2.3-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
Algorithm Hash digest
SHA256 f6ced9a99cd5faf8aa18a079dbb6b449101e3ef27207ae9813595dcb4871e7c8
MD5 246f9f0c1a205b469bc11344e9949559
BLAKE2b-256 3fa35e828c254bf2751b52a437c80d2e2f5472e5d144cb7db640ec9aa2dda656

See more details on using hashes here.

Provenance

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

File metadata

File hashes

Hashes for llmshim-0.2.3-py3-none-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 4c8a7ee7d6ac6a154b1c85e95c5af9d44e6469214b2b063acf834b5fe86e1450
MD5 704766fe33da93f6611a98d170daea2b
BLAKE2b-256 26c1d7f7cde7842032425c2b792eafed1ea4ad5d431ed2625949c394f3415fd7

See more details on using hashes here.

Provenance

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

File metadata

File hashes

Hashes for llmshim-0.2.3-py3-none-macosx_10_12_x86_64.whl
Algorithm Hash digest
SHA256 832cc336f91ee6f157c40de2cac6d48368e675620982a20c6379b2abd8f33aee
MD5 2b41ea4b00f51a387fc0b9d38e2d6cd7
BLAKE2b-256 23cea85ec2d45a879a3ee8d4405aeb5d8e8ab419c971656bd618e45441f43b48

See more details on using hashes here.

Provenance

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