LLM Wrapper
A unified Python library for interacting with multiple Large Language Model APIs including OpenAI, Google Gemini, and Anthropic. This wrapper provides a consistent interface across different LLM providers, simplifying integration and allowing easy switching between models.
Features
- Single interface for multiple LLM providers (OpenAI, Google Gemini, Anthropic)
- Simple configuration with API keys or environment variables
- Standardized request and response formats across providers
- Comprehensive error handling with detailed contextual messages
- Automatic rate limit handling with exponential backoff
- Full streaming support for real-time responses
- Proper system message handling for all providers
- Input validation and type checking for robust operation
- Detailed usage metrics for token consumption
- Consistent default parameters across all providers
- Consistent parameter handling across providers
- Built-in error handling with retries for rate limiting
- Streaming support for efficient token generation
- Simplified message handling for both completions and chat
Installation
pip install awesome-llm-wrapper
Quick Start
from llm_wrapper import LLMClient
# Initialize with your API keys
client = LLMClient(
openai_api_key="your-openai-key",
gemini_api_key="your-gemini-key",
anthropic_api_key="your-anthropic-key"
)
# Or load from environment variables
client = LLMClient.from_env()
# Make a simple completion request
response = client.complete(
provider="openai", # or "gemini" or "anthropic"
prompt="Tell me a joke about programming",
model="gpt-4o-mini", # optional: specify a model (defaults to provider's DEFAULT_MODEL if not specified)
max_tokens=100
)
# Access the generated text
print(response.text)
# Access additional information
print(f"Model used: {response.model}")
print(f"Provider: {response.provider}")
print(f"Token usage: {response.usage}")
Advanced Usage
Chat Completions
# Chat completion with conversation history
response = client.chat(
provider="anthropic",
messages=[
{"role": "system", "content": "You are a helpful assistant."},
{"role": "user", "content": "What is the capital of France?"},
{"role": "assistant", "content": "The capital of France is Paris."},
{"role": "user", "content": "What is its population?"}
],
model="claude-3-5-sonnet", # optional: specify a model (defaults to provider's DEFAULT_MODEL if not specified)
temperature=0.7,
max_tokens=150
)
print(response.text)
Streaming Responses
# Streaming response for real-time output
for chunk in client.stream_chat(
provider="openai",
messages=[
{"role": "user", "content": "Write a poem about AI"}
],
model="gpt-4o-mini", # optional: specify a model (defaults to provider's DEFAULT_MODEL if not specified)
temperature=0.9
):
print(chunk.text, end="")
Using Message Objects
from llm_wrapper import LLMClient, Message
# Using Message objects instead of dictionaries
response = client.chat(
provider="gemini",
messages=[
Message(role="system", content="You are a helpful assistant."),
Message(role="user", content="Explain quantum computing in simple terms.")
],
model="gemini-2.0-flash" # optional: specify a model
)
System Message Handling
Each provider handles system messages differently, but LLM Wrapper normalizes this for you:
# System messages are properly formatted for each provider
response = client.chat(
provider="anthropic", # Works the same for OpenAI and Gemini
messages=[
{"role": "system", "content": "You are a helpful assistant who always responds in rhyme."},
{"role": "user", "content": "Tell me about machine learning."}
]
)
Behind the scenes:
- OpenAI: System messages are passed directly as "system" role messages
- Anthropic: System messages are formatted with
<system>...</system>tags - Gemini: System messages are prepended to the first user message
Model Selection
Each provider has a default model, but you can specify a different model using the model parameter:
# Using specific models for each provider
# OpenAI (default: gpt-4o-mini)
response = client.complete(
provider="openai",
prompt="Generate a story",
model="gpt-4", # override the default model
max_tokens=100
)
# Gemini (default: gemini-2.0-flash)
response = client.complete(
provider="gemini",
prompt="Generate a story",
model="gemini-2.0-pro",
max_tokens=100
)
# Anthropic (default: claude-3-5-sonnet)
response = client.complete(
provider="anthropic",
prompt="Generate a story",
model="claude-3-opus",
max_tokens=100
)
Error Handling and Rate Limiting
The library provides comprehensive error handling, including automatic retries for rate limit errors:
from llm_wrapper import LLMClient
try:
response = client.complete(
provider="openai",
prompt="Generate a story",
max_tokens=100
)
print(response.text)
except ValueError as e:
print(f"Configuration error: {e}") # Invalid API keys, missing parameters, etc.
except requests.HTTPError as e:
print(f"HTTP error: {e}") # API errors with detailed context
except Exception as e:
print(f"Other error: {e}") # Any other errors that might occur
Rate limit handling is built-in:
- Automatic retries with exponential backoff
- Respects the
Retry-Afterheader when provided by the API - Detailed error messages if all retries fail
Configuration
Environment Variables
You can configure the library using environment variables:
OPENAI_API_KEY=your-openai-key
GEMINI_API_KEY=your-gemini-key
ANTHROPIC_API_KEY=your-anthropic-key
If no valid API keys are found, the library will raise a clear error message.
Available Models
Each provider has a default model that will be used if no model is specified:
| Provider | Default Model | Other Available Models |
|---|---|---|
| OpenAI | gpt-4o-mini | gpt-4, gpt-4-turbo, gpt-3.5-turbo, etc. |
| Gemini | gemini-2.0-flash | gemini-2.0-pro, gemini-1.5-pro, etc. |
| Anthropic | claude-3-5-sonnet | claude-3-opus, claude-3-haiku, etc. |
You can specify any model supported by the provider's API using the model parameter.
Consistent Default Parameters
All providers use consistent default parameters:
max_tokens: 1000 (for all providers)- Other parameters are passed directly to the underlying API
Response Object
The Response object provides access to:
text: The generated text contentprovider: The provider used (OpenAI, Gemini, or Anthropic)model: The specific model usedraw_response: The full raw response from the providerusage: Token usage statisticsfinish_reason: The reason why the generation stopped
Parameter Handling
The library intelligently handles parameter conversion between different providers:
Common Parameters (automatically converted)
| Parameter | OpenAI | Gemini | Anthropic |
|---|---|---|---|
max_tokens |
max_tokens |
maxOutputTokens |
max_tokens |
temperature |
temperature |
temperature |
temperature |
top_p |
top_p |
topP |
top_p |
top_k |
N/A | topK |
N/A |
You can use the snake_case (Python style) parameter names consistently across all providers, and the library will automatically convert them to the appropriate format for each API:
# This works for all providers
response = client.complete(
provider="gemini", # or "openai" or "anthropic"
prompt="Tell me a joke",
max_tokens=100,
temperature=0.7,
top_p=0.9,
top_k=40 # only used by Gemini, ignored by others
)
Provider-Specific Parameters
You can also pass provider-specific parameters directly:
# OpenAI-specific
response = client.complete(
provider="openai",
prompt="Tell me a joke",
frequency_penalty=0.5, # OpenAI-specific
presence_penalty=0.2 # OpenAI-specific
)
# Gemini-specific
response = client.complete(
provider="gemini",
prompt="Tell me a joke",
candidateCount=2, # Gemini-specific
stopSequences=["The end"] # Gemini-specific
)
# Anthropic-specific
response = client.complete(
provider="anthropic",
prompt="Tell me a joke",
stop_sequences=["The end"] # Anthropic-specific
)
Development
Setting Up the Development Environment
-
Clone the repository:
git clone https://github.com/yourusername/llm-wrapper.git cd llm-wrapper
-
Create and activate a virtual environment:
python -m venv venv source venv/bin/activate # On Windows use `venv\Scripts\activate`
-
Install development dependencies:
pip install -e .[dev]
Running Tests
Run the test suite with:
pytest tests/
Project Structure
src/llm_wrapper/: Main package directoryclient.py: Main client interfacemodels.py: Data models and response objectsproviders/: Provider implementationsbase.py: Base provider classopenai.py: OpenAI providergemini.py: Google Gemini provideranthropic.py: Anthropic provider
Adding New Providers
- Create a new provider file in
src/llm_wrapper/providers/(e.g.,new_provider.py) - Implement the provider class inheriting from
BaseProvider - Add the provider to the
Providerenum inmodels.py - Update the
LLMClientclass inclient.pyto support the new provider - Add tests for the new provider in
tests/
Contributing Guidelines
- Follow PEP 8 style guidelines
- Write comprehensive docstrings for all public methods
- Include unit tests for new features
- Update documentation (README.md) when adding new features
- Use descriptive commit messages
License
MIT
Metadata
Release files for awesome-llm-wrapper 0.1.2
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| awesome_llm_wrapper-0.1.2.tar.gz | 12.0 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| awesome_llm_wrapper-0.1.2-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 27.3 kB
Release files / awesome_llm_wrapper-0.1.2.tar.gz
| Download URL | awesome_llm_wrapper-0.1.2.tar.gz |
|---|---|
| Size | 12.0 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
51c64de7c595f767ba3bfdc7371b613cbd463f67251ffbe2640ef2f432474703
|
|
BLAKE2b-256 checksum How to use checksums |
b785e693a8b819cafec58dd7e98a06b6a09ee49d04099b695ffcfb745f1595b2
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.1.0 CPython/3.13.2
|
Release files / awesome_llm_wrapper-0.1.2-py3-none-any.whl
| Download URL | awesome_llm_wrapper-0.1.2-py3-none-any.whl |
|---|---|
| Size | 15.2 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
f858f5d0334c9392cb0c29b674febe7efd773ab574944f3c0f183e8362c37a10
|
|
BLAKE2b-256 checksum How to use checksums |
238fbcd0ece8eba9f450a8813aa1d37bd3f374b9769795ed345ef8fb0989685c
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.1.0 CPython/3.13.2
|