HiAPI
Блог

Руководство

Как вызвать gpt-image-2/text-to-image@ext через API HiAPI: curl и Python

Практическое пошаговое руководство по запросам для разработчиков, интегрирующих генерацию изображений по тексту

Oct 31, 2026
黑绿底上,黄铜色与深绿色扁平缎带以经纬交织方式构成开放式网格,这是教程文章的封面图。

Что даёт вам 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. Сбой, сохраняющийся при минимальном запросе, — это проблема интеграции в вашем окружении; сбой, который исчезает, указывает на добавленные вами параметры.

Похожие статьи

Все статьи →

Начните работать с постоянными артефактами ИИ

Получите API-ключ и вызывайте модели изображений, видео и аудио через один API на основе tasks.

Читать документацию API