Руководство
Как вызывать flux-3-max/text-to-video через HiAPI API: руководство по curl и Python
Практическое интеграционное упражнение по отправке асинхронных запросов текст-в-видео на HiAPI
Возможности и сценарии применения flux-3-max/text-to-video
flux-3-max/text-to-video — это эндпоинт текст-в-видео на HiAPI: вы отправляете промпт с описанием сцены, а модель возвращает сгенерированный видеоклип. Это подходящий инструмент, когда у вас есть текстовая идея, а не готовый материал — например, трейлер продукта, короткое видео для соцсетей, раскадровка-превью или массово генерируемые пустые кадры — и вы хотите, чтобы генерация выполнялась как управляемая задача, а не запускалась вами самостоятельно.
Он подходит для рабочих процессов, где видео — лишь один из этапов более крупного конвейера. Генератор сценариев создаёт промпты, flux-3-max/text-to-video превращает их в видеоклипы, а ваше приложение отвечает за хранение или доставку результатов. Поскольку вызов асинхронный, он также подходит для бэкенд-сервисов, которые не могут держать запрос открытым на всё время рендеринга.
Не используйте его, когда нужна покадровая точность редактирования существующего видео или когда ваш промпт на самом деле является лишь статичным изображением — для последнего эндпоинт текст-в-изображение дешевле и быстрее. Если выходные данные должны реагировать на предоставленный материал, следует использовать вариант изображение-в-видео. Рассматривайте flux-3-max/text-to-video как точку входа для генерации видеоклипов из промптов и проектируйте интеграцию вокруг отправки задач, а не синхронных ответов.
Структура запроса: эндпоинт, аутентификация и нагрузка
Каждый запрос к flux-3-max/text-to-video состоит из трёх частей: пути эндпоинта, заголовка аутентификации и JSON-тела запроса, указывающего модель и её входные данные.
Аутентификация
HiAPI использует bearer-токены. Поместите ваш API-ключ в заголовок Authorization:
Authorization: Bearer $HIAPI_API_KEY
Content-Type: application/json
Храните ключ на стороне сервера. Не встраивайте его в клиентский код и не коммитьте в репозиторий; при разработке загружайте из переменных окружения, а в продакшене — из менеджера секретов.
Идентификатор модели
В теле запроса поле model выбирает эндпоинт. Используйте точный идентификатор flux-3-max/text-to-video; опечатка здесь — самая частая причина отклонения запроса.
Структура нагрузки
Минимальное тело запроса содержит имя модели и промпт:
{
"model": "flux-3-max/text-to-video",
"prompt": "日出时分,薄雾笼罩的松林上空缓缓航拍,电影级光影"
}
Необязательные поля — длительность и переключатель нативного аудио — описаны в следующем разделе. Поскольку генерация асинхронная, немедленный ответ на этот POST-запрос — это объект задачи с идентификатором, который нужно опрашивать, а не готовое видео. Проектируйте код так, чтобы сначала считывать этот идентификатор, а остальное — во вторую очередь.
Управление длительностью и нативным аудио
Два параметра уровня запроса определяют результат: длительность видеоклипа и то, генерирует ли модель аудио вместе с видео.
Длительность
Задайте длину клипа в нагрузке через поле duration. Выбирайте минимальную длительность, достаточную для повествования — короткие клипы рендерятся быстрее, их проще проверять, и вы всегда можете запросить ещё один. Перед отправкой проверьте значение по диапазону, указанному в документации flux-3-max/text-to-video; значения вне диапазона отклоняются при отправке, и локальный отлов этой проблемы экономит один сетевой обмен.
Нативное аудио
Переключатель нативного аудио определяет, генерирует ли модель звуковую дорожку вместе с клипом. Включайте, когда видео будет смотреться со звуком, и выключайте, когда видео будет без звука, с субтитрами или с отдельной музыкой на постпродакшене. Генерация аудио, которое вы отбросите, лишь увеличивает время задачи без всякой пользы.
Осознанный выбор
Не позволяйте значениям по умолчанию решать за вас. Для быстрой проверки раскадровки обычно достаточно короткого клипа без звука. Для финального материала для соцсетей целью может быть более длинный клип с нативным аудио. Зафиксируйте этот выбор в конфигурации приложения, а не хардкодьте в месте вызова, чтобы можно было менять его по функциям без правки кода запросов. Отправляйте только те поля, которые действительно хотите переопределить, а остальным позволяйте эндпоинту применить значения по умолчанию.
Рабочий запрос curl
Самый быстрый способ проверить учётные данные и нагрузку — отправить задачу одним вызовом curl.
curl -X POST "$HIAPI_BASE_URL/v1/videos/generations" \
-H "Authorization: Bearer $HIAPI_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "flux-3-max/text-to-video",
"prompt": "一只纸船漂过被雨水浸湿的街道,温暖的街灯,浅景深",
"duration": 5,
"native_audio": false
}'
Сначала установите HIAPI_BASE_URL и HIAPI_API_KEY в оболочке. Значения длительности и аудио здесь приведены только для примера — используйте значения в диапазоне, указанном в документации модели.
Чтение немедленного ответа
Ответ — это объект задачи, а не видео. Он содержит job_id (или эквивалентный идентификатор) и статус вроде queued или processing. Сохраните этот идентификатор; это ваш дескриптор для всех последующих вызовов. Если ответ выглядит как объект ошибки, проверьте код статуса и сообщение перед повторной попыткой — некорректная нагрузка будет падать одинаково каждый раз.
Успешная отправка означает лишь то, что задача принята, и ничего более. Не пытайтесь искать URL видео в первом ответе; он не появится там до завершения задачи.
Жизненный цикл асинхронной задачи
Генерация видео занимает от секунд до минут, поэтому HiAPI моделирует её как задачу. Ваш клиент отправляет её один раз, а затем проверяет статус, пока задача не достигнет терминального состояния.
Статусы
Задача проходит путь от queued к processing и затем к терминальному состоянию — completed или failed. Только терминальное состояние является окончательным; любое промежуточное означает, что нужно продолжать ждать.
Опрос без бомбардировки
Опрашивайте эндпоинт статуса, используя сохранённый идентификатор задачи. Два правила сохраняют опрос здоровым:
- Ждите между опросами. Начинайте с короткого интервала и постепенно увеличивайте его, либо используйте фиксированный интервал, явно превышающий типичное время в очереди. Бомбардировка эндпоинта статуса ничего не даёт.
- Задайте ограничения. Ограничьте общее время ожидания и общее число попыток. Если к тому моменту задача не завершена, сообщите об этом вашему приложению, а не зацикливайтесь бесконечно.
В веб-обработчике не блокируйте поток запроса на цикле опроса. Отправьте задачу, сохраните её идентификатор, сразу вернитесь, а завершение жизненного цикла пусть отслеживает фоновый рабочий поток или клиент. В пакетных сценариях достаточно простого цикла с sleep.
Чтение результата
Когда задача сообщает о completed, ответ несёт ссылку на выходные данные — URL видео или дескриптор материала, который ваше приложение может скачать или передать потоком. При неудаче прочитайте поле error; оно обычно указывает причину (неверные параметры, отказ по контенту, внутренняя ошибка). Записывайте идентификатор задачи вместе с сообщением об ошибке, чтобы запрос в поддержку или повторная попытка были обоснованы. Никогда не считайте отсутствующее поле вывода успехом — явно проверяйте статус.
Тот же запрос на Python
Процесс curl напрямую переносится на Python. Минимальному клиенту нужны отправка, цикл опроса и достаточная обработка ошибок, чтобы отличать неверный запрос от медленной задачи.
import os, time
import requests
BASE = os.environ["HIAPI_BASE_URL"]
API_KEY = os.environ["HIAPI_API_KEY"]
HEADERS = {
"Authorization": f"Bearer {API_KEY}",
"Content-Type": "application/json",
}
def submit(prompt, duration=5, native_audio=False):
body = {
"model": "flux-3-max/text-to-video",
"prompt": prompt,
"duration": duration,
"native_audio": native_audio,
}
resp = requests.post(f"{BASE}/v1/videos/generations",
headers=HEADERS, json=body, timeout=30)
resp.raise_for_status()
return resp.json()["job_id"]
def wait(job_id, interval=5, max_attempts=60):
for attempt in range(max_attempts):
time.sleep(interval)
r = requests.get(f"{BASE}/v1/videos/generations/{job_id}",
headers=HEADERS, timeout=30)
r.raise_for_status()
data = r.json()
status = data.get("status")
if status == "completed":
return data
if status == "failed":
raise RuntimeError(data.get("error", "job failed"))
raise TimeoutError(f"job {job_id} did not finish in time")
Замечания по реализации
raise_for_status() отделяет транспортные и HTTP-ошибки (аутентификация, некорректная нагрузка) от ошибок уровня задачи, которые появляются внутри успешного ответа. Проверка failed явно читает поле error, а не предполагает статус completed. Ограничение числа попыток превращает неограниченное ожидание в предсказуемое исключение.
В продакшене оберните опрос в политику Retry для транзитных сетевых ошибок и переиспользуйте один requests.Session. Если вы запускаете много задач, перенесите wait в рабочий поток, а не в путь запроса.
Устранение типичных сбоев
Большинство проблем интеграции сводится к нескольким категориям. У каждой есть конкретный способ проверки.
Ошибки аутентификации
401 или 403 означают, что ключ отсутствует, истёк или имеет неверный формат. Убедитесь, что заголовок Authorization присутствует, использует схему Bearer, а переменные окружения действительно заполнены в среде выполнения — а не только в вашей оболочке.
Некорректная нагрузка
400 обычно означает, что тело запроса не соответствует схеме. Проверьте, что JSON разбирается, model в точности равно flux-3-max/text-to-video, а запрос отправляет Content-Type: application/json. Используйте сериализацию библиотекой JSON, а не ручную сборку строк.
Неверные значения параметров
Длительность вне диапазона документации, неизвестное имя поля или неверный тип переключателя аудио приводят к отклонению при отправке. Проверяйте локально по параметрам документации модели перед отправкой.
Преждевременный опрос
Немедленный и повторяющийся опрос после отправки не заставит задачу завершиться быстрее. Используйте экспоненциальную паузу или фиксированный интервал и позвольте объекту задачи сообщить, когда он вышел из состояния queued.
Необработанные сбои задач
Задача, достигшая failed, не обязательно означает баг в вашем запросе — это может быть отказ по контенту или внутренняя ошибка. Прочитайте сообщение об ошибке, запишите идентификатор задачи и решите, повторять ли с изменённым промптом или эскалировать.
Восприятие ответа отправки как результата
Если ваш код ожидает URL видео сразу после отправки, он сломается. Первый ответ — это задача; только терминальное состояние несёт выходные данные. Как только эти шесть проверок на месте, большинство проблем интеграции решается.
Похожие статьи
Все статьи →-
Руководство
Как вызвать hailuo-2.3-fast/image-to-video через HiAPI API: практика с curl и Python
Первый рабочий запрос к быстрому и недорогому уровню генерации видео по изображению — от ID модели до загрузки MP4
-
Руководство
Как вызывать hailuo-2.3/text-to-video через API HiAPI: curl, Python и рабочие примеры запросов
-
Руководство
Использование Kandinsky 6.0 Pro для преобразования текста в видео на HiAPI: руководство по curl и Python
Практическая демонстрация с упором на запросы: построение вызова от промпта до видеоклипа, отправка запроса, опрос статуса завершения и скачивание результата