Руководство
Как вызывать seedream-5.0-lite/text-to-image через HiAPI API: руководство по curl и Python
Практическое упражнение с рабочими запросами для разработчиков: интеграция текст-в-изображение через HiAPI
Что на самом деле делает эта интеграция
Вызов текст-в-изображение на HiAPI — это короткий диалог между вашим кодом и асинхронной очередью задач. Вы отправляете запрос с описанием нужного изображения; платформа проверяет запрос, принимает задачу и возвращает идентификатор. Изображения в первом ответе нет — оно генерируется позже. Затем ваш код отслеживает задачу, пока она не сообщит о завершении, и наконец скачивает изображение по URL, который предоставляет задача.
Эта форма важна, потому что она определяет, как вы пишете интеграцию. Есть три разных момента: отправка, опрос и получение. У каждого свои режимы отказа. Отправка завершается ошибкой при некорректном формате полезной нагрузки или неверном пути модели. Опрос завершается ошибкой при неправильно написанном цикле — слишком быстром, слишком коротком или не различающем «всё ещё выполняется» и «завершено». Получение завершается ошибкой, если вы считаете выходной URL постоянным адресом или забываете записать байты на диск.
В своей основе seedream-5.0-lite/text-to-image — это универсальная модель текст-в-изображение на платформе HiAPI. Вы вызываете её по этому точному идентификатору модели. Параметры, которые вы отправляете, — это обычные параметры такого вызова: имя модели, промпт и любые параметры управления размером или количеством выходных данных, описанные в документации эндпоинта. Вам не нужен специальный SDK; достаточно обычного HTTPS-клиента.
Прочитав это руководство, вы получите запрос, воспроизводимый через curl, функцию Python вокруг него, приём формулировки промптов, чтобы отрисованный текст был чётким и читаемым, и цикл опроса, который действительно завершается. Всё работает через один и тот же эндпоинт HiAPI, поэтому как только один вызов сработает, останется только настройка параметров.
Составление запроса с помощью curl
Начните с командной строки. Рабочий вызов curl — это эталон полезной нагрузки: как только он сработает, любой другой язык — лишь упражнение в переводе.
Перед первым вызовом вам понадобятся две вещи: ваш API-ключ HiAPI и базовый URL API. Ключ передаётся как bearer-токен в заголовке Authorization. По возможности не допускайте его попадания в историю оболочки; переменная окружения — самая простая привычка.
export HIAPI_API_KEY="your_api_key_here"
Сам запрос — это POST с JSON-телом. Идентификатор модели — это сегмент пути, который вы вызываете, а промпт описывает изображение:
curl -sS -X POST "$HIAPI_BASE_URL" \
-H "Authorization: Bearer $HIAPI_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "seedream-5.0-lite/text-to-image",
"prompt": "A minimalist poster for a coffee shop called North Roast, warm cream background, bold dark lettering"
}'
Установите HIAPI_BASE_URL в значение эндпоинта отправки текст-в-изображение, указанного в документации платформы; путь зависит от интерфейса продукта, поэтому копируйте, а не угадывайте.
Прежде чем писать больше кода, прочитайте ответ. Успешная отправка возвращает объект JSON, содержащий идентификатор задачи и поле статуса. Статус обычно указывает, что задача поставлена в очередь или обрабатывается — ещё не завершена. Это ожидаемое поведение. Точно запишите имена возвращённых полей; вы будете ссылаться на них в следующих двух разделах.
Две ошибки на уровне curl вызывают большинство первых неудач. Первая — отсутствующий ключ или неверная область действия: ответ будет ошибкой аутентификации, а не ошибкой модели. Вторая — некорректное тело: неэкранированные кавычки в промпте, висячая запятая, одинарные кавычки там, где JSON требует двойных. Если платформа отклоняет полезную нагрузку, отформатируйте её через jq и проверьте отдельно, прежде чем винить модель.
Когда отправка возвращает идентификатор, у вас есть действующий запрос. Всё после этого — ожидание и получение.
Перенос на Python
Версия на Python должна быть небольшой переиспользуемой функцией — а не скриптом с жёстко закодированным единственным промптом. Используйте requests (или httpx, если предпочитаете); сам вызов не требует специального клиента.
import os
import requests
API_KEY = os.environ["HIAPI_API_KEY"]
BASE_URL = os.environ["HIAPI_BASE_URL"]
HEADERS = {
"Authorization": f"Bearer {API_KEY}",
"Content-Type": "application/json",
}
def submit_image(prompt: str, **params) -> dict:
payload = {
"model": "seedream-5.0-lite/text-to-image",
"prompt": prompt,
**params,
}
response = requests.post(BASE_URL, headers=HEADERS, json=payload, timeout=30)
response.raise_for_status()
return response.json()
Здесь три намеренных решения. Ключ и базовый URL берутся из окружения, поэтому функцию безопасно коммитить. Универсальный параметр **params позволяет передавать размеры вывода или другие документированные опции без редактирования функции. А raise_for_status() немедленно превращает HTTP-ошибки в исключения, что вам и нужно — 4xx при отправке никогда не станет валидной задачей, поэтому быстрый отказ лучше проверки запутанного тела ответа.
Возвращённый словарь — это ваша запись задачи. Распечатайте его один раз во время разработки, чтобы узнать точные ключи идентификатора и статуса. Не индексируйте его вслепую; небольшой аксессор сохранит читаемость остального кода:
job = submit_image("A flat illustration of a paper plane over a city map")
print(job)
Если он печатает поставленную в очередь задачу, перенос из curl верен. Если он выбрасывает исключение, сообщение из raise_for_status() скажет вам, столкнулись ли вы с проблемой аутентификации или проблемой полезной нагрузки — те же две категории, что и в оболочке.
Написание промптов для мировых знаний и отрисованного текста
Модели текст-в-изображение strongest, когда промпт описывает то, что должно быть видно, и слабее всего, когда намекает на знания, которые модель должна вывести. seedream-5.0-lite/text-to-image может использовать общий мировой контекст — узнаваемые объекты, распространённые дизайнерские приёмы, стили типографики — но вам всё равно нужно дать ему достаточно содержания, чтобы закрепить этот контекст.
Для промптов сцен описывайте субъект, композицию и визуальный стиль. 'A cozy reading nook by a window, soft afternoon light, three-quarter view, muted earth tones' говорит модели и что рисовать, и как оформить стиль. Расплывчатые промпты дают обычные изображения; конкретные промпты дают пригодные изображения.
Отрисовка текста — это место, где промпты обычно терпят неудачу. Если вам нужен текст внутри изображения, следуйте нескольким правилам:
- Заключайте точную строку в кавычки. Пишите нужный текст в кавычках, чтобы он явно был литералом, а не описанием.
- Будьте кратки. Короткие заголовки или названия брендов отрисовываются надёжно; абзацы — нет.
- Указывайте положение и стиль. 'The word "North" centered at the top in a bold sans-serif' лучше, чем 'some text at the top'.
- Избегайте конкурирующего текста. Несколько разных текстовых элементов на одном изображении легко превращаются в абракадабру. Если нужно несколько, делайте их краткими и разносите друг от друга.
- Меняйте по одной переменной за раз. Меняйте формулировку, а не формулировку, компоновку и стиль одновременно, иначе вы не узнаете, что решило проблему.
Для всего, что связано с узнаваемым контекстом — категория продукта, тип плаката, тип вывески — называйте это явно. Предварительные знания модели наиболее полезны, когда промпт даёт им зацепку. 'A vintage travel poster for a coastal town' несёт больше полезного контекста, чем 'a poster'.
Не выдумывайте параметры. Если промпт не даёт желаемого расположения текста, сначала поправьте формулировку самого промпта, а уже потом пробуйте опции, которых нет в документации.
Обработка асинхронных задач и скачивание вывода
Опрос — это место, где интеграция тихо ломается. Задача асинхронна, поэтому вам нужен цикл, который проверяет статус, ждёт между проверками, в конце концов сдаётся и точно знает, какие значения статуса означают «готово».
import time
def wait_for_job(job_id: str, poll_interval: float = 3.0, timeout: float = 180.0) -> dict:
deadline = time.monotonic() + timeout
while time.monotonic() < deadline:
response = requests.get(
f"{BASE_URL}/{job_id}", headers=HEADERS, timeout=30
)
response.raise_for_status()
job = response.json()
status = job.get("status")
if status in {"succeeded", "completed"}:
return job
if status in {"failed", "error", "cancelled"}:
raise RuntimeError(f"Job {job_id} ended with status {status}")
time.sleep(poll_interval)
raise TimeoutError(f"Job {job_id} did not finish within {timeout}s")
Скорректируйте путь опроса и строки статуса по тому, что показывает документация платформы — эти две детали с наибольшей вероятностью отличаются от приведённого наброска. Важна структура: монотонный дедлайн, сон между проверками, явные наборы успеха и неудачи, и тайм-аут, который выбрасывает исключение, а не возвращает полузавершённую задачу.
Как только задача сообщает об успехе, ответ содержит URL вывода. Считайте этот URL временным. Скачивайте байты сразу, а не сохраняйте ссылку:
def download_image(url: str, path: str) -> None:
response = requests.get(url, timeout=60)
response.raise_for_status()
with open(path, "wb") as f:
f.write(response.content)
job = wait_for_job(job_id)
download_image(job["output"]["url"], "out.png")
Прежде чем продолжить, убедитесь, что файл — настоящее изображение: откройте его, проверьте размеры или хотя бы убедитесь, что длина в байтах не подозрительно мала. Если сервер корректно закрыл соединение, усечённая загрузка для requests выглядит как успешная.
Частые ошибки и способы их исправления
Большинство неудач в первых интеграциях делятся на четыре категории. Разбирайтесь с ними по порядку.
Отправка отклонена
Если первый вызов возвращает 4xx, распечатайте тело ответа. Ошибка аутентификации означает, что ключ отсутствует, просрочен или отправлен не как bearer-токен. Ошибка схемы означает некорректную полезную нагрузку — неверное поле модели, отсутствующий промпт или опечатка в документированном параметре. Проверьте JSON отдельно и сравните с рабочим примером curl.
Задача никогда не завершается
Цикл бесконечно крутится или завершается по тайм-ауту. Сначала проверьте интервал опроса: долбёжка эндпоинта без сна может вызвать ограничение частоты, из-за чего здоровая задача выглядит зависшей. Затем проверьте сравнение статусов — если платформа возвращает success, а вы сопоставляете с succeeded, каждая задача выглядит незавершённой. Запишите одно исходное значение статуса вместо догадок.
Выходной URL возвращает 404 или 403
Выходной URL подписан и ограничен по времени. Если вы опрашивали долго, а затем начали получать, ссылка могла истечь. Получайте сразу после завершения, а если нужно сохранить результат, сохраняйте файл, а не ссылку.
Изображение отрисовано, но текст нечитаем
Это проблема промпта, а не кода. Сократите текст, заключайте его в точные кавычки, уменьшите количество текстовых элементов и сделайте инструкции по стилю более явными. Перезапускайте, меняя по одному изменению за раз, чтобы знать, какая правка помогла.
Запрос зависает или истекает по тайм-ауту
Всегда задавайте явные тайм-ауты для вызовов отправки и опроса. Запрос без тайм-аута может бесконечно блокировать рабочий процесс, а цикл опроса без дедлайна превращает кратковременный сбой в зависший процесс.
Когда поведение неожиданное, сведите его к минимальному вызову curl, который всё ещё падает. Если сырой HTTP-запрос ведёт себя неправильно, проблема не в слое Python — как только curl снова работает, перенос обратно в Python механический. Страница модели seedream-5.0-lite/text-to-image перечисляет текущие параметры и форму ответа, поэтому смотрите туда, прежде чем предполагать имена полей.
Похожие статьи
Все статьи →-
Руководство
Как вызвать 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
Практическая демонстрация с упором на запросы: построение вызова от промпта до видеоклипа, отправка запроса, опрос статуса завершения и скачивание результата