A production-ready Claude API proxy server
Project description
Claude API Proxy
A production-ready Claude API proxy server that enables seamless integration with OpenAI-compatible API providers.
Features
- 🔄 Protocol Conversion: Complete Claude API to OpenAI API format conversion
- 🚀 High Performance: Async FastAPI with connection pooling
- 📡 Streaming Support: Real-time Server-Sent Events streaming
- 🎯 Smart Model Mapping: Configurable model routing (Haiku→Small, Sonnet/Opus→Big)
- 🔒 Secure: Optional API key validation and request authentication
- 🐳 Docker Ready: Easy deployment with Docker/Docker Compose
- 🔍 Observable: Health checks, logging, and error handling
- 🛠️ Developer Friendly: Type-safe with Pydantic models
Quick Start
🚀 Simple Testing (Recommended)
For quick local testing, just install and run:
# Install from PyPI
pip install claude-proxy
# Set your OpenAI API key
export OPENAI_API_KEY=sk-your-openai-key
# Start the proxy (default: http://localhost:8085)
claude-proxy
That's it! The proxy will start and be ready to use with Claude Code.
⚙️ Advanced Configuration
For custom configuration, set environment variables:
# API Configuration
export OPENAI_API_KEY=sk-your-openai-key
export OPENAI_BASE_URL=https://api.openai.com/v1 # Optional
# Model Mapping
export BIG_MODEL=gpt-4o # For Claude Sonnet/Opus requests
export SMALL_MODEL=gpt-4o-mini # For Claude Haiku requests
# Server Settings
export HOST=0.0.0.0
export PORT=8085
export LOG_LEVEL=INFO
# Optional: API key validation
export ANTHROPIC_API_KEY=your-anthropic-key-for-validation
# Then run
claude-proxy
🏭 Production Deployment
For production use with better performance and reliability:
# Install with production dependencies
pip install claude-proxy[production]
# Option 1: Run with uvicorn (ASGI server)
uvicorn claude_proxy.main:app --host 0.0.0.0 --port 8085 --workers 4
# Option 2: Run with gunicorn + uvicorn workers (recommended)
gunicorn claude_proxy.main:app -w 4 -k uvicorn.workers.UvicornWorker --bind 0.0.0.0:8085
# Option 3: Behind a reverse proxy (nginx/traefik)
uvicorn claude_proxy.main:app --host 127.0.0.1 --port 8085 --workers 4
Production Environment Variables
# Required
export OPENAI_API_KEY=sk-your-production-key
# Recommended for production
export ANTHROPIC_API_KEY=your-validation-key # Enable API key validation
export LOG_LEVEL=WARNING # Reduce log verbosity
export REQUEST_TIMEOUT=60 # Shorter timeout for production
🐳 Docker Deployment
# Build and run with docker-compose
docker-compose up -d
# Or build manually
docker build -t claude-proxy .
docker run -p 8085:8085 -e OPENAI_API_KEY=your-key claude-proxy
🔗 Use with Claude Code
# Set the proxy URL
export ANTHROPIC_BASE_URL=http://localhost:8085
export ANTHROPIC_API_KEY=any-value # Or your validation key if set
# Use Claude Code as normal
claude
🛠️ Development Setup
For development work:
# Clone the repository
git clone <repository-url>
cd claude-proxy
# Install with uv (recommended)
uv sync
# Run in development mode
uv run python app.py
# Or run the package directly
uv run claude-proxy
API Endpoints
Main Endpoints
POST /v1/messages- Chat completions (compatible with Claude API)POST /v1/messages/count_tokens- Token countingGET /health- Health checkGET /test-connection- Test connectivity to target APIGET /- API information
Model Mapping
The proxy automatically maps Claude models to your configured models:
| Claude Model | Maps To | Environment Variable |
|---|---|---|
claude-3-haiku* |
SMALL_MODEL |
Default: gpt-4o-mini |
claude-3-sonnet* |
BIG_MODEL |
Default: gpt-4o |
claude-3-opus* |
BIG_MODEL |
Default: gpt-4o |
claude-sonnet-4* |
BIG_MODEL |
Default: gpt-4o |
Usage Examples
Basic Chat Completion
import httpx
response = httpx.post(
"http://localhost:8085/v1/messages",
headers={"x-api-key": "your-api-key"}, # Optional if validation disabled
json={
"model": "claude-3-5-sonnet-20241022",
"max_tokens": 100,
"messages": [
{"role": "user", "content": "Hello, world!"}
]
}
)
print(response.json())
Streaming Chat
import httpx
with httpx.stream(
"POST",
"http://localhost:8085/v1/messages",
headers={"x-api-key": "your-api-key"},
json={
"model": "claude-3-haiku",
"max_tokens": 100,
"stream": True,
"messages": [
{"role": "user", "content": "Tell me a story"}
]
}
) as response:
for line in response.iter_lines():
if line.startswith("data: "):
print(line[6:]) # Remove "data: " prefix
With System Prompt and Tools
response = httpx.post(
"http://localhost:8085/v1/messages",
headers={"x-api-key": "your-api-key"},
json={
"model": "claude-3-sonnet",
"max_tokens": 200,
"system": "You are a helpful assistant.",
"messages": [
{"role": "user", "content": "What's the weather like?"}
],
"tools": [
{
"type": "function",
"function": {
"name": "get_weather",
"description": "Get current weather",
"parameters": {
"type": "object",
"properties": {
"location": {"type": "string"}
}
}
}
}
]
}
)
Provider Configuration
OpenAI
OPENAI_API_KEY=sk-your-openai-key
OPENAI_BASE_URL=https://api.openai.com/v1
BIG_MODEL=gpt-4o
SMALL_MODEL=gpt-4o-mini
Azure OpenAI
OPENAI_API_KEY=your-azure-key
OPENAI_BASE_URL=https://your-resource.openai.azure.com/openai/deployments/your-deployment
BIG_MODEL=gpt-4
SMALL_MODEL=gpt-35-turbo
Local Models (Ollama)
OPENAI_API_KEY=dummy-key # Required but can be dummy
OPENAI_BASE_URL=http://localhost:11434/v1
BIG_MODEL=llama3.1:70b
SMALL_MODEL=llama3.1:8b
Development
Running Tests
# Run all tests
uv run pytest
# Run with coverage
uv run pytest --cov=. --cov-report=html
# Run specific test file
uv run pytest tests/test_app.py -v
Code Quality
# Format code
uv run black .
# Lint code
uv run ruff check .
# Type checking
uv run mypy .
Project Structure
claude-proxy/
├── app.py # FastAPI application
├── config.py # Configuration management
├── utils.py # Utility functions
├── models/ # Data models
│ ├── claude.py # Claude API models
│ └── openai.py # OpenAI API models
├── providers/ # LLM provider implementations
│ ├── base.py # Base provider class
│ ├── openai.py # OpenAI provider
│ └── anthropic.py # Anthropic provider (pass-through)
└── tests/ # Test suite
Deployment
Docker
# Build image
docker build -t claude-proxy .
# Run container
docker run -p 8085:8085 --env-file .env claude-proxy
Docker Compose
# Create .env file with your configuration
cp .env.example .env
# Start services
docker-compose up -d
# View logs
docker-compose logs -f
Production Considerations
- Use a reverse proxy (Nginx/Traefik) for HTTPS termination
- Set up monitoring and logging
- Configure resource limits and health checks
- Use secrets management for API keys
- Enable API key validation in production
Contributing
- Fork the repository
- Create a feature branch
- Make your changes
- Add tests
- Run the test suite
- Submit a pull request
License
MIT License - see LICENSE file for details.
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
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_proxy-0.2.0.tar.gz.
File metadata
- Download URL: claude_proxy-0.2.0.tar.gz
- Upload date:
- Size: 76.5 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.1.0 CPython/3.10.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
1aa6782a8ef8a0382e207930f66047de7c5f5d684772d2d18f5fe1420ddeee97
|
|
| MD5 |
359b9097570acce001818376afbdc5e1
|
|
| BLAKE2b-256 |
97323c72ca63cbed51fa8070e3b2d589118f3ae1cbf8aea11eb88e879d9221a3
|
File details
Details for the file claude_proxy-0.2.0-py3-none-any.whl.
File metadata
- Download URL: claude_proxy-0.2.0-py3-none-any.whl
- Upload date:
- Size: 18.0 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.1.0 CPython/3.10.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
1ce6a5d4c55fbbcfc9f95797bb7404e1d9681535e2d45b4f1a9c5c29bcc94d63
|
|
| MD5 |
bc75594313beff6d8efcc41bc4141db1
|
|
| BLAKE2b-256 |
b42fa08e8c1a692e3e88d8648ef0cbd23ca5f6de993c299a4489ab654b487d05
|