Руководство
Как использовать ideogram-v4.5 через HiAPI API: curl, Python и работающий запрос
Что даёт вам ideogram-v4.5 на HiAPI
Когда текст на изображении действительно важен, ideogram-v4.5 — та модель, которую стоит выбрать. Макеты постеров, графические знаки, рендеры упаковки, карточки для соцсетей — любой сценарий, где одна опечатка в заголовке или размытая подпись испортит материал, — именно в этом ценность этой модели. Если же вы генерируете абстрактные текстуры или фотографические пейзажи, где ничего не нужно читать, универсальные модели изображений обычно дешевле и быстрее.
Это статья-интеграционное руководство, а не обзор модели. Прочитав её, вы получите работающий запрос, Python-клиент, выполняющий то же самое, и переиспользуемую вспомогательную функцию, которая берёт на себя то, на чём обычно спотыкаются: параметры соотношения сторон, опрос асинхронных задач и получение результата.
Одну вещь нужно усвоить сразу: генерация изображений на HiAPI — это API асинхронных задач. Вы отправляете запрос, получаете идентификатор, затем опрашиваете, пока задача не завершится. Код, который предполагает, что тело ответа уже содержит изображение, работать не будет. Каждый раздел ниже ведёт к этой схеме.
Прежде чем отправить запрос
Перед первым вызовом нужно подготовить четыре вещи.
1. API-ключ
Создайте его в консоли вашего аккаунта HiAPI и держите подальше от системы контроля версий. Экспортируйте его как переменную окружения, а не вставляйте в скрипт:
export HIAPI_API_KEY="your_key_here"
2. Базовый URL
Все запросы отправляются на базовый URL HiAPI API с добавлением конкретного пути эндпоинта генерации. Документация платформы перечисляет текущие пути; если документация говорит иное, не хардкодьте путь, который вы увидели в статье в блоге (включая эту).
3. Идентификатор модели
Строка модели, которую вы передаёте в теле запроса, идентифицирует ideogram-v4.5. Используйте точный регистр, указанный в списке моделей платформы — идентификаторы моделей сопоставляются буквально, и малейшее отклонение вернёт ошибку валидации, а не полезную подсказку.
4. Справочник параметров
Страница модели ideogram-v4.5 — авторитетный источник того, какие поля принимает тело запроса: ограничения длины промпта, поддерживаемые соотношения сторон, формат вывода, а также любые параметры seed или стиля. Прочитайте её перед написанием кода. Параметры, не перечисленные там, могут молча игнорироваться или отклоняться, а угадывание значений — самый частый способ потратить время на отладку.
С этими четырьмя вещами можно отправлять первый запрос.
Работающий запрос curl
Ниже минимальный пример отправки. Если в вашем аккаунте другие значения, подставьте путь эндпоинта и идентификатор модели из документации платформы.
curl -X POST "$HIAPI_BASE_URL/<generation-path>" \
-H "Authorization: Bearer $HIAPI_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "ideogram-v4.5",
"input": {
"prompt": "A vintage travel poster for the Amalfi Coast, bold serif headline reading \"AMALFI\", warm sunset palette, grainy print texture"
}
}'
Что делает каждая часть:
Authorization— аутентификация по bearer-токену. Отсутствующий или неверно отформатированный заголовок — самая частая причина 401.Content-Type— должен бытьapplication/json. Некоторые HTTP-клиенты не устанавливают его автоматически при POST, что приводит к непонятным ошибкам парсинга на сервере.model— буквальный идентификатор модели. Размещайте его на верхнем уровне тела запроса, как показано в документации.input.prompt— ваша инструкция для генерации. Как показано выше, заключайте в кавычки текст, который хотите видеть отрендеренным на изображении, чтобы модель обрабатывала его как буквальный текст, а не как описание.input.*— все остальные параметры генерации (соотношение сторон, формат, seed и т. д.) принадлежат этому вложенному объекту, рядом сprompt.
Успешная отправка возвращает JSON-объект, содержащий идентификатор задачи и поле статуса. Изображения в этом ответе нет — это ожидаемое поведение. Сохраните идентификатор; он понадобится на шаге опроса.
Тот же вызов на Python
Python-версия — это перевод один к одному. Мы используем requests и разделяем то же тело запроса, чтобы вы могли сравнить их бок о бок.
import os
import json
import requests
API_KEY = os.environ["HIAPI_API_KEY"]
BASE_URL = os.environ["HIAPI_BASE_URL"]
GEN_PATH = "/<generation-path>" # confirm in platform docs
payload = {
"model": "ideogram-v4.5",
"input": {
"prompt": (
"A vintage travel poster for the Amalfi Coast, bold serif "
'headline reading "AMALFI", warm sunset palette, grainy print texture'
)
},
}
response = requests.post(
BASE_URL + GEN_PATH,
headers={
"Authorization": f"Bearer {API_KEY}",
"Content-Type": "application/json",
},
data=json.dumps(payload),
timeout=30,
)
response.raise_for_status()
job = response.json()
print(job)
Два намеренных решения:
json.dumpsвместоjson=делает формат передачи наглядно идентичным примеру с curl. Работают оба; явная запись облегчает проверку того, что вы фактически отправляете, при отладке.timeout=30только для отправки. Отправка быстрая, генерация — нет. Никогда не допускайте, чтобы вызов отправки наследовал короткий таймаут, заданный для опроса, иначе вы будете сообщать о нормально работающей задаче как о сбое.
Выведенный словарь job содержит идентификатор задачи и текущий статус. Сохраните идентификатор куда-нибудь — цикл опроса зависит от него.
Управление соотношением сторон и форматом вывода
Соотношение сторон и формат вывода — это параметры тела запроса, а не отдельные эндпоинты. Они находятся в том же объекте input, что и промпт:
{
"model": "ideogram-v4.5",
"input": {
"prompt": "...",
"aspect_ratio": "<ratio from docs>",
"output_format": "<format from docs>"
}
}
Важная здесь дисциплина — не угадывать значения. Каждая модель генерации предоставляет фиксированные перечисления соотношений и форматов, и разные модели принимают разные варианты написания — 16:9 против 16x9, png против PNG и т. д. Передача значения, не поддерживаемого моделью, обычно приводит к ошибке валидации или, что хуже, к молчаливому откату к выводу по умолчанию, что выглядит как баг в вашем промпте.
Итак, рабочий процесс:
- Откройте страницу модели ideogram-v4.5 на платформе и дословно скопируйте список поддерживаемых соотношений сторон и форматов вывода.
- Поместите эти значения в небольшой белый список в коде, чтобы недопустимый ввод отвергался в месте вызова, а не на стороне API.
- По умолчанию используйте соотношение, соответствующее вашей нижестоящей вёрстке. Если изображение должно поместиться в слот социальной карточки 1200×630, выберите значение, близкое к этому соотношению, а не генерируйте квадрат и не обрезайте содержимое.
Изображения с плотным текстом заслуживают отдельного предупреждения: экстремальные соотношения (сверхширокие баннеры, сверхвысокие постеры) сжимают пространство, доступное для рендеринга текста. Для заголовков, которые действительно должны быть чёткими, средние горизонтальные или вертикальные соотношения надёжнее, чем панорамные экстремальные.
Обработка асинхронных задач и загрузка результатов
Жизненный цикл одной генерации состоит из трёх шагов: отправка → опрос → получение.
Отправка
Этот шаг вы уже освоили в предыдущем разделе. Ответ даёт вам идентификатор задачи и статус, например queued или processing.
Опрос
Опрашивайте эндпоинт статуса задачи с этим идентификатором, пока статус не сообщит о завершении. Две правила делают этот процесс корректным:
- Спите между опросами. Начните примерно с одной секунды и постепенно увеличивайте задержку. Долбёжка эндпоинта статуса не ускорит задачу и рискует вызвать ограничение частоты запросов.
- Ограничьте время ожидания. Задайте максимальное число попыток или дедлайн, и по его превышении явно выдавайте ошибку, а не зацикливайтесь бесконечно.
import time
def wait_for_job(job_id, headers, base_url, status_path,
max_attempts=60, initial_delay=1.0, factor=1.5):
delay = initial_delay
for _ in range(max_attempts):
r = requests.get(
f"{base_url}{status_path}/{job_id}",
headers=headers,
timeout=30,
)
r.raise_for_status()
data = r.json()
status = data.get("status")
if status in ("succeeded", "completed", "success"):
return data
if status in ("failed", "error", "cancelled"):
raise RuntimeError(f"job {job_id} ended with status {status}: {data}")
time.sleep(delay)
delay *= factor
raise TimeoutError(f"job {job_id} did not finish in time")
Сверьтесь с документацией платформы, чтобы узнать точные строки статусов и путь статуса для вашего аккаунта — сопоставляйте по значениям из документации, а любой нераспознанный статус считайте всё ещё выполняющимся, а не успешным.
Получение
Когда задача сообщает о завершении, ответ содержит расположение вывода (обычно URL). Загрузите его обычным GET и запишите байты на диск. URL вывода может быть ограничен по времени, поэтому скачивайте сразу, а не сохраняйте URL на потом. Всё, что нужно знать для написания этого цикла, следует из структуры ответа на отправку — отдельного API «получения изображения» изучать не нужно.
Упаковка в переиспользуемую вспомогательную функцию
Три отдельных скрипта, каждый из которых заново реализует опрос, — это проблема сопровождения. Соберите это один раз.
import os, json, time, requests
class IdeogramClient:
def __init__(self, base_url, api_key, gen_path, status_path,
poll_attempts=60, poll_factor=1.5):
self.base_url = base_url.rstrip("/")
self.gen_path = gen_path
self.status_path = status_path
self.poll_attempts = poll_attempts
self.poll_factor = poll_factor
self.headers = {
"Authorization": f"Bearer {api_key}",
"Content-Type": "application/json",
}
def generate(self, prompt, **params):
body = {"model": "ideogram-v4.5", "input": {"prompt": prompt, **params}}
r = requests.post(self.base_url + self.gen_path,
headers=self.headers,
data=json.dumps(body), timeout=30)
r.raise_for_status()
job = r.json()
done = self._wait(job["id"])
url = done["output"]["url"] # confirm shape in docs
return self._download(url)
def _wait(self, job_id):
delay = 1.0
for _ in range(self.poll_attempts):
r = requests.get(f"{self.base_url}{self.status_path}/{job_id}",
headers=self.headers, timeout=30)
r.raise_for_status()
data = r.json()
if data.get("status") in ("succeeded", "completed", "success"):
return data
if data.get("status") in ("failed", "error", "cancelled"):
raise RuntimeError(data)
time.sleep(delay)
delay *= self.poll_factor
raise TimeoutError(job_id)
def _download(self, url):
r = requests.get(url, timeout=60)
r.raise_for_status()
return r.content
Использование — один вызов: img_bytes = IdeogramClient(...).generate("...", aspect_ratio="<from docs>"). Подстройте доступ к done["output"]["url"] и строки статусов под структуру ответа из документации — эти два места, скорее всего, потребуют тонкой настройки под аккаунт.
Частые ошибки и приёмы отладки
Большинство неудач первой недели попадает в пять категорий.
401 / 403 — аутентификация. Ключ отсутствует, содержит пробелы из-за копипаста или у него нет префикса Bearer . Выведите по четыре символа с начала и конца фактически отправляемого ключа; завершающий перевод строки из env-файла — классический виновник.
400 — некорректный JSON или неизвестное поле. Если тело запроса собрано конкатенацией строк, неэкранированные кавычки в промпте ломают JSON. Стройте тело как словарь и сериализуйте через json.dumps. Если JSON парсится, следующий подозреваемый — имя параметра, которое модель не принимает; сверьте ваши ключи со страницей модели посимвольно.
404 / модель не найдена. Обычно это опечатка или неверный регистр идентификатора модели, либо устаревший путь эндпоинта. Копируйте оба из документации платформы, а не по памяти и не из старых руководств.
429 — ограничение частоты. Почти всегда из-за слишком агрессивного опроса. Увеличьте начальную задержку опроса и фактор нарастания. На стороне отправки добавьте повтор с джиттером для ответов 429 и 5xx, но не повторяйте 4xx-ошибки валидации — они будут сбоить одинаково каждый раз.
Задача успешна, но изображение не открывается. Проверьте, что вы скачали байты, а не JSON-страницу ошибки; вызов raise_for_status() на GET-запросе скачивания ловит большинство таких проблем. Также убедитесь, что вы считаете URL скачивания краткосрочным и не кешируете его между сессиями.
Если сомневаетесь, логируйте полное тело ответа и код статуса для каждого вызова в цепочке — отправки, каждого опроса и скачивания. API обычно прямо сообщает, что пошло не так; баг обычно в том, что мы просто не посмотрели.
С работающей отправкой, циклом опроса и разумной обработкой ошибок ideogram-v4.5 можно подключить к реальному пайплайну так же, как любой другой вызов модели HiAPI.
Похожие статьи
Все статьи →-
Руководство
Как вызвать 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
Практическая демонстрация с упором на запросы: построение вызова от промпта до видеоклипа, отправка запроса, опрос статуса завершения и скачивание результата