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.0.tar.gz (20.3 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.0-py3-none-any.whl (16.6 kB view details)

Uploaded Python 3

File details

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

File metadata

  • Download URL: llmwire-0.1.0.tar.gz
  • Upload date:
  • Size: 20.3 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.0.tar.gz
Algorithm Hash digest
SHA256 86895f31ce6d0ab1687f068ea8eca65639ed8d169244ec76a8d431f3ec7a27a6
MD5 0b334b9ce34c021d8e4b81c92755212b
BLAKE2b-256 178e284cc2e70e60d5a74c4995a5e64c8df553172734ba4a0e41fbe08a7e7b1e

See more details on using hashes here.

File details

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

File metadata

  • Download URL: llmwire-0.1.0-py3-none-any.whl
  • Upload date:
  • Size: 16.6 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.0-py3-none-any.whl
Algorithm Hash digest
SHA256 70bc88679e5a6e663f6fd3d0c4d4c1fc2dc8a35860a382a681769f47cac61ecd
MD5 64e80dc2663d755287033aba9e762aeb
BLAKE2b-256 a89e50e3e88d4ec8d19e41522f956d80eca78429500a112d83026ab4dfc6d7d0

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