Руководство
Как вызвать gpt-image-2/text-to-image@ext через API HiAPI: curl и Python
Практическое пошаговое руководство по запросам для разработчиков, интегрирующих генерацию изображений по тексту
Что даёт вам gpt-image-2/text-to-image@ext
gpt-image-2/text-to-image@ext — это модель генерации изображений по тексту, доступная через унифицированный интерфейс HiAPI. Вам достаточно отправить промпт и необязательные параметры генерации на один и тот же эндпоинт, чтобы получить сгенерированные данные изображения. Не нужно устанавливать какие-либо компоненты, специфичные для модели, не нужно подключать отдельные SDK по каждому поставщику и не нужно управлять отдельными учётными записями — один и тот же API-ключ и одинаковая структура запроса охватывают остальные возможности платформы.
Выбирайте эту модель, когда вашему продукту нужно превратить текстовое описание в новое изображение: маркетинговый текст в ключевой визуал, пользовательский промпт в миниатюру, инструмент дизайна, который рендерит концепт-изображения по запросу. Поскольку вызов — это обычный HTTP-запрос, он легко встраивается в бэкенд-сервис, worker очереди или скрипт без каких-либо клиентских библиотек.
Это правильный выбор, когда на входе текст, а на выходе — растровое изображение, которое вы собираетесь хранить и распространять самостоятельно. Если в будущем вам понадобится переключиться на другой путь работы с изображениями на платформе, логика интеграции — аутентификация, обёртка запроса, обработка вывода — останется неизменной; достаточно поменять идентификатор модели и блок параметров.
Как читать это руководство
Это пошаговое руководство разворачивается слой за слоем. Сначала минимальный запрос, возвращающий изображение, затем версия на Python, далее структурное решение между одиночным вызовом и асинхронным опросом, и наконец обработка вывода. Каждый слой можно протестировать независимо, поэтому при возникновении проблемы вы точно знаете, какое изменение её внесло.
Предварительные требования и аутентификация
Перед отправкой первого запроса вам нужны две вещи: учётная запись HiAPI и привязанный к ней API-ключ. Создайте ключ в панели управления учётной записи и храните его так же, как любой секрет — локально в переменной окружения, в production в secrets manager. Не коммитьте его в репозиторий и не вставляйте в клиентский код, который отправляется в браузер.
Аутентификация выполняется через bearer-токен в заголовке запроса. Формат всегда одинаковый:
Authorization: Bearer $HIAPI_API_KEY
Задайте эту переменную один раз в shell, и приведённые ниже примеры смогут ссылаться на неё, не раскрывая ключ:
export HIAPI_API_KEY="your-key-here"
Что нужно подтвердить перед началом
- Ключ активен и имеет доступ к генерации изображений.
- Ваше окружение может отправлять исходящие HTTPS-запросы на эндпоинт HiAPI.
- Вы знаете, куда будут записываться сгенерированные файлы — локальный каталог для тестов, объектное хранилище для production.
Если ключ отсутствует или имеет неверный формат, проблема сразу проявится при первом вызове в виде ошибки аутентификации — это самый ранний и самый ясный момент для обнаружения проблемы.
Минимальный рабочий запрос curl
Начните с минимального запроса, который даёт изображение. Всё, кроме промпта, необязательно, а сохранение первого вызова компактным означает, что любая ошибка почти наверняка связана с аутентификацией или структурой запроса, а не с конфликтом параметров.
curl -sS -X POST "$HIAPI_BASE_URL/v1/images/generations" \
-H "Authorization: Bearer $HIAPI_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "gpt-image-2/text-to-image@ext",
"prompt": "一枚斑驳的黄铜指南针放在折叠的纸质地图上,柔和的窗光,浅景深",
"size": "1024x1024",
"n": 1
}'
Разбор по полям
model— идентификатор модели. Это единственное значение, привязывающее запрос кgpt-image-2/text-to-image@ext; оно должно быть точным.prompt— описание содержимого. Будьте конкретны в отношении субъекта, стиля и освещения; расплывчатые промпты дают расплывчатые изображения, и их труднее отлаживать, чем ошибки параметров.size— размер вывода. На этапе проверки конвейера можно опустить, приняв значение по умолчанию.n— количество изображений, генерируемых за вызов. Во время интеграции держите его равным 1, чтобы сбой точно соответствовал одному результату.
Запишите ответ в файл, чтобы можно было его проверить, не засоряя терминал двоичными данными:
curl -sS -X POST "$HIAPI_BASE_URL/v1/images/generations" \
-H "Authorization: Bearer $HIAPI_API_KEY" \
-H "Content-Type: application/json" \
-d @payload.json -o response.json
Как только он вернёт изображение, у вас есть заведомо рабочая базовая линия. Каждое последующее изменение должно быть одним откатываемым изменением относительно неё.
Перенос запроса на Python
Версия на Python — это тот же запрос, просто другой способ передачи. Используйте requests — это наименее подверженный сюрпризам выбор, и он взаимно однозначно соответствует полям curl, которые вы уже проверили.
import os
import requests
API_KEY = os.environ["HIAPI_API_KEY"]
BASE_URL = os.environ["HIAPI_BASE_URL"]
payload = {
"model": "gpt-image-2/text-to-image@ext",
"prompt": "一枚斑驳的黄铜指南针放在折叠的纸质地图上,柔和的窗光",
"size": "1024x1024",
"n": 1,
}
response = requests.post(
f"{BASE_URL}/v1/images/generations",
headers={
"Authorization": f"Bearer {API_KEY}",
"Content-Type": "application/json",
},
json=payload,
timeout=120,
)
response.raise_for_status()
data = response.json()
Разбор ключевых моментов
json=payloadза один шаг задаёт тип содержимого и сериализует тело запроса — никакой ручной сборки строк, никаких ошибок экранирования.- На практике
timeoutне является необязательным. Генерация изображений медленнее типичных вызовов JSON API; отсутствие таймаута означает, что при замедлении вышестоящего сервиса worker зависнет. raise_for_status()превращает HTTP-сбой в исключение, которое вы можете перехватить и классифицировать, вместо того чтобы пропускать некорректное тело ответа вниз по потоку.
Держите payload в виде dict, а не встроенной строки. Когда позже вы добавите параметры, вам достаточно добавить ключ — структура запроса не изменится, и вам никогда не придётся заново отлаживать транспортный уровень.
Если вы предпочитаете клиент в стиле SDK, те же эндпоинт и заголовки по-прежнему применимы; отличается только синтаксис вызова. Сначала проверьте с помощью curl, затем используйте клиент, который уже стандартизирован в вашем приложении.
Выбор между одиночным вызовом и асинхронным опросом
Это проектное решение, а не синтаксическое, и оно влияет на логику повторов и хранения больше, чем любой другой выбор в интеграции.
Одиночный вызов
Используйте одиночный цикл запрос-ответ в следующих случаях:
- Вы генерируете по запросу, и пользователь ожидает результат.
- Ваш HTTP-слой может выдержать длительное соединение.
- Вы генерируете одно изображение за раз, а не пакетом.
Задайте таймаут с запасом относительно самого медленного наблюдаемого времени генерации и рассматривайте таймаут как повторяемый сбой, а не как жёсткую ошибку.
Асинхронный опрос
Выбирайте асинхронность при пакетной обработке, когда запросы приходят от worker очереди или когда вызывающая сторона не должна блокироваться. Схема такова: отправить, получить дескриптор, затем опрашивать состояние завершения.
import time
def poll_until_done(fetch_status, handle, interval=2, max_wait=300):
deadline = time.monotonic() + max_wait
while time.monotonic() < deadline:
status = fetch_status(handle)
if status["state"] == "succeeded":
return status
if status["state"] == "failed":
raise RuntimeError(status.get("error", "generation failed"))
time.sleep(interval)
raise TimeoutError("generation did not finish in time")
Правила надёжного цикла опроса
- Экспоненциальная задержка. Начинайте с короткого интервала и постепенно увеличивайте его; постоянный частый опрос расходует квоту и лимит частоты запросов.
- Ограничивайте ожидание. Дедлайн
max_waitне даёт потерянным задачам навсегда занимать worker. - Сохраняйте дескриптор. Если worker перезапустится, вы должны иметь возможность возобновить опрос, а не отправлять запрос заново и платить за повторную генерацию.
- Считайте сбой терминальным состоянием каждой задачи. Состояние
failedследует регистрировать в журнале, а не молча повторять в частом цикле.
Решайте это как можно раньше. Встраивание асинхронной семантики в синхронный путь кода задним числом означает одновременную переписку вызывающей стороны, хранилища и обработки ошибок.
Обработка вывода изображения
Ответ содержит сгенерированное изображение, но это данные внутри JSON-обёртки — а не URL, допускающий горячую привязку. Относитесь к ним как к двоичному выводу, которым вы владеете.
Декодирование и сохранение
import base64
item = data["data"][0]
image_bytes = base64.b64decode(item["b64_json"])
with open("out.png", "wb") as f:
f.write(image_bytes)
Если ответ несёт URL вместо встроенных данных, немедленно загрузите его и запишите байты в собственное хранилище. Сгенерированные URL временны; всё, что вы предоставляете пользователям, должно находиться за вашей собственной инфраструктурой.
Проверяйте перед распространением
- Проверяйте магические числа. PNG начинается с
\x89PNG; HTML-страница ошибки — нет. Проверка нескольких байтов ловит проблемы прокси, которые возвращают HTTP 200, но некорректное тело ответа. - Записывайте размер. Фиксируйте длину в байтах, чтобы усечённые загрузки были заметны в мониторинге.
- Детерминированное хранение. Именуйте файлы по ID генерации, а не по тексту промпта, и сохраняйте промпт, параметры и метаданные ответа вместе с изображением. Эта комбинация позволит вам позже воспроизвести или проверить любой вывод.
- Правильно задавайте тип содержимого — исходя из фактического файла, а не из предположений.
Сохраняйте метаданные вместе с артефактом
Ведите небольшую сопроводительную запись: идентификатор модели, полный промпт, размеры и количество, метку времени, а также любой ID запроса из ответа. Через шесть месяцев, когда кто-то спросит, почему изображение выглядит именно так, эта запись будет вашим единственным ответом.
Отладка типичных сбоев
Большинство сбоев первой интеграции сводятся к трём категориям. Проверяйте их в этом порядке — стоимость диагностики примерно возрастает от низкой к высокой.
Ошибки аутентификации
401 или 403 означает, что ключ неверен, отозван или не отправлен. Выведите конструкцию заголовков без секрета, убедитесь, что префикс Bearer и пробел на месте, и подтвердите, что переменная окружения действительно заполнена в процессе, отправляющем запрос — частая ловушка: задана в shell, но отсутствует в worker или контейнере.
Некорректное тело запроса
400 обычно указывает на тело запроса. Вернитесь к минимальному запросу из раздела curl, затем добавляйте поля по одному. Частые виновники:
- Строка
modelне полностью совпадает сgpt-image-2/text-to-image@ext. - Тело запроса не является допустимым JSON — лишняя запятая или неэкранированные кавычки.
- Неверный тип параметра;
n— число, а не строка. - Отсутствует
Content-Type: application/json, и сервер не может разобрать тело запроса.
Таймауты и медленные ответы
Если соединение обрывается до возврата изображения, скорее всего вы превысили клиентский таймаут, а не столкнулись со сбоем модели. Для схемы с одиночным вызовом увеличьте таймаут; для любой пакетной формы переходите на асинхронный опрос. При повторе убедитесь, что нет дублирующей генерации: если запрос мог уже завершиться успешно, проверьте наличие результата перед повторной отправкой.
Когда ничего из вышеперечисленного не подходит
Захватите полный ответ неудачного запроса — код состояния, заголовки и тело ответа — и воспроизведите его минимальной командой curl. Сбой, сохраняющийся при минимальном запросе, — это проблема интеграции в вашем окружении; сбой, который исчезает, указывает на добавленные вами параметры.
Похожие статьи
Все статьи →-
Руководство
Как вызвать 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
Практическая демонстрация с упором на запросы: построение вызова от промпта до видеоклипа, отправка запроса, опрос статуса завершения и скачивание результата