---
title: Python SDK
description: Официальный Python SDK Clipia (PyPI clipia 1.5.0) — клиенты Clipia и AsyncClipia, очередь генераций, каталог и оценка цены, проверка вебхуков и ошибки.
icon: FileCode
---

Официальный Python-клиент Clipia публикуется в PyPI как `clipia`. Он построен на `httpx`, работает на Python 3.9+ и даёт синхронный `Clipia` и асинхронный `AsyncClipia` с теми же методами. Клиент покрывает очередь генераций (`submit`, `status`, `result`), высокоуровневый `subscribe`, каталог моделей с оценкой цены и данные аккаунта.

<Callout type="info" title="Пакет">
Пакет и модуль называются `clipia`, текущая версия — 1.5.0. Базовый URL — `https://api.clipia.ai`. Переменные окружения SDK сам не читает: ключ передаётся явно в `api_key`.
</Callout>

## Быстрый старт [#quickstart]

<Steps>

<Step>

### Установка

```bash
pip install clipia
```

</Step>

<Step>

### Клиент

```python
import os
from clipia import Clipia

# Ключ берите из переменной окружения, не вписывайте его в код
clipia = Clipia(api_key=os.environ["CLIPIA_KEY"])
```

Кроме `api_key` конструктор принимает `base_url` (только `https://`), `timeout` HTTP-запросов (по умолчанию 60 секунд), `max_retries` (сколько раз `submit` повторяет временный сбой, по умолчанию 2; `0` отключает повторы), `retry_delay` (базовая пауза между повторами, по умолчанию 0.5 секунды) и `transport` — свой `httpx`-транспорт для тестов. Клиент можно использовать как контекстный менеджер (`with Clipia(...) as clipia:`) или закрыть вручную через `clipia.close()`.

</Step>

<Step>

### Генерация с ожиданием результата

`subscribe` ставит задачу в очередь и опрашивает статус, пока она не завершится:

```python
out = clipia.subscribe(
    "nano-banana-2",
    input={"prompt": "неоновый город под дождём, кинематографичный свет"},
    on_queue_update=lambda s: print(s.status),
    poll_interval=1.0,   # по умолчанию, секунды
    timeout=600.0,       # по умолчанию, секунды
)

if out.status == "COMPLETED":
    print(out.output)  # ссылки на готовые медиа
    print(out.cost)    # стоимость в кредитах
else:
    print(out.error)
```

</Step>

</Steps>

`subscribe` возвращает результат и при `FAILED`, поэтому проверяйте `status`. Кратковременные ошибки опроса (сеть, `429`, `5xx`) клиент повторяет сам. Если задача не завершилась за `timeout`, выбрасывается `ClipiaTimeoutError`; задача при этом продолжает выполняться, и её можно забрать по `request_id`.

## Ручное управление очередью [#queue]

```python
job = clipia.submit(
    "nano-banana-2",
    input={"prompt": "..."},
    webhook_url="https://example.com/clipia-webhook",  # необязательно
)

status = clipia.status(job.request_id)
result = clipia.result(job.request_id)
# result.pending == True, пока задача в IN_QUEUE или IN_PROGRESS
```

<Callout type="info" title="Ключ идемпотентности">
На каждый вызов `submit` SDK генерирует новый `Idempotency-Key` и сам повторяет временные сбои — ошибку сети, `429`, `500`, `502`, `503`, `504` — до `max_retries` раз с тем же ключом, учитывая `Retry-After`: внутренний повтор не создаст вторую задачу. Но новый вызов `submit` в вашем коде получает новый ключ. Чтобы ваш собственный повтор попал в ту же задачу, передайте `idempotency_key` и используйте его при повторе — см. [«Идемпотентность»](/ru/docs/api-reference/idempotency).
</Callout>

## Каталог, цена и аккаунт [#catalog]

```python
catalog = clipia.models.list()        # {"data": [...]}
model = clipia.models.get("nano-banana-2")

estimate = clipia.models.estimate("nano-banana-2", {"prompt": "неоновый город"})
print(estimate.credits)

account = clipia.account.get()
# {"account_id": ..., "balance": {"credits": ...}, "usage_30d": {"requests": ..., "credits_spent": ...}}
```

Каталог и аккаунт возвращаются как словари (`TypedDict`), ответы очереди и оценки — как объекты с атрибутами. В `models.list()` могут прийти LLM-модели без `slug` — см. [«Каталог моделей»](/ru/docs/api-reference/models).

## Проигнорированные параметры [#warnings]

Если в `input` есть ключ, который модель не применит (опечатка, параметр другой модели), `submit` и `models.estimate` принимают запрос как обычно, а ключ возвращают в `warnings` — по элементу на каждый. Когда все параметры приняты, список пуст.

```python
# job — ответ submit из раздела выше
for w in job.warnings:
    print(w.code, w.parameter, w.message)
    # unknown_parameter aspect_ration Parameter "aspect_ration" is not recognized and was ignored. …

# То же до запуска: оценка ничего не списывает
estimate = clipia.models.estimate("nano-banana-2", {"prompt": "..."})
print(estimate.warnings)  # [] — все параметры приняты
```

Класс `InputWarning` и атрибут `warnings` появились в версии 1.5.0. `subscribe` возвращает итог генерации, предупреждений в нём нет: чтобы их прочитать, вызывайте `submit` или `models.estimate`. Значения `code` и остальные правила — в разделе [«Проигнорированные параметры»](/ru/docs/api-reference/submit#warnings).

## Асинхронный клиент [#async]

```python
import asyncio
from clipia import AsyncClipia

async def main():
    async with AsyncClipia(api_key=os.environ["CLIPIA_KEY"]) as clipia:
        out = await clipia.subscribe("nano-banana-2", input={"prompt": "кот"})
        print(out.output)

asyncio.run(main())
```

## Проверка вебхуков [#webhooks]

```python
from clipia.webhooks import verify_signature

ok = verify_signature(
    secret=os.environ["CLIPIA_WEBHOOK_SECRET"],
    headers=request.headers,
    body=raw_body,           # сырое тело запроса, str или bytes
    tolerance_seconds=300,   # по умолчанию
)
```

Функция возвращает `True` или `False` и не выбрасывает исключений на некорректных данных. Секрет вебхуков свой у каждого API-ключа — см. [«Вебхуки»](/ru/docs/api-reference/webhooks).

## Обработка ошибок [#errors]

Любой ответ не из диапазона 2xx превращается в `ClipiaApiError` с атрибутами `status`, `code`, `type`, `message` и, если сервер прислал `Retry-After`, `retry_after` в секундах. `ClipiaTimeoutError` — его подкласс для истёкшего `timeout` в `subscribe`: `status` равен 0, `code` — `poll_timeout`, `request_id` хранит идентификатор задачи, которая продолжает выполняться.

```python
from clipia import ClipiaApiError

try:
    clipia.submit("nano-banana-2", input={"prompt": "..."})
except ClipiaApiError as e:
    print(e.status, e.code, e.type, e.message)
```

Коды ошибок — на странице [«Ошибки»](/ru/docs/api-reference/errors).

## Песочница [#sandbox]

Ключ с префиксом `clipia_test_` возвращает заготовленный результат мгновенно и без списания кредитов. Подробнее — в разделе [«Песочница»](/ru/docs/getting-started/sandbox).
