# RunBlob Python SDK

Official async Python SDK for the [RunBlob](https://runblob.com) AI generation platform.

Currently supported: **Nano Banana (Gemini)** image generation. More models coming in future updates — Kling, Sora, Veo and others.

For pricing, available models and API documentation visit [runblob.com](https://runblob.com).

## Install

```bash
pip install runblob
```

## Quick Start

```python
import asyncio
from runblob import RunBlob

async def main():
    async with RunBlob(api_key="sk-...") as client:
        result = await client.nanobanana.generate_and_wait(
            prompt="A cute orange cat on a windowsill",
            model="pro",
            quality="4k",
        )
        print(result.result_image_url)

asyncio.run(main())
```

## Generate and poll separately

```python
async with RunBlob(api_key="sk-...") as client:
    task = await client.nanobanana.generate(prompt="A sunset over the ocean")
    print(task.task_uuid)
    print(task.price)

    status = await client.nanobanana.get_status(task.task_uuid)
    print(status.status)

    result = await client.nanobanana.wait_for_result(task.task_uuid)
    print(result.result_image_url)
```

## Batch generation

```python
async with RunBlob(api_key="sk-...") as client:
    results = await client.nanobanana.generate_batch_and_wait(
        prompts=[
            "A red apple on a white table",
            "A mountain peak covered in snow",
            "An anime girl with blue hair",
        ],
        model="standard",
        concurrency=5,
    )
    for r in results:
        print(r.result_image_url)
```

## Webhooks

```python
async with RunBlob(api_key="sk-...") as client:
    await client.nanobanana.generate(
        prompt="A forest at dawn",
        callback_url="https://your-server.com/webhook",
    )
```

```python
from runblob import parse_webhook_payload, verify_webhook_signature

event = parse_webhook_payload(request_body)
if event.is_completed:
    print(event.result_image_url)
```

## Error handling

```python
from runblob import RunBlob, AuthenticationError, RateLimitError, RunBlobError

async with RunBlob(api_key="sk-...") as client:
    try:
        result = await client.nanobanana.generate(prompt="test")
    except AuthenticationError:
        print("Invalid API key")
    except RateLimitError as e:
        print(f"Rate limited, retry after {e.retry_after}s")
    except RunBlobError as e:
        print(f"SDK error: {e}")
```

## Configuration

```python
client = RunBlob(
    api_key="sk-...",
    max_connections=200,
    rate_limit_rps=100.0,
    max_retries=5,
    timeout=60.0,
    circuit_breaker_threshold=10,
)
```

## Requirements

- Python 3.10+
- [runblob.com](https://runblob.com) API key
