Metadata-Version: 2.4
Name: aiutils-sdk
Version: 0.2.0
Summary: Python SDK for the AiUtils Developer API — 100+ AI models via one unified API
Author-email: AiUtils Team <dev@aiutils.io>
License-Expression: MIT
Keywords: ai,llm,openai,anthropic,generation,sdk
Classifier: Development Status :: 4 - Beta
Classifier: Intended Audience :: Developers
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.9
Classifier: Programming Language :: Python :: 3.11
Requires-Python: >=3.9
Description-Content-Type: text/markdown
Requires-Dist: httpx>=0.25.0
Requires-Dist: pydantic>=2.0

# AiUtils Python SDK

Official Python SDK for the [AiUtils Developer API](https://developer.aiutils.io) — access 1400+ AI models (LLM, image, video, audio, 3D) through one unified API.

## Install

```bash
pip install aiutils-sdk
```

## Quick Start

```python
from aiutils_sdk import AiUtils

client = AiUtils(api_key="ak-dev-YOUR_KEY")

# Chat completion (OpenAI-compatible)
response = client.chat.completions.create(
    model="gen:deepseek:deepseek-v4-flash",
    messages=[{"role": "user", "content": "Explain quantum computing"}],
    max_tokens=1000,
)
print(response.choices[0].message.content)
print(f"Cost: {response.usage.dt_consumed} DT")
```

---

## Authentication

```python
client = AiUtils(
    api_key="ak-dev-YOUR_KEY",         # Required (get from developer.aiutils.io/api-keys)
    base_url="https://developer-api.aiutils.io",  # Default
    timeout=60.0,                       # Request timeout (seconds)
)
```

---

## Chat Completions

OpenAI-compatible chat completions with 90+ LLM models.

```python
response = client.chat.completions.create(
    model="gen:deepseek:deepseek-v4-flash",  # Cheapest: 1.54 DT/1M tokens
    messages=[
        {"role": "system", "content": "You are a helpful assistant."},
        {"role": "user", "content": "What is Python?"},
    ],
    temperature=0.7,
    max_tokens=1000,
    top_p=1.0,
)

print(response.choices[0].message.content)
print(f"Tokens: {response.usage.total_tokens}")
print(f"Cost: {response.usage.dt_consumed} DT")
```

### Available LLM Models

| Model ID | Label | Cost (DT/1M tokens in) |
|----------|-------|------------------------|
| `gen:deepseek:deepseek-v4-flash` | DeepSeek v4 Flash | 1.54 |
| `gen:deepseek:deepseek-chat` | DeepSeek Chat | 2.80 |
| `elidia-1:gpt-4.1-nano` | GPT 4.1 Nano | 1.12 |
| `elidia-1:gpt-4.1-mini` | GPT 4.1 Mini | 4.50 |
| `gen:deepseek:deepseek-v4-pro` | DeepSeek v4 Pro | 6.05 |
| `elidia-1:gpt-4o` | GPT 4o | 18.75 |
| `gen:anthropic:claude-opus-4-8` | Claude Opus 4.8 | 105.0 |
| `gen:openai:gpt-5.6-sol` | GPT 5.6 Sol | 75.0 |

Use `client.models.list(category="llm")` for the full up-to-date list.

---

## Image Generation

570+ image models across all vendors.

```python
# Synchronous (immediate result)
result = client.generations.create(
    model="elidia-2:flux/dev",
    parameters={"prompt": "A futuristic city at sunset, cyberpunk", "image_size": "landscape_16_9"},
)
print(result.download_urls)  # ['https://cdn.aiutils.io/...']
print(f"Cost: {result.dt_consumed} DT")
```

### Image Models (sample)

| Model ID | Label | Cost |
|----------|-------|------|
| `elidia-2:flux/dev` | FLUX.1 Dev | ~0.5 DT/megapixel |
| `elidia-2:flux-pro/v1.1-ultra` | FLUX Pro Ultra | ~1.5 DT/megapixel |
| `elidia-2:stable-diffusion-v35-large` | SD 3.5 Large | ~0.3 DT/megapixel |
| `elidia-1:midjourney` | Midjourney | via Elidia-1 |

---

## Video Generation

550+ video models. Most are **async** (take 30s-5min to complete).

```python
# With auto-polling (blocks until done)
result = client.generations.create(
    model="elidia-2:kling-video/v1.6/pro/text-to-video",
    parameters={"prompt": "A drone shot over a mountain lake at dawn"},
    wait_for_completion=True,
    timeout=300,
)
print(result.status)        # "completed"
print(result.download_urls) # ['https://cdn.aiutils.io/...mp4']

# With webhook (non-blocking, result POSTed to your URL)
result = client.generations.create(
    model="elidia-2:kling-video/v1.6/pro/text-to-video",
    parameters={"prompt": "Ocean waves crashing on rocks"},
    wait_for_completion=False,
    webhook_url="https://your-server.com/webhook/aiutils",
)
print(result.id)     # "abc123-..."
print(result.status) # "processing"
# Your webhook receives the full result when done
```

---

## Audio & Voice

140+ audio/voice/music models.

```python
# Text-to-speech
result = client.generations.create(
    model="elidia-2:playht/tts/v3",
    parameters={"text": "Hello world", "voice": "en-US-1"},
)
print(result.download_urls)

# Music generation
result = client.generations.create(
    model="elidia-1:ace-step",
    parameters={"prompt": "Upbeat electronic track, 120 BPM"},
    wait_for_completion=True,
)
```

---

## 3D Generation

48 3D models (text-to-3D, image-to-3D).

```python
result = client.generations.create(
    model="elidia-2:trellis",
    parameters={"prompt": "A medieval castle"},
    wait_for_completion=True,
    timeout=300,
)
print(result.download_urls)  # ['https://.../.glb']
```

---

## Embeddings

```python
response = client.embeddings.create(
    model="text-embedding-3-small",
    input=["Hello world", "How are you?"],
)
for emb in response.data:
    print(f"Dimension: {len(emb.embedding)}")
print(f"Tokens: {response.usage.total_tokens}")
```

---

## Model Catalog

Browse all 1400+ models with schemas and pricing.

```python
# List models by category
models = client.models.list(category="image", vendor="elidia-2", page_size=50)
for m in models.data:
    print(f"{m.id} — {m.label} ({m.pricing.credits} DT/{m.pricing.unit})")

# Get full model detail with input/output schema
detail = client.models.get("elidia-2:flux/dev")
print(detail)  # Includes input_schema, output_schema, pricing
```

### Categories

| Category | Count | Description |
|----------|-------|-------------|
| `llm` | 97 | Chat completions, reasoning, vision |
| `image` | 570 | Text-to-image, image-to-image |
| `video` | 551 | Text-to-video, image-to-video |
| `audio` | 141 | TTS, voice cloning, audio effects |
| `music` | 1 | Music generation |
| `3d` | 48 | Text-to-3D, image-to-3D |

---

## Wallet & Billing

Check balance and view transaction history.

```python
# Check balance
balance = client.wallet.balance()
print(f"Available: {balance.balance_dt} DT")
print(f"Today used: {balance.daily_dt_used} DT")

# View transaction history
txns = client.wallet.transactions(limit=10)
for t in txns.transactions:
    print(f"{t.created_at} | {t.type} | {t.amount_dt} DT | {t.description}")

# Estimate cost before running
estimate = client.wallet.estimate_cost(
    model="gen:deepseek:deepseek-v4-flash",
    parameters={"max_tokens": 2000},
)
print(f"Estimated cost: {estimate.estimated_dt} DT (${estimate.estimated_usd:.4f})")
```

---

## Webhooks

Configure global webhook to receive all async results, or use per-request webhooks.

### Global Webhook (account-level)

```python
# Set global webhook — all async completions delivered here
client.webhooks.set_config(
    url="https://your-server.com/webhook/aiutils",
    events=["generation.completed", "generation.failed", "balance.low"],
    secret="whsec_your_signing_secret",  # For signature verification
)

# Check current config
config = client.webhooks.get_config()
print(f"Active: {config.is_active}, URL: {config.url}")

# View delivery history (for debugging)
deliveries = client.webhooks.list_deliveries(limit=10)
for d in deliveries.deliveries:
    print(f"{d.created_at} | {d.event} | {d.status} | HTTP {d.response_code}")

# Remove webhook
client.webhooks.delete_config()
```

### Per-Request Webhook

```python
# Override global webhook for this specific request
result = client.generations.create(
    model="elidia-2:kling-video/v1.6/pro/text-to-video",
    parameters={"prompt": "A cat playing piano"},
    wait_for_completion=False,
    webhook_url="https://your-server.com/webhook/this-specific-job",
)
```

### Webhook Payload

Your webhook endpoint receives a POST with:

```json
{
    "event": "generation.completed",
    "generation_id": "abc123-...",
    "status": "completed",
    "model": "elidia-2:flux/dev",
    "output": { ... },
    "download_urls": ["https://cdn.aiutils.io/..."],
    "dt_consumed": 5,
    "created_at": 1721234567.89
}
```

Headers include `X-Webhook-Signature` (HMAC-SHA256 of body using your secret).

---

## Cost Estimation

Estimate cost BEFORE running any request.

```python
# Estimate chat cost
estimate = client.wallet.estimate_cost(
    model="gen:deepseek:deepseek-v4-flash",
    parameters={"max_tokens": 4000},
)
print(f"~{estimate.estimated_dt} DT (${estimate.estimated_usd:.4f})")
print(f"Provider: ${estimate.breakdown['provider_cost_usd']:.4f}")
print(f"Platform fee: {estimate.breakdown['platform_fee_pct']}%")

# Estimate generation cost
estimate = client.wallet.estimate_cost(
    model="elidia-2:flux/dev",
    parameters={"image_size": "landscape_16_9"},
)
```

---

## Error Handling

```python
from aiutils_sdk import (
    AiUtils, AuthenticationError, InsufficientDTError,
    RateLimitError, APIError, ProviderError,
)

try:
    response = client.chat.completions.create(...)
except AuthenticationError:
    print("Invalid API key — check developer.aiutils.io/api-keys")
except InsufficientDTError:
    print("Not enough DT — top up at developer.aiutils.io/billing")
except RateLimitError:
    print("Too many requests — back off and retry")
except APIError as e:
    print(f"API error ({e.status_code}): {e}")
except ProviderError:
    print("AI provider error — retry")
```

---

## Pricing

All usage is billed in **DT (Developer Tokens)**: `1 DT = $0.001 USD`.

Cost formula: `DT = CEIL(provider_cost_usd * 1.08 * 1000)`

The 8% platform fee is the only markup — no hidden costs.

| Tier | Input (DT/1M tokens) | Output (DT/1M tokens) |
|------|---------------------|----------------------|
| Budget (DeepSeek Flash) | 1.54 | 3.08 |
| Standard (GPT-4o-mini) | 1.69 | 6.75 |
| Premium (Claude Opus) | 105 | 450 |

For media models, costs vary per model — use `client.wallet.estimate_cost()` or check `model.pricing` in the catalog.

---

## Context Manager

```python
with AiUtils(api_key="ak-dev-YOUR_KEY") as client:
    response = client.chat.completions.create(...)
# HTTP connections cleaned up automatically
```

---

## Links

- [Developer Console](https://developer.aiutils.io)
- [API Keys](https://developer.aiutils.io/api-keys)
- [Playground](https://developer.aiutils.io/playground)
- [Model Catalog](https://developer.aiutils.io/models)
- [Billing & Top Up](https://developer.aiutils.io/billing)
