Skip to main content

Unified SDK for AI services with OpenAI compatibility

Project description

SDKRouter

SDKRouter

Unified Python SDK for AI services. Access 300+ LLM models, vision, audio, image generation, search, knowledge bases, 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, crop_to, preset management @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
Knowledge Base Vector search, GitHub crawling, MCP @docs/13-knowbase.md
Banner Generator README/social banners with LLM prompt enhancement @docs/14-banner.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)

Banner Generator

Generate hero images and banners for README.md and other project files. The LLM always runs — it reads your project context, follows the target image model's prompt rules (DALL-E vs Gemini), and writes an optimised prompt automatically.

from sdkrouter import SDKRouter
from sdkrouter.tools.banner import BannerStyle, BannerSize

client = SDKRouter(api_key="sk_live_xxx")

# From README — LLM picks style from context automatically
result = client.banner.generate(
    source="README.md",
    output="assets/banner.png",
)
print(result.image_url)    # CDN URL
print(result.saved_to)     # local file path
print(result.cost_usd)     # total cost (LLM + image gen)

# Steer LLM aesthetic with a style enum
result = client.banner.generate(
    source="README.md",
    preset=BannerStyle.GLASSMORPHISM,  # enum — directs LLM's aesthetic
    size=BannerSize.GITHUB,            # enum — 1792x1024
    model="@smart",
    output="banner.png",
)

# String values also accepted
result = client.banner.generate(
    title="My API Gateway",
    preset="cyberpunk",
    size="social",
    output="social.png",
)

# Skip LLM — provide your own final prompt
result = client.banner.generate(
    prompt="Pixar-style 3D robot at a futuristic terminal, vivid neon colors",
    output="custom.png",
)

# Dry run — see the LLM-generated prompt before spending on image gen
result = client.banner.generate(
    source="README.md",
    preset=BannerStyle.AI_NETWORK,
    dry_run=True,
)
print(result.prompt)

Visual Style Presets (BannerStyle enum)

Passed as preset= — steers the LLM's aesthetic direction. The LLM always runs and adapts the style to your project context.

Enum Value Visual Style Best For
BannerStyle.GLASSMORPHISM "glassmorphism" Dark navy, frosted glass, neon teal API gateways, SDKs, LLM routers
BannerStyle.ISOMETRIC "isometric" Pastel 3D boxes, geometric CLI tools, data pipelines
BannerStyle.AI_NETWORK "ai_network" Glowing nodes in deep space AI/ML, vector search, LLMs
BannerStyle.CYBERPUNK "cyberpunk" Neon circuits, matrix rain GPU tools, real-time systems
BannerStyle.BLUEPRINT "blueprint" White lines on navy, schematic DevOps, infrastructure
BannerStyle.MINIMAL "minimal" Smooth gradient, SaaS feel Web frameworks, open-source
BannerStyle.SPEED "speed" Light beams, motion blur CDN, proxy, shortlinks
BannerStyle.PIXAR "pixar" Friendly 3D mascot Beginner tools, educational
BannerStyle.HOLOGRAPHIC "holographic" Iridescent, rainbow refraction AI assistants, next-gen APIs
BannerStyle.GRADIENT_MESH "gradient_mesh" Organic gradient mesh SaaS products, productivity

Size Presets (BannerSize enum)

Enum Value Size Use case
BannerSize.GITHUB "github" 1792×1024 README.md hero image (default)
BannerSize.SOCIAL "social" 1200×630 Twitter / LinkedIn card
BannerSize.OG "og" 1200×630 OpenGraph meta image
BannerSize.WIDE "wide" 1792×512 Wide website banner
BannerSize.SQUARE "square" 1024×1024 npm / PyPI icon

Model-Aware Prompt Generation

The LLM generates prompts optimised for the target image model's rules:

Model Family Prompt rules
@balancedopenai/gpt-5-image-mini DALL-E Natural language, negatives embedded in text
@cheap / @fast / @smart → Gemini Gemini Natural language, strong style adherence, hex colors
openai/gpt-image-1, dall-e-3 DALL-E Natural language
google/gemini-2.5-flash-image Gemini 100–250 words, explicit art style names

Parameters

client.banner.generate(
    source="README.md",             # local file or GitHub URL
    title="My Library",             # project title (optional)
    description="...",              # short description (optional)
    github_url="https://...",       # GitHub repo URL (optional)
    prompt="...",                   # skip LLM, use your own final prompt
    preset=BannerStyle.AI_NETWORK,  # visual style enum (or string)
    size=BannerSize.GITHUB,         # size enum (or string)
    model="@balanced",              # image gen model (auto-detects family)
    llm_model="@smart",             # LLM for prompt generation
    quality="hd",                   # "standard" or "hd"
    style="vivid",                  # "natural" or "vivid"
    output="banner.png",            # save to disk (optional)
    dry_run=False,                  # True = return prompt only, no image gen
)

Knowledge Base

Manage per-user knowledge base projects with vector search and GitHub crawling.

client = SDKRouter(api_key="sk_live_xxx")

# Create a project
project = client.knowbase.projects.create(
    name="My Docs",
    slug="my-docs",
    is_public=True,
)

# Add a GitHub repository as a data source
source = client.knowbase.sources("my-docs").add(
    url="https://github.com/org/repo",
    branch="main",
    path_filter="docs/",
)

# Trigger an immediate crawl
client.knowbase.sources("my-docs").crawl(source.id)

# Upload a document manually
doc = client.knowbase.documents("my-docs").upload(
    title="API Reference",
    content="# API Reference\n\nAuthenticate using Bearer tokens...",
)

# Upload a local Markdown file
doc = client.knowbase.documents("my-docs").upload_file(Path("./README.md"))

# Semantic vector search (multilingual)
results = client.knowbase.search("my-docs", "how to authenticate")
for r in results.results:
    print(f"{r.similarity:.2f}  {r.document_title}")
    print(r.content[:200])

Bulk Archive Ingest

Upload a ZIP or a local directory — files are converted, LLM-summarised, vectorised, and indexed asynchronously via a background job:

from pathlib import Path

# Upload a ZIP archive and wait for completion
queued = client.knowbase.documents("my-docs").upload_archive("docs.zip")
client.knowbase.documents("my-docs").wait_for_archive_done(queued.job_id)

# Or ingest a local directory directly
queued = client.knowbase.documents("my-docs").upload_dir(Path("./docs"))
client.knowbase.documents("my-docs").wait_for_archive_done(queued.job_id, timeout=300)

# Poll job status manually
status = client.knowbase.documents("my-docs").job_status(queued.job_id)
print(status.status, status.progress)

# Wait for embeddings to be ready after ingest
client.knowbase.documents("my-docs").wait_for_processing(doc.id)

Supported file types: .md, .mdx, .py, .ts, .tsx, .js, .go, .json, .yaml, .rst, .txt and more.

MCP Integration

Connect Claude Desktop, Cursor, or any MCP-compatible LLM client directly to your knowledge base:

{
  "mcpServers": {
    "my-docs": {
      "url": "https://mcp.sdkrouter.com/mcp",
      "headers": {
        "Authorization": "Bearer sk_live_xxx"
      }
    }
  }
}

MCP tools exposed: search_knowledge_base, list_projects, get_project_info.

Payments

Cryptocurrency payment processing via NowPayments.

client = SDKRouter(api_key="sk_live_xxx")

# Check balance
balance = client.payments.get_balance()
print(balance.currency, balance.amount)

# Create a payment invoice
payment = client.payments.create(
    amount_usd="49.00",
    currency_code="USDTTRC20",
    description="Pro plan",
    callback_url="https://example.com/webhook",
)
print(payment.payment_url)   # redirect user here
print(payment.payment_id)

# Check status
status = client.payments.check_status(payment.payment_id)
print(status.status)  # "waiting", "confirming", "confirmed", "finished"

# List recent payments
page = client.payments.list(page=1, page_size=20)
for p in page.results:
    print(p.payment_id, p.status, p.amount_usd)

# Request a withdrawal
withdrawal = client.payments.create_withdrawal(
    amount_usd="100.00",
    currency_code="USDTTRC20",
    wallet_address="T...",
)

Proxies

Manage residential and datacenter proxy pools with rotation and assignment.

client = SDKRouter(api_key="sk_live_xxx")

# List all proxies
proxies = client.proxies.list()

# Get healthy proxies only
healthy = client.proxies.get_healthy()
korean = client.proxies.get_korean()
by_country = client.proxies.get_by_country("US")

# Create a rotation group
rotation = client.proxies.create_rotation(
    name="scraping-pool",
    proxy_ids=[p.id for p in healthy[:10]],
)

# Assign a proxy to a task
assignment = client.proxies.create_assignment(
    proxy_id=healthy[0].id,
    task_id="job-123",
)

# Performance stats
stats = client.proxies.get_performance_stats()

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
)

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, knowledge base) 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")
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
# SDKROUTER_MCP_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


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

sdkrouter-0.1.41.tar.gz (255.5 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

sdkrouter-0.1.41-py3-none-any.whl (399.7 kB view details)

Uploaded Python 3

File details

Details for the file sdkrouter-0.1.41.tar.gz.

File metadata

  • Download URL: sdkrouter-0.1.41.tar.gz
  • Upload date:
  • Size: 255.5 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.10.18

File hashes

Hashes for sdkrouter-0.1.41.tar.gz
Algorithm Hash digest
SHA256 37bb8dac919d43986bebe923317186e81d600fbfaf9900f465d5020ba5bec935
MD5 19eb224e0eece8d2bb267129e008da87
BLAKE2b-256 f2401a22067ba45a1b1d43c2ce9fc450fad4b931b20db50d13f4c990ce6949ab

See more details on using hashes here.

File details

Details for the file sdkrouter-0.1.41-py3-none-any.whl.

File metadata

  • Download URL: sdkrouter-0.1.41-py3-none-any.whl
  • Upload date:
  • Size: 399.7 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.10.18

File hashes

Hashes for sdkrouter-0.1.41-py3-none-any.whl
Algorithm Hash digest
SHA256 6eef3d431c2c9668898360d428f2173152d8a1b81bd0a2cabdafb5472f952e6d
MD5 5a88226a6573cd5aec747861f5d23f5c
BLAKE2b-256 a601feb8fc0ea5da8f91bde13683337fe3ca1efdba3eb985804c32df57f51b6d

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page