Unified SDK for AI services with OpenAI compatibility
Project description
SDKRouter
Unified Python SDK for AI services. Access 300+ LLM models, vision, audio, image generation, search, translation, and more through a single interface.
Installation
pip install sdkrouter
Quick Start
from sdkrouter import SDKRouter, Model
client = SDKRouter(api_key="your-api-key")
response = client.chat.completions.create(
model=Model.cheap(),
messages=[{"role": "user", "content": "Hello!"}]
)
print(response.choices[0].message.content)
Features
| Feature | Description | Docs |
|---|---|---|
| Chat | OpenAI-compatible completions, streaming | @docs/01-chat.md |
| Structured Output | Pydantic models, JSON extraction | @docs/02-structured-output.md |
| Audio | TTS, STT, Deepgram streaming | @docs/03-audio.md |
| Vision | Image analysis, OCR | @docs/04-vision.md |
| Image Gen | AI image generation | @docs/05-image-gen.md |
| Search | Web search with modes | @docs/06-search.md |
| CDN | File storage | @docs/07-cdn.md |
| Translator | JSON/text translation | @docs/08-translator.md |
| Payments | Crypto payments | @docs/09-payments.md |
| Proxies | Proxy management | @docs/10-proxies.md |
| Embeddings | Text embeddings | @docs/11-embeddings.md |
| Other | Shortlinks, cleaner, models API | @docs/12-other.md |
Model Routing
Smart model selection with IDE autocomplete:
from sdkrouter import Model
Model.cheap() # Lowest cost
Model.smart() # Highest quality
Model.balanced() # Best value
Model.fast() # Fastest
# With capabilities
Model.cheap(vision=True) # + vision
Model.smart(tools=True) # + function calling
Model.balanced(json=True) # + JSON mode
# Categories
Model.smart(code=True) # Coding
Model.cheap(reasoning=True) # Problem solving
Async Support
from sdkrouter import AsyncSDKRouter, Model
import asyncio
async def main():
client = AsyncSDKRouter(api_key="your-api-key")
response = await client.chat.completions.create(
model=Model.cheap(),
messages=[{"role": "user", "content": "Hello!"}]
)
# Parallel requests
results = await asyncio.gather(
client.vision.analyze(image_url="..."),
client.audio.speech(input="Hello!"),
)
asyncio.run(main())
Audio Example
from sdkrouter import SDKRouter, AudioModel
client = SDKRouter()
# Text-to-Speech
response = client.audio.speech(
input="Hello!",
model=AudioModel.cheap(),
voice="nova",
)
Path("output.mp3").write_bytes(response.audio_bytes)
# Speech-to-Text
result = client.audio.transcribe(file=audio_bytes)
print(result.text)
Deepgram Streaming
from sdkrouter import AsyncSDKRouter
from sdkrouter.tools.audio.stt import DeepgramConfig
sdk = AsyncSDKRouter()
config = DeepgramConfig(
model="nova-3",
endpointing=300, # VAD: silence threshold (ms)
vad_events=True, # Enable VAD events
)
async with sdk.audio.stt.stream_deepgram(config) as session:
await session.send(audio_chunk)
async for segment in session.transcripts():
print(segment.text)
Provider Selection
By default the server auto-detects the provider from the model name. You can override this explicitly:
# Client-level — all requests go through this provider
client = SDKRouter(api_key="your-key", provider="openrouter")
# Per-request override via extra_body
response = client.chat.completions.create(
model="qwen3-max",
messages=[{"role": "user", "content": "Hi"}],
extra_body={"provider": "alibaba"}, # overrides client-level
)
# Works with async too
client = AsyncSDKRouter(api_key="your-key", provider="alibaba")
result = await client.parse(
model="qwen3-max",
messages=[...],
response_format=MyModel,
)
Available providers: openrouter, openai, anthropic (more coming).
Direct Provider Routing
By default (use_self_hosted=True) all LLM and embedding requests go through llm.sdkrouter.com.
To route directly to a provider using your own API key:
# OpenAI directly
client = SDKRouter(
api_key="sk-...",
llm_url="https://api.openai.com/v1",
use_self_hosted=False,
)
# OpenRouter directly
client = SDKRouter(
api_key="sk-or-...",
llm_url="https://openrouter.ai/api/v1",
use_self_hosted=False,
)
In both cases api_url (CDN, vision, search, shortlinks) stays on api.sdkrouter.com —
only LLM/embeddings traffic is redirected to llm_url.
Embeddings
# Via sdkrouter proxy (default, single key)
client = SDKRouter(api_key="your-sdkrouter-key")
result = client.embeddings.create(
["Hello world", "Semantic search"],
model="openai/text-embedding-3-small",
)
vectors = [item.embedding for item in result.data]
# Directly via OpenAI key
client = SDKRouter(
api_key="sk-...",
llm_url="https://api.openai.com/v1",
use_self_hosted=False,
)
result = client.embeddings.create("Hello world", model="text-embedding-3-small")
# Directly via OpenRouter key
client = SDKRouter(
api_key="sk-or-...",
llm_url="https://openrouter.ai/api/v1",
use_self_hosted=False,
)
result = client.embeddings.create("Hello world", model="openai/text-embedding-3-small")
| Model | Dimensions |
|---|---|
openai/text-embedding-3-small |
1536 (default) |
openai/text-embedding-3-large |
3072 |
openai/text-embedding-ada-002 |
1536 (legacy) |
Configuration
# Environment variables (auto-loaded)
# SDKROUTER_API_KEY
# SDKROUTER_LLM_URL
# SDKROUTER_API_URL
# SDKROUTER_AUDIO_URL
client = SDKRouter(
api_key="your-key",
timeout=60.0,
max_retries=3,
)
Prompt Caching & Metrics
For Anthropic Claude models, SDKRouter automatically applies cache_control breakpoints.
Cache metrics are returned in response.usage.prompt_tokens_details:
response = client.chat.completions.create(
model="anthropic/claude-haiku-4-5",
messages=[...], # long conversation
)
details = response.usage.prompt_tokens_details
if details:
print("Cache read tokens: ", details.cached_tokens) # billed at 10%
print("Cache write tokens:", details.cache_write_tokens) # billed at 125%
No client-side changes needed — caching is transparent and automatic.
Supported Providers
- OpenAI: GPT-4.5, GPT-4o, o3, o1
- Anthropic: Claude Opus 4.6, Claude Sonnet 4.6, Claude Haiku 4.5
- Google: Gemini 2.5 Pro, Gemini 2.0 Flash
- Alibaba DashScope: Qwen3-Max, Qwen3.5-Plus, Qwen-Plus, QwQ-32B, Qwen3-VL
- Meta: Llama 4, Llama 3.3
- Mistral: Mistral Large, Codestral
- DeepSeek: DeepSeek V3, R1
- And 300+ 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.32.tar.gz.
File metadata
- Download URL: sdkrouter-0.1.32.tar.gz
- Upload date:
- Size: 168.1 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.10.18
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
2ceea4093c0af470282560018e9a98d268fbcff1eb01eb7560935d647b613dec
|
|
| MD5 |
cbf399fd2d9b80a509c4bc225bf56fe3
|
|
| BLAKE2b-256 |
c64a5391d3a678853564b84a9252dc84a2826860474b9cd52d54c64714385d02
|
File details
Details for the file sdkrouter-0.1.32-py3-none-any.whl.
File metadata
- Download URL: sdkrouter-0.1.32-py3-none-any.whl
- Upload date:
- Size: 254.8 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 |
872e736e0f7285ba9f48435f4ce13ea6b7306e073847be78b84ccc9577d35845
|
|
| MD5 |
c092ed27f1f8fe253b2c6036f80cdbb0
|
|
| BLAKE2b-256 |
68535d14c7ee291dfd27c2a5a1681bfb20b04eac8ed0047eba099eb10999d9f3
|