Unified SDK for AI services with OpenAI compatibility
Project description
SDKRouter
Unified Python SDK for AI services with OpenAI compatibility. Access 300+ LLM models through a single interface, plus vision analysis, CDN, URL shortening, and HTML cleaning tools.
Installation
pip install sdkrouter
Quick Start
from sdkrouter import SDKRouter
client = SDKRouter(api_key="your-api-key")
# OpenAI-compatible chat completions
response = client.chat.completions.create(
model="openai/gpt-4o",
messages=[{"role": "user", "content": "Hello!"}]
)
print(response.choices[0].message.content)
Features
Chat Completions (OpenAI-Compatible)
# Non-streaming
response = client.chat.completions.create(
model="anthropic/claude-3.5-sonnet",
messages=[{"role": "user", "content": "Explain quantum computing"}],
max_tokens=500,
)
# Streaming
for chunk in client.chat.completions.create(
model="openai/gpt-4o",
messages=[{"role": "user", "content": "Count to 5"}],
stream=True,
):
print(chunk.choices[0].delta.content or "", end="")
Structured Output (Pydantic)
Get type-safe responses with automatic JSON schema generation:
from pydantic import BaseModel, Field
from sdkrouter import SDKRouter
class Step(BaseModel):
explanation: str = Field(description="Explanation of the step")
result: str = Field(description="Result of this step")
class MathSolution(BaseModel):
steps: list[Step] = Field(description="Solution steps")
final_answer: float = Field(description="The final answer")
client = SDKRouter()
result = client.parse(
model="openai/gpt-4o",
messages=[
{"role": "system", "content": "You are a math tutor. Show your work."},
{"role": "user", "content": "Solve: 3x + 7 = 22"},
],
response_format=MathSolution,
)
solution = result.choices[0].message.parsed
for i, step in enumerate(solution.steps, 1):
print(f"{i}. {step.explanation} → {step.result}")
print(f"Answer: x = {solution.final_answer}")
Vision Analysis
result = client.vision.analyze(
image_url="https://example.com/image.jpg",
prompt="Describe this image",
)
print(result.description)
print(f"Cost: ${result.cost_usd:.6f}")
Quality Tiers
| Tier | Model | Use Case |
|---|---|---|
fast |
gpt-4o-mini | Quick analysis, lower cost |
balanced |
gpt-4o | Default, good quality/cost ratio |
best |
claude-3.5-sonnet | Highest accuracy |
result = client.vision.analyze(
image_url="https://example.com/image.jpg",
model_quality="best", # fast | balanced | best
)
OCR (Text Extraction)
result = client.vision.ocr(
image_url="https://example.com/document.jpg",
language_hint="en", # optional
)
print(result.text)
OCR Modes
| Mode | Speed | Accuracy | Use Case |
|---|---|---|---|
tiny |
Fastest | Basic | Simple text, receipts |
small |
Fast | Good | Standard documents |
base |
Medium | High | Default, balanced |
maximum |
Slow | Best | Complex layouts, handwriting |
result = client.vision.ocr(
image_url="https://example.com/document.jpg",
mode="maximum", # tiny | small | base | maximum
)
CDN File Storage
# Upload bytes
file = client.cdn.upload(
b"file content",
filename="document.txt",
is_public=True,
)
print(file.url)
print(file.short_url)
# Upload from URL
file = client.cdn.upload(
url="https://example.com/image.png",
filename="image.png",
)
# List files
files = client.cdn.list(page=1, page_size=20)
for f in files.results:
print(f"{f.filename}: {f.size_bytes} bytes")
# Get file details
file = client.cdn.get("file-uuid")
# Delete file
client.cdn.delete("file-uuid")
# Statistics
stats = client.cdn.stats()
print(f"Total files: {stats.total_files}")
print(f"Total size: {stats.total_size_bytes} bytes")
URL Shortener
# Create short link
link = client.shortlinks.create(
target_url="https://example.com/very-long-url-here",
custom_slug="my-link", # optional
max_hits=1000, # optional limit
)
print(link.short_url)
print(link.code)
# List links
links = client.shortlinks.list()
for link in links.results:
print(f"{link.code}: {link.hit_count} hits")
# Statistics
stats = client.shortlinks.stats()
print(f"Total links: {stats.total_links}")
print(f"Total hits: {stats.total_hits}")
HTML Cleaner
result = client.cleaner.clean(
html_content,
output_format="markdown", # html | markdown | text
remove_scripts=True,
remove_styles=True,
max_tokens=4000, # optional token limit
)
print(result.cleaned_html)
print(f"Original: {result.original_size} bytes")
print(f"Cleaned: {result.cleaned_size} bytes")
print(f"Compression: {result.compression_ratio:.1f}x")
LLM Models API
# List available models with pagination
models = client.models.list(page=1, page_size=50)
for m in models.results:
print(f"{m.model_id}: context={m.context_length}")
# Get model details
model = client.models.get("openai/gpt-4o")
print(f"Context: {model.context_length} tokens")
print(f"Vision: {model.supports_vision}")
print(f"Price: ${model.pricing.prompt}/M input")
# List providers
providers = client.models.providers()
for p in providers.providers:
print(f"{p.name}: {p.model_count} models")
# Calculate cost
cost = client.models.calculate_cost(
"openai/gpt-4o",
input_tokens=1000,
output_tokens=500,
)
print(f"Input: ${cost.input_cost_usd:.6f}")
print(f"Output: ${cost.output_cost_usd:.6f}")
print(f"Total: ${cost.total_cost_usd:.6f}")
# Statistics
stats = client.models.stats()
print(f"Total models: {stats.total_models}")
print(f"Vision models: {stats.vision_models}")
Token Utilities
from sdkrouter.utils import count_tokens, count_messages_tokens
# Count tokens in text
tokens = count_tokens("Hello, world!")
print(f"Tokens: {tokens}")
# Count tokens in messages
messages = [
{"role": "system", "content": "You are helpful."},
{"role": "user", "content": "Hello!"},
]
tokens = count_messages_tokens(messages)
print(f"Message tokens: {tokens}")
Async Support
All features support async operations:
from sdkrouter import AsyncSDKRouter
import asyncio
async def main():
client = AsyncSDKRouter(api_key="your-api-key")
# Async chat
response = await client.chat.completions.create(
model="openai/gpt-4o",
messages=[{"role": "user", "content": "Hello!"}]
)
# Async structured output
result = await client.parse(
model="openai/gpt-4o",
messages=[...],
response_format=MyModel,
)
# Parallel requests
results = await asyncio.gather(
client.vision.analyze(image_url="..."),
client.cdn.list(),
client.models.stats(),
)
asyncio.run(main())
Configuration
from sdkrouter import SDKRouter
# Environment variables (auto-loaded)
# SDKROUTER_API_KEY - API key
# SDKROUTER_BASE_URL - Custom base URL
# Direct configuration
client = SDKRouter(
api_key="your-key",
base_url="https://your-server.com",
timeout=60.0,
max_retries=3,
)
# Use OpenRouter directly
client = SDKRouter(
openrouter_api_key="your-openrouter-key",
use_self_hosted=False,
)
Type Safety
All responses are fully typed with Pydantic models:
from sdkrouter.tools import (
VisionAnalyzeResponse,
OCRResponse,
CDNFileDetail,
ShortLinkDetail,
CleanResponse,
LLMModelDetail,
)
# IDE autocomplete works
result: VisionAnalyzeResponse = client.vision.analyze(...)
result.description # str
result.cost_usd # float
result.usage.total_tokens # int
Examples
See the examples directory for complete working examples:
| Example | Description |
|---|---|
01_quickstart.py |
Quick start with all features |
02_chat.py |
Chat completions, streaming, multi-turn |
03_structured_output.py |
Pydantic structured output |
04_vision.py |
Vision analysis with quality tiers |
05_cdn.py |
File upload, download, management |
06_shortlinks.py |
URL shortening |
07_models.py |
LLM models listing, cost calculation |
08_cleaner.py |
HTML cleaning and compression |
09_keys.py |
API key management |
10_tokens.py |
Token counting utilities |
11_async.py |
Advanced async patterns |
Supported Models
Access 300+ models from providers:
- OpenAI: GPT-4o, GPT-4 Turbo, GPT-4o-mini, o1, o1-mini
- Anthropic: Claude 3.5 Sonnet, Claude 3 Opus, Claude 3 Haiku
- Google: Gemini 2.0 Flash, Gemini 1.5 Pro
- Meta: Llama 3.3, Llama 3.2, Llama 3.1
- Mistral: Mistral Large, Mixtral, Codestral
- DeepSeek: DeepSeek V3, DeepSeek R1
- And many more via OpenRouter
License
MIT
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 sdkrouter-0.1.1.tar.gz.
File metadata
- Download URL: sdkrouter-0.1.1.tar.gz
- Upload date:
- Size: 67.6 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.10.18
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
7ad7b77df69ce7b8742e80a52552b1f645f5f9b7871e4cdfe2e05f4170317997
|
|
| MD5 |
54b5b195b53c03a5760e52f88449665c
|
|
| BLAKE2b-256 |
d14d968b1b71f29764e3f37edb3b5f5d97b42333c3b49c14159d056f06646cfa
|
File details
Details for the file sdkrouter-0.1.1-py3-none-any.whl.
File metadata
- Download URL: sdkrouter-0.1.1-py3-none-any.whl
- Upload date:
- Size: 111.2 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.10.18
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
4909c57cba9b7e0936dd629fb6d14fe3dc68b9c54cdf72715fb043ad27e8afb7
|
|
| MD5 |
a84d474b1205651fdf44b4b3c2774a2d
|
|
| BLAKE2b-256 |
95776906766223718cbe5ec6298cc2413fae973d8c2023fc6c18e9300d141d7f
|