Metadata-Version: 2.4
Name: sdkrouter
Version: 0.1.0
Summary: Unified SDK for AI services with OpenAI compatibility
Project-URL: Homepage, https://github.com/markolofsen/sdkrouter
Project-URL: Documentation, https://sdkrouter.com
Project-URL: Repository, https://github.com/markolofsen/sdkrouter
Author-email: markolofsen <dev@markolofsen.com>
License-Expression: MIT
Keywords: ai,api,cdn,llm,ocr,openai,sdk,vision
Classifier: Development Status :: 4 - Beta
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: MIT License
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Topic :: Software Development :: Libraries :: Python Modules
Requires-Python: >=3.10
Requires-Dist: beautifulsoup4>=4.12.0
Requires-Dist: httpx<1.0.0,>=0.25.0
Requires-Dist: lxml>=5.0.0
Requires-Dist: markdownify>=0.14.0
Requires-Dist: openai<3.0.0,>=1.0.0
Requires-Dist: pydantic-settings>=2.0.0
Requires-Dist: pydantic<3.0.0,>=2.0.0
Requires-Dist: rich>=14.0.0
Requires-Dist: tenacity>=9.0.0
Requires-Dist: tiktoken>=0.5.0
Requires-Dist: toon-python>=0.1.2
Provides-Extra: dev
Requires-Dist: build>=1.0.0; extra == 'dev'
Requires-Dist: mypy>=1.13.0; extra == 'dev'
Requires-Dist: pytest-asyncio>=0.24.0; extra == 'dev'
Requires-Dist: pytest-cov>=6.0.0; extra == 'dev'
Requires-Dist: pytest>=8.0.0; extra == 'dev'
Requires-Dist: questionary>=2.0.0; extra == 'dev'
Requires-Dist: ruff>=0.8.0; extra == 'dev'
Requires-Dist: toml>=0.10.0; extra == 'dev'
Requires-Dist: twine>=5.0.0; extra == 'dev'
Description-Content-Type: text/markdown

# 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

```bash
pip install sdkrouter
```

## Quick Start

```python
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)

```python
# 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, end="")
```

### Vision Analysis

```python
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}")
```

### CDN File Storage

```python
# Upload file
file = client.cdn.upload(
    b"file content",
    filename="document.txt",
    is_public=True,
)
print(file.url)

# List files with pagination
files = client.cdn.list(page=1, page_size=20)
for f in files.results:
    print(f"{f.filename}: {f.url}")
```

### URL Shortener

```python
# Create short link
link = client.shortlinks.create(target_url="https://example.com/long-url")
print(link.short_url)

# Get statistics
stats = client.shortlinks.stats()
print(f"Total links: {stats.total_links}")
```

### HTML Cleaner

```python
result = client.cleaner.clean(
    html_content,
    output_format="markdown",
    remove_scripts=True,
    remove_styles=True,
)
print(result.cleaned_html)
print(f"Compression: {result.compression_ratio:.1f}x")
```

### LLM Models API

```python
# List available models
models = client.models.list(page=1, page_size=50)
for m in models.results:
    print(f"{m.model_id}: {m.name}")

# Get model details
model = client.models.get("openai/gpt-4o")
print(f"Context: {model.context_length} tokens")
print(f"Price: ${model.pricing.prompt}/M input tokens")

# Calculate cost
cost = client.models.calculate_cost(
    "openai/gpt-4o",
    input_tokens=1000,
    output_tokens=500,
)
print(f"Total: ${cost.total_cost_usd:.6f}")
```

## Async Support

All features support async operations:

```python
from sdkrouter import AsyncSDKRouter
import asyncio

async def main():
    client = AsyncSDKRouter(api_key="your-api-key")

    # Async chat completion
    response = await client.chat.completions.create(
        model="openai/gpt-4o",
        messages=[{"role": "user", "content": "Hello!"}]
    )

    # Parallel requests
    results = await asyncio.gather(
        client.vision.analyze(image_url="..."),
        client.models.list(),
        client.cdn.stats(),
    )

asyncio.run(main())
```

## Type Safety

All responses are fully typed with Pydantic models:

```python
from sdkrouter.tools import (
    VisionAnalyzeResponse,
    CDNFileDetail,
    PaginatedLLMModelListList,
    CleanResponse,
)

# IDE autocomplete and type checking
result: VisionAnalyzeResponse = client.vision.analyze(...)
print(result.description)  # str
print(result.cost_usd)     # float
print(result.usage.total_tokens)  # int
```

## Configuration

```python
# Environment variables
# SDKROUTER_API_KEY - API key
# SDKROUTER_BASE_URL - Custom base URL (default: https://ai.sdkrouter.com)

# Or pass directly
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,
)
```

## Supported Models

Access 300+ models from providers:

- **OpenAI**: GPT-4o, GPT-4 Turbo, GPT-3.5 Turbo
- **Anthropic**: Claude 3.5 Sonnet, Claude 3 Opus, Claude 3 Haiku
- **Google**: Gemini Pro, Gemini Flash
- **Meta**: Llama 3.1, Llama 3.2
- **Mistral**: Mistral Large, Mixtral
- And many more via OpenRouter

## License

MIT
