Skip to main content

Lightweight multi-provider LLM client for Python

Project description

LLMWire

CI PyPI Python License: MIT

Lightweight multi-provider LLM client for Python. A single async interface to OpenAI, Anthropic, and Ollama — with automatic fallback, exponential-backoff retry, streaming, and structured Pydantic output. No provider SDK dependencies; all requests go over plain httpx.

Features

  • Unified API — one LLMClient for all supported providers
  • Async-first — built entirely on asyncio and httpx
  • Automatic fallback — on provider failure, tries the next provider in the list
  • Exponential backoff — configurable retry with full jitter
  • Streaming — token-by-token via client.stream(), async generator interface
  • Structured output — pass any Pydantic BaseModel as response_model
  • No provider SDKs — runtime deps are only httpx, pydantic, pydantic-settings, pyyaml
  • Environment variable config — all settings readable from LLMKIT_* env vars

Quick Start

pip install llmwire

Chat

import asyncio
from llmwire import LLMClient, LLMConfig, ProviderConfig

config = LLMConfig(
    providers=[
        ProviderConfig(name="openai", api_key="sk-...", model="gpt-4o"),
        ProviderConfig(name="anthropic", api_key="sk-ant-...", model="claude-3-5-sonnet-20241022"),
    ]
)

async def main():
    async with LLMClient(config) as client:
        response = await client.chat("What is the capital of France?")
        print(response.content)
        # Provider: openai | Model: gpt-4o | Tokens: 42

asyncio.run(main())

Streaming

async def main():
    async with LLMClient(config) as client:
        async for chunk in client.stream("Write a haiku about async programming."):
            print(chunk.content, end="", flush=True)
        print()

Structured Output

from pydantic import BaseModel

class Sentiment(BaseModel):
    label: str        # "positive", "negative", or "neutral"
    confidence: float

async def main():
    async with LLMClient(config) as client:
        result: Sentiment = await client.chat(
            "Classify: 'I love this library!'",
            response_model=Sentiment,
        )
        print(result.label, result.confidence)  # positive  0.97

Configuration

Direct

from llmwire import LLMConfig, ProviderConfig

config = LLMConfig(
    providers=[
        ProviderConfig(name="openai", api_key="sk-...", model="gpt-4o"),
        ProviderConfig(name="ollama", model="llama3.2"),          # no key needed
    ],
    fallback=True,    # try next provider on failure (default: True)
    max_retries=3,    # per-provider retry attempts (default: 3)
    timeout=30.0,     # request timeout in seconds (default: 30.0)
)

Environment Variables

export LLMKIT_PROVIDERS__0__NAME=openai
export LLMKIT_PROVIDERS__0__API_KEY=sk-...
export LLMKIT_PROVIDERS__0__MODEL=gpt-4o

export LLMKIT_PROVIDERS__1__NAME=anthropic
export LLMKIT_PROVIDERS__1__API_KEY=sk-ant-...
export LLMKIT_PROVIDERS__1__MODEL=claude-3-5-sonnet-20241022

export LLMKIT_FALLBACK=true
export LLMKIT_MAX_RETRIES=3
config = LLMConfig()  # reads from environment

Provider Support

Provider Chat Streaming Auth Default endpoint
OpenAI yes yes API key https://api.openai.com/v1
Anthropic yes yes API key https://api.anthropic.com/v1
Ollama yes yes none http://localhost:11434

The base_url field on ProviderConfig lets you point any provider at a compatible endpoint (e.g. Azure OpenAI, local OpenAI-compatible servers).

Further Reading

License

MIT. See LICENSE.

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

llmwire-0.1.1.tar.gz (20.5 kB view details)

Uploaded Source

Built Distribution

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

llmwire-0.1.1-py3-none-any.whl (16.7 kB view details)

Uploaded Python 3

File details

Details for the file llmwire-0.1.1.tar.gz.

File metadata

  • Download URL: llmwire-0.1.1.tar.gz
  • Upload date:
  • Size: 20.5 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for llmwire-0.1.1.tar.gz
Algorithm Hash digest
SHA256 eed67115fa124a3e24919acad10cbdb0895b318e9fd37746aa1a240b4e3cb252
MD5 d1219ed0281938e2442f9e61f5196721
BLAKE2b-256 b65fdfb452e7b6dfa13a1896526d27c84c9bbee3e1860ce574299ce92f53a5ab

See more details on using hashes here.

File details

Details for the file llmwire-0.1.1-py3-none-any.whl.

File metadata

  • Download URL: llmwire-0.1.1-py3-none-any.whl
  • Upload date:
  • Size: 16.7 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for llmwire-0.1.1-py3-none-any.whl
Algorithm Hash digest
SHA256 87d57506fc1329ec6df35cc3719e039285d946cc88bb6cbd7940eb55f8049e78
MD5 d1da12e8d4fd0660740719b716e90b18
BLAKE2b-256 0c53ac7a5ccaf7fad3937416608d39de8c1d4e6b9b729c7e0a052ba4ac0d4938

See more details on using hashes here.

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