# API Wan 3.0: текст в видео и изображение в видео на Python

> Вызов Wan 3.0 из Python: скрипт от 31 октября 2026 г. для текста в видео и изображения в видео, параметры, реальные клипы, ошибки и цена Alibaba.

- Canonical HTML: https://omniakey.com/ru/blog/wan-3-0-api
- Markdown: https://omniakey.com/ru/blog/wan-3-0-api.md
- Published: 2026-10-31 (updated 2026-10-31)
- Author: Kiki, COO at OmniaKey
- Language: ru
- Category: API setup
- Reading time: 8 min
- All posts: https://omniakey.com/blog/llms.txt

---

[Wan 3.0](https://omniakey.com/ru/wan3-0-video) работает в Alibaba Cloud Model Studio под идентификатором `wan3.0-video` и под более быстрым `wan3.0-video-prime`. Каждый вызов асинхронный: создать задачу, опросить ID, скачать MP4. Наш скрипт на Python сделал 5-секундный клип 720P из текста за 2 min 42 s и клип из кадра за 3 min 20 s, оба со звуком.

1. Положите ключ в `OMNIAKEY_API_KEY`.
2. Отправьте POST на `https://api.omniakey.com/v1/media/tasks` с моделью, операцией, промптом, параметрами и новым `Idempotency-Key`.
3. Опрашивайте `GET /v1/media/tasks/{id}`, пока статус не станет succeeded, затем сразу скачайте `assets[0].url`.

## Есть ли официальный API Wan 3.0 и какую модель выбрать?

Да. Alibaba Cloud Model Studio — официальный API, в нём есть `wan3.0-video` и `wan3.0-video-prime` (справка обновлена 15 октября 2026 г.). Вызов создания требует заголовка `X-DashScope-Async: enable`, а путь Python у Alibaba — SDK DashScope 2.0.1 или новее.

||Alibaba Model Studio|OmniaKey|
|-|-|-|
|Оба ID модели|Есть|Есть|
|Заголовок async|Нужен|Не нужен|
|Ссылка на видео|24 часа|Около 1 часа, продлевается|
|Оплата|За секунду|За секунду|
|Python|SDK DashScope|Стандартная библиотека|

Оба ID принимают одно тело запроса, и модель выбирает режим по присланным медиа. Скрипт ниже запускает `wan3.0-video`, переключает его строка `MODEL`. [Wan 3.0 Prime](https://omniakey.com/ru/wan3-0-video-prime) мы не запускали: документация OmniaKey описывает его как те же возможности примерно за половину времени (проверено 31 октября 2026 г.).

## Что нужно до первого вызова?

Три вещи, и первая — ключ:

1. Ключ API OmniaKey, экспортированный в оболочке:

   ```bash
   export OMNIAKEY_API_KEY="your-key"
   ```

2. Python 3. Скрипт использует только стандартную библиотеку, поэтому python3 запускает его как есть.

3. Для изображения в видео нужен первый кадр: JPEG шириной около 1024 px или публичный HTTPS-URL. Скрипт не принимает файл больше 700 000 байт, потому что Base64 добавляет треть, а тело ограничено 1 MiB (документация, проверено 31 октября 2026 г.).

## Какие параметры важны?

Семь полей делают основную работу, и каждое — значение внутри `parameters`.

|Параметр|Что делает|По умолчанию|
|-|-|-|
|Длительность|Длина клипа, секунды|5|
|Разрешение|Уровень размера кадра|1080P|
|Пропорции|Форма кадра|adaptive|
|Звук|Звуковая дорожка|on|
|Seed|Подсказка для повтора|-1|
|Расширение промпта|Переписывает промпт|on|
|Водяной знак|Ставит метку в углу|off|

Скрипт задаёт длительность, разрешение и пропорции. Он просит 720P, тогда как по умолчанию у Alibaba 1080P, что по прайс-листу стоит вдвое дороже за секунду.

## Как выглядит код на Python?

Скрипт ниже отработал без изменений 31 октября 2026 г.: только стандартная библиотека, оба режима, одна строка MODEL для переключения.

```python
import base64
import json
import os
import time
import urllib.error
import urllib.request
import uuid

API = "https://api.omniakey.com/v1/media/tasks"
KEY = os.environ["OMNIAKEY_API_KEY"]
MODEL = "wan3.0-video"

def request(method, url, body=None, extra_headers=None):
    headers = {"Authorization": f"Bearer {KEY}", "User-Agent": "omniakey-example/1"}
    data = None
    if body is not None:
        headers["Content-Type"] = "application/json"
        data = json.dumps(body).encode()
    headers.update(extra_headers or {})
    req = urllib.request.Request(url, data=data, headers=headers, method=method)
    with urllib.request.urlopen(req, timeout=120) as resp:
        return json.load(resp)

def poll(url, attempts=5):
    for attempt in range(attempts):
        try:
            return request("GET", url)
        except urllib.error.HTTPError as err:
            if err.code < 500 or attempt == attempts - 1:
                raise
        except urllib.error.URLError:
            if attempt == attempts - 1:
                raise
        time.sleep(5 * (attempt + 1))

def run_task(body, out_path):
    task = request("POST", API, body, {"Idempotency-Key": str(uuid.uuid4())})["id"]
    print("task", task, flush=True)
    for _ in range(180):  # 5-second polls, up to 15 minutes
        time.sleep(5)
        state = poll(f"{API}/{task}")
        if state["status"] not in ("queued", "processing"):
            break
    else:
        raise TimeoutError(f"{task} is still {state['status']}: poll it again later, do not resubmit")
    if state["status"] != "succeeded":
        raise RuntimeError(state.get("error") or state["status"])
    asset_url = state["assets"][0]["url"]  # signed link: short-lived, so download now
    req = urllib.request.Request(asset_url, headers={"User-Agent": "omniakey-example/1"})
    with urllib.request.urlopen(req, timeout=300) as resp, open(out_path, "wb") as f:
        f.write(resp.read())
    return task

def text_to_video(prompt, out_path, duration=5, resolution="720P", ratio="16:9"):
    body = {
        "model": MODEL,
        "type": "video",
        "operation": "text_to_video",
        "input": {"prompt": prompt},
        "parameters": {"duration": duration, "resolution": resolution, "ratio": ratio},
    }
    return run_task(body, out_path)

def image_to_video(prompt, image_path, out_path, duration=5, resolution="720P"):
    with open(image_path, "rb") as f:
        raw = f.read()
    if len(raw) > 700_000:  # base64 adds a third, and the whole body must stay under 1 MiB
        raise ValueError("first frame too large: save it as a JPEG about 1024 px wide")
    frame = "data:image/jpeg;base64," + base64.b64encode(raw).decode()
    body = {
        "model": MODEL,
        "type": "video",
        "operation": "image_to_video",
        "input": {"prompt": prompt, "media": [{"type": "first_frame", "url": frame}]},
        "parameters": {"duration": duration, "resolution": resolution, "ratio": "adaptive"},
    }
    return run_task(body, out_path)

if __name__ == "__main__":
    print("done", text_to_video(
        "A blacksmith hammers a glowing horseshoe on an anvil in a dark forge. Sparks fly at each "
        "strike and light his leather apron. The camera slowly pushes in. Sound of the hammer ringing "
        "on steel and the fire crackling. No dialogue, no music, no text.",
        "forge.mp4",
    ))
    print("done", image_to_video(
        "Image 1 is the first frame. The paper boat drifts slowly to the right across the puddle. "
        "Light rain makes small ripples and the cafe lights shimmer in the water. The camera stays "
        "low and still. Sound of light rain. No dialogue, no music, no text.",
        "boat.jpg",
        "boat-drifts.mp4",
    ))
```

Что делает каждая часть:

- `run_task` создаёт новый `Idempotency-Key` для каждой задачи. Повторная отправка того же ключа с тем же телом возвращает исходную задачу и никогда не списывает деньги дважды (документация, проверено 31 октября 2026 г.).
- Он опрашивает каждые 5 секунд, максимум 15 минут, и затем поднимает TimeoutError.
- Таймаут значит: опросить тот же ID позже; повторная отправка создаёт новый ключ, вторую задачу и второй счёт.
- Он сразу скачивает первый URL ресурса, потому что подписанная ссылка живёт недолго.
- `image_to_video` не принимает кадр больше 700 000 байт: Base64 добавляет треть, а тело ограничено 1 MiB.
- Вызов изображения ставит пропорции `adaptive`, поэтому клип повторяет форму кадра.

Что он вывел:

```text
task task_<id>
done task_<id>
task task_<id>
done task_<id>
```

## Что получилось из двух вызовов?

Оба файла вернулись как MP4 длиной 5,04 секунды, 150 кадров при 30 fps, H.264, со стереодорожкой AAC при 44,1 kHz.

### Текст в видео: кузница

![Четыре кадра из клипа кузницы Wan 3.0](https://omniakey.com/_img/blog/wan-3-0-api/wan-forge-grid.4c1b058b.1288.webp)

_Текст в видео, 5 s при 720P: кадры на 0,3, 2,2, 3,5 и 4,7 секунды._

Клип следует промпту: кузнец в тёмной рубахе и кожаном фартуке бьёт молотом по раскалённой оранжевой подкове, на 2,2 секунды летят искры, и камера немного наезжает. Недостаток — выштампованное клеймо мастера неразборчивыми буквами на наковальне, хотя промпт просил без текста. От запуска до файла прошло 2 min 42 s; MP4 весит 6,6 МБ при 1280×720.

### Изображение в видео: бумажный кораблик

![Исходный кадр и три кадра из клипа с бумажным корабликом Wan 3.0](https://omniakey.com/_img/blog/wan-3-0-api/wan-paper-boat-grid.e2ffd154.1288.webp)

_Изображение в видео: отправленный кадр (слева вверху), затем клип на 1,6, 3,5 и 4,7 секунды._

Первый кадр — изображение, сделанное в Nano Banana 2.1: красный бумажный кораблик в дождевой луже; его уменьшили до JPEG 1024×571 весом 158 КБ и отправили встроенным как data URL. Клип сохраняет сумеречный свет и мокрую брусчатку, ведёт кораблик слева направо, как просили, даёт круги на воде на 1,6 секунды и держит камеру низко и неподвижно. Вернулся он как 1284×716, потому что adaptive повторил форму кадра, за 3 min 20 s при 7,4 МБ.

### Звук включён, и работает ли "no music"?

Звук включён по умолчанию. Gemini 3.8 Flash описал дорожку кузницы как металлический звон без речи и без музыки, а дорожку кораблика — как меланхоличную спокойную фортепианную мелодию, хотя этот промпт заканчивался на "no music". [Гайд по промптам](https://www.alibabacloud.com/help/en/model-studio/wan3-video-generation-prompt-guide) Alibaba (обновлён 16 октября 2026 г.) советует писать "No BGM" или "No background music", а в нашем промпте не было ни того, ни другого.

С `"audio": false` файл несёт только видеодорожку: наша 2-секундная задача 480P с фонарём пришла без звуковой дорожки, и Alibaba считает одинаково в обоих случаях.

|Клип|Время|Размер|Звук|
|-|-|-|-|
|Кузница (текст)|2 min 42 s|1280×720|Звон, без музыки|
|Кораблик (кадр)|3 min 20 s|1284×716|Фортепиано вопреки "no music"|
|Фонарь, звук выкл.|4 min 36 s|854×480|Без звуковой дорожки|

Время в очереди меняется: задача на 2 секунды без звука заняла 4 min 36 s, дольше любого 5-секундного клипа 720P. Для формулировок промптов в [гайде по промптам Wan 3.0](https://omniakey.com/ru/blog/wan-3-0-prompt-guide) есть структура и примеры.

## Как забрать видеофайл и сколько живут ссылки?

Опрашивайте `GET /v1/media/tasks/{id}`, пока статус не станет succeeded, failed или canceled; пока задача идёт, там queued или processing. Завершённая задача возвращает подписанный URL ресурса, который живёт около часа (документация OmniaKey, проверено 31 октября 2026 г.). Скачайте его сразу, а когда старая ссылка истечёт, опросите задачу снова ради свежей, потому что запись хранится 24 часа.

Файл — это MP4 с видео H.264 при 30 fps, а собственный URL видео у Alibaba живёт 24 часа. Отмена задачи Wan 3.0 не останавливает рендер, и задача, которая успешно завершилась после отмены, всё равно оплачивается, поэтому проверьте длительность и разрешение до отправки.

## Какие ошибки вы увидите?

Большинство из них приходят раньше, чем появляется задача, и у каждой есть исправление в запросе или в ключе.

- **400 `model_price_error`** — длительность вне 2–30 секунд. Наша проверка с `"duration": 1` упала за 0,9 s с "media duration must be between 2 and 30 seconds"; задача не создалась, и деньги не списались.
- **400 `missing_idempotency_key`** — нет заголовка Idempotency-Key. Добавьте его, до 255 символов.
- **409 `idempotency_key_reused`** — тот же ключ, другое тело. Создавайте новый ключ для каждого промпта.
- **403 `model_not_allowed`** — ключ не может вызывать эту модель. Проверьте значение `model`, затем настройки ключа.
- **403 с сообщением о балансе или лимите расходов** — мало средств или лимит на ключ. Пополните баланс или поднимите лимит.
- **404 `task_not_found`** — неверный ID или задача старше 24 часов. Опросите ID, который вернул вызов создания.
- **409 `task_state_conflict`** — задача уже завершилась, например когда отмена приходит после успеха. Сначала прочитайте статус.
- **429** — слишком много запросов. OmniaKey не публикует фиксированные лимиты, поэтому ждите с экспоненциальной задержкой и джиттером.
- **503 `no_available_channel`** — нет канала для этой операции, например видео в видео. Используйте текст в видео или изображение в видео.
- **`TimeoutError`** — всё ещё идёт после 15 минут. Опросите тот же ID позже; повторная отправка создаст вторую задачу и второй счёт.

## Сколько стоит клип Wan 3.0?

Alibaba берёт плату за секунду видео, а неудачный запрос не оплачивается (страница цен обновлена 29 октября 2026 г.). В таблице — прайс-лист Alibaba за секунду для Сингапура, проверенный 31 октября 2026 г., по [странице цен Alibaba для Model Studio](https://www.alibabacloud.com/help/en/model-studio/model-pricing).

|Модель|480P|720P|1080P|
|-|-|-|-|
|Wan 3.0|$0.05|$0.1|$0.2|
|Wan 3.0 Prime|$0.068|$0.14|$0.28|

5-секундный клип 720P стоит у Alibaba $0.50 на Wan 3.0 (5 × $0.1) и $0.70 на Prime (5 × $0.14). У трёх цен Wan 3.0 стоит пометка "Limited-time 30% off", и страница не говорит, включена ли она в цифры. Звук включён или выключен — цена та же.

Бесплатная квота Alibaba — 30 секунд видео, вход плюс выход, на `wan3.0-video` в Сингапуре; у Prime её нет. У Alibaba в Китае (Пекин) для стандартной модели долларовые ставки ниже: $0.041256, $0.082513 и $0.165025 за секунду при 480P, 720P и 1080P.

OmniaKey тоже берёт плату за секунду, актуальные ставки — на страницах моделей [Wan 3.0](https://omniakey.com/ru/wan3-0-video) и [Wan 3.0 Prime](https://omniakey.com/ru/wan3-0-video-prime).

## Частые вопросы

### Сколько идёт один вызов?

Alibaba пишет, что задача обычно занимает от 1 до 5 минут, и советует опрашивать каждые 15 секунд (справка, проверено 31 октября 2026 г.). Наши три задачи заняли 2 min 42 s, 3 min 20 s и 4 min 36 s.

### Как выключить звук?

Поставьте `"audio": false` внутри `parameters`, и MP4 придёт только с видеодорожкой, как наша задача с фонарём. Цена не меняется.

### wan3.0-video или wan3.0-video-prime?

Берите `wan3.0-video` ради более низкой ставки Alibaba и бесплатной квоты 30 секунд в Сингапуре, а Prime — когда важнее время. OmniaKey описывает Prime как те же возможности примерно за половину времени.

### Сколько живёт ссылка на видео?

Около часа на OmniaKey, и повторный опрос задачи вернёт свежую ссылку, пока запись хранится 24 часа. Собственный URL видео у Alibaba живёт 24 часа.

## Проверенные источники

- [Справка API генерации видео Wan 3.0](https://www.alibabacloud.com/help/en/model-studio/wan3-video-generation-api-reference), проверено 31 октября 2026 г.
- [Руководство по генерации видео Wan 3.0](https://www.alibabacloud.com/help/en/model-studio/wan3-video-generation-guide), проверено 31 октября 2026 г.
- [Гайд по промптам для генерации видео Wan 3.0](https://www.alibabacloud.com/help/en/model-studio/wan3-video-generation-prompt-guide), проверено 31 октября 2026 г.
- [Цены моделей Alibaba Cloud Model Studio](https://www.alibabacloud.com/help/en/model-studio/model-pricing), проверено 31 октября 2026 г.
- [Документация видео API OmniaKey](https://docs.omniakey.com/en/media/video), проверено 31 октября 2026 г.
- [Обзор media API OmniaKey](https://docs.omniakey.com/en/media/overview), проверено 31 октября 2026 г.
- [Коды ошибок API OmniaKey](https://docs.omniakey.com/en/api/errors), проверено 31 октября 2026 г.
