A simple Python wrapper for Claude CLI with streaming support and OpenAI-compatible API interface
Project description
Claude Wrapper
A simple Python wrapper for Claude CLI that seamlessly integrates Claude's capabilities into your Python applications. This package provides streaming support and an OpenAI-compatible API interface.
โจ Key Features
- ๐ง Simple Integration: Use Claude CLI through Python with minimal setup
- ๐ Streaming Support: Real-time response streaming with proper async handling
- ๐ OpenAI-Compatible API: Drop-in replacement for OpenAI API clients
- ๐ No API Keys: Leverages Claude CLI's authentication - no separate API keys needed
- โก Robust Error Handling: Automatic retries and comprehensive error management
- ๐ Efficient: Subprocess optimization with configurable timeouts and retries
๐ 5-Minute Quickstart
Prerequisites
- Install Claude CLI (if not already installed):
npm install -g @anthropic-ai/claude-cli
# OR
brew install claude
# Authenticate once
claude login
- Install Claude Wrapper:
pip install claude-wrapper
# OR from source
git clone https://github.com/yourusername/claude-wrapper
cd claude-wrapper
pip install -e .
Quick Examples
Example 1: Basic Chat (30 seconds)
import asyncio
from claude_wrapper import ClaudeClient
async def quick_chat():
client = ClaudeClient()
# Simple question
response = await client.chat("What is Python?")
print(response)
asyncio.run(quick_chat())
Example 2: Streaming Responses (1 minute)
import asyncio
from claude_wrapper import ClaudeClient
async def stream_example():
client = ClaudeClient()
print("Claude: ", end="")
async for chunk in client.stream_chat("Tell me a short joke"):
print(chunk, end="", flush=True)
print() # New line after response
asyncio.run(stream_example())
Example 3: CLI Usage (30 seconds)
# Quick question
claude-wrapper chat "What is the capital of France?"
# Stream the response
claude-wrapper chat "Explain quantum computing" --stream
Example 4: API Server with OpenAI Client (2 minutes)
# Terminal 1: Start the server
claude-wrapper server
# Terminal 2: Use with OpenAI client
from openai import OpenAI
client = OpenAI(
base_url="http://localhost:8000/v1",
api_key="not-needed" # No API key required!
)
# Works exactly like OpenAI
response = client.chat.completions.create(
model="sonnet",
messages=[
{"role": "user", "content": "Write a haiku about Python"}
]
)
print(response.choices[0].message.content)
Example 5: Advanced Usage with Error Handling (1 minute)
import asyncio
from claude_wrapper import ClaudeClient
from claude_wrapper.core.exceptions import ClaudeTimeoutError, ClaudeAuthError
async def robust_chat():
client = ClaudeClient(timeout=30, retry_attempts=3)
try:
# Simple request
response = await client.chat("Explain quantum computing")
print(f"Response: {response}")
except ClaudeAuthError:
print("Please run 'claude login' first")
except ClaudeTimeoutError:
print("Request timed out, try increasing timeout")
asyncio.run(robust_chat())
๐ฆ Installation
From PyPI (when published)
pip install claude-wrapper
From Source
git clone https://github.com/yourusername/claude-wrapper
cd claude-wrapper
pip install -e .
Using uv (recommended for development)
uv pip install -e .
# Run tests
uv run pytest
๐ฏ Core Capabilities
What Claude Wrapper Does
โ
Wraps Claude CLI - Provides Python interface to Claude CLI commands
โ
Handles Streaming - Supports real-time streaming with --output-format stream-json
โ
Provides API Server - OpenAI-compatible REST API
โ
Error Recovery - Automatic retries with exponential backoff
โ
Token Estimation - Estimates token usage (word count ร 1.3)
Current Limitations
The wrapper works with Claude CLI's supported options:
- โ
Uses
--printflag for non-interactive responses - โ
Supports
--output-format stream-jsonfor streaming - โ ๏ธ Parameters like
max_tokens,temperature,system_promptare not passed to CLI (Claude CLI doesn't support them yet) - โ ๏ธ Token counting is estimated, not exact
๐๏ธ Architecture
Your Application
โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ Claude Wrapper โ
โ โ
โ โโโโโโโโโโโโโโโโโโโโโโโโโโโโ โ
โ โ Python Interface โ โ
โ โ โข ClaudeClient โ โ
โ โ โข Error Handling โ โ
โ โโโโโโโโโโโโโโฌโโโโโโโโโโโโโโ โ
โ โ โ
โ โโโโโโโโโโโโโโโโโโโโโโโโโโโโ โ
โ โ Subprocess Manager โ โ
โ โ โข Async execution โ โ
โ โ โข Retry logic โ โ
โ โ โข Timeout handling โ โ
โ โโโโโโโโโโโโโโฌโโโโโโโโโโโโโโ โ
โโโโโโโโโโโโโโโโโผโโโโโโโโโโโโโโโโโโ
โ
Claude CLI (--print)
โ
Claude AI
๐ API Reference
ClaudeClient
class ClaudeClient:
def __init__(
self,
claude_path: str = "claude", # Path to Claude CLI
timeout: float = 120.0, # Command timeout in seconds
retry_attempts: int = 3, # Number of retries
retry_delay: float = 1.0 # Delay between retries
)
Methods
**chat(message, kwargs)
- Send a message and get a response
- Returns:
str
**stream_chat(message, kwargs)
- Stream a response in real-time
- Returns:
AsyncGenerator[str, None] - Falls back to regular chat if streaming unavailable
**complete(prompt, kwargs)
- Simple completion
- Returns:
str
count_tokens(text)
- Estimate token count
- Returns:
Dict[str, int]withtokensandwords
๐ง CLI Commands
# Chat commands
claude-wrapper chat "Your message"
claude-wrapper chat "Your message" --stream
# Server
claude-wrapper server --host 0.0.0.0 --port 8000
# Other commands
claude-wrapper version
โ๏ธ Configuration
Environment Variables
export CLAUDE_WRAPPER_CLAUDE_PATH="/usr/local/bin/claude"
export CLAUDE_WRAPPER_TIMEOUT=120
export CLAUDE_WRAPPER_RETRY_ATTEMPTS=3
export CLAUDE_WRAPPER_API_KEY="optional-api-key" # Optional API key for server
Configuration File
Create ~/.claude-wrapper/config.yaml:
claude:
path: /usr/local/bin/claude
timeout: 120
retry_attempts: 3
api:
key: optional-api-key # Optional API key for server
๐งช Testing
# Install with dev dependencies
pip install -e ".[dev]"
# Run tests
pytest tests/
# Run specific test file
pytest tests/test_client.py -v
# Run without coverage
pytest --no-cov
# Using uv (recommended)
uv run pytest
๐ Troubleshooting
Claude CLI Not Found
# Check installation
which claude
# Set custom path
export CLAUDE_WRAPPER_CLAUDE_PATH=/path/to/claude
Authentication Issues
# Re-authenticate
claude login
Timeout Errors
# Increase timeout
client = ClaudeClient(timeout=300)
Streaming Not Working
The wrapper will automatically fall back to non-streaming mode if Claude CLI doesn't support streaming for your version.
๐ Performance Notes
- First Message: ~1-2 seconds (includes CLI startup)
- Follow-up Messages: ~0.8-1.5 seconds
- Memory Usage: ~50MB base
- Token Estimation: Approximately 1.3 tokens per word
๐ค Contributing
- Fork the repository
- Create your feature branch (
git checkout -b feature/amazing) - Make your changes
- Run tests (
uv run pytest) - Commit (
git commit -m 'Add amazing feature') - Push (
git push origin feature/amazing) - Open a Pull Request
๐ License
MIT License - see LICENSE file for details.
๐ Acknowledgments
- Anthropic for Claude and Claude CLI
- The Python async/await ecosystem
- FastAPI and Typer for excellent frameworks
Built to make Claude accessible and efficient for Python developers.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file claude_wrapper-0.1.dev15.tar.gz.
File metadata
- Download URL: claude_wrapper-0.1.dev15.tar.gz
- Upload date:
- Size: 184.5 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.12.9
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
18cd57e6fa66f724488e8640bee87c1c9faf2c6093ca5e013dc3754ce779ac6d
|
|
| MD5 |
464033f7d7457eadf0451c73b5551ce1
|
|
| BLAKE2b-256 |
c460dad710839a0d0298498f3b61b2c1b8d1c6a32349fc4eb04f33ac2eddf844
|
Provenance
The following attestation bundles were made for claude_wrapper-0.1.dev15.tar.gz:
Publisher:
release.yml on darth-veitcher/claude-wrapper
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
claude_wrapper-0.1.dev15.tar.gz -
Subject digest:
18cd57e6fa66f724488e8640bee87c1c9faf2c6093ca5e013dc3754ce779ac6d - Sigstore transparency entry: 406291815
- Sigstore integration time:
-
Permalink:
darth-veitcher/claude-wrapper@e73c0080c98c242b83f04587a9aa338aabc9cad1 -
Branch / Tag:
refs/heads/main - Owner: https://github.com/darth-veitcher
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@e73c0080c98c242b83f04587a9aa338aabc9cad1 -
Trigger Event:
push
-
Statement type:
File details
Details for the file claude_wrapper-0.1.dev15-py3-none-any.whl.
File metadata
- Download URL: claude_wrapper-0.1.dev15-py3-none-any.whl
- Upload date:
- Size: 20.8 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.12.9
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
94f24e7b5b2fbbba93f343d3747e0372c4d6c0ce751bd081eb5129338c6ad2bf
|
|
| MD5 |
0f8e392463a3fb5692ce863f83f83047
|
|
| BLAKE2b-256 |
edcad7783a2a3ea5e5d39fa5941fa1a3413bd8b483ed7a942cb3c9247c6188d9
|
Provenance
The following attestation bundles were made for claude_wrapper-0.1.dev15-py3-none-any.whl:
Publisher:
release.yml on darth-veitcher/claude-wrapper
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
claude_wrapper-0.1.dev15-py3-none-any.whl -
Subject digest:
94f24e7b5b2fbbba93f343d3747e0372c4d6c0ce751bd081eb5129338c6ad2bf - Sigstore transparency entry: 406291822
- Sigstore integration time:
-
Permalink:
darth-veitcher/claude-wrapper@e73c0080c98c242b83f04587a9aa338aabc9cad1 -
Branch / Tag:
refs/heads/main - Owner: https://github.com/darth-veitcher
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@e73c0080c98c242b83f04587a9aa338aabc9cad1 -
Trigger Event:
push
-
Statement type: