Руководство
Как вызывать recraft-v4-styles-pro/text-to-image в API hiapi: curl и Python
Что делает этот эндпоинт и когда его использовать
recraft-v4-styles-pro/text-to-image преобразует текстовый промпт в изображение, и его отличительная черта — учёт стиля: вы можете направлять визуальный язык результата через стилевые референсы, а не полагаться только на формулировку промпта. Это практичный выбор, когда вывод должен сохранять единое ощущение на множестве генераций, а не выглядеть хорошо лишь в одной-двух.
Разработчики обычно используют его в следующих сценариях:
- Материалы с единым брендом — ключевые визуалы, карточки для соцсетей и варианты рекламы, которые должны укладываться в одну визуальную систему.
- Макеты продуктов и маркетинга — итерации по промпту с фиксированной стилистикой для получения набора вариантов в духе бренда.
- Шаг конвейера — генерация как этап более крупной автоматизации, где сохранённое изображение потребляет другой сервис.
Одна особенность определяет написание каждого примера кода ниже: генерация изображений асинхронна. Запрос отправляет задачу и немедленно возвращается; изображение появляется позже. Вам нужно написать шаг отправки и шаг опроса и рассматривать их как две независимые задачи.
Подготовка учётных данных hiapi и основы запросов
Все вызовы идут через единый интерфейс эндпоинтов hiapi, поэтому перед первым запросом нужно подготовить три вещи:
- API-ключ из вашей учётной записи hiapi. Обращайтесь с ним как с любым другим секретом: загружайте из переменной окружения и никогда не вписывайте в скрипт, которым можете поделиться.
- Идентификатор модели, который должен точно совпадать с опубликованным:
recraft-v4-styles-pro/text-to-image. - Инструмент с поддержкой HTTP —
curlдля исследования и HTTP-библиотека для любого постоянного сценария.
export HIAPI_API_KEY="your-key-here"
Соглашения, которые стоит усвоить сразу:
- Используйте
Content-Type: application/jsonпри отправке тела JSON. - Аутентифицируйтесь через заголовок bearer-токена.
- Передавайте id модели, промпт и стилевые референсы как отдельные поля нагрузки, а не запихивайте всё в одну строку — так шаг опроса и журналы будут понятнее.
О точных именах заголовков, базовом URL и текущих определениях полей смотрите справочную документацию hiapi API для этой модели; считайте этот учебник описанием формы вызова, а справочник — источником истины для имён.
Рабочий запрос curl
Ниже вызов отправки. Понимайте его как три слоя: транспорт, аутентификация и тело запроса.
curl -sS -X POST "$HIAPI_BASE_URL/generate" \
-H "Authorization: Bearer $HIAPI_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "recraft-v4-styles-pro/text-to-image",
"prompt": "minimalist product photo of a ceramic mug on a linen surface, soft daylight",
"style_references": []
}'
Разбор по строкам:
-X POST— отправьте задачу, а не получайте.Authorization: Bearer ...— токен берётся из переменной окружения, поэтому команду можно безопасно вставлять в терминал, а без переменной — безопасно делиться.-d '{...}'— тело JSON.model— точный идентификатор.prompt— свободный текст, описывающий сцену.style_references— точка подключения управления стилем, о ней речь ниже.-sS— тихий индикатор прогресса, но ошибки всё равно показываются, чтобы неудачные вызовы были видны.
Успешный ответ — это подтверждение, а не изображение: вы получаете идентификатор задачи и статус. Запишите этот идентификатор — это единственный дескриптор, нужный для опроса. Если вы исследуете в интерактивном режиме, пропустите ответ через форматировщик JSON, чтобы id задачи и статус были заметнее.
Передача стилевых референсов вместе с промптом
Ментальная модель проста: промпт говорит, что, стилевые референсы говорят, как это должно выглядеть. Держите их раздельно в нагрузке, и вы сохраните гибкость — можно повторно прогнать один и тот же промпт с разными наборами стилей, чтобы сравнить результаты.
{
"model": "recraft-v4-styles-pro/text-to-image",
"prompt": "ceramic mug on a linen surface, soft daylight",
"style_references": [
"https://your-bucket.example.com/styles/mug-ref-01.jpg",
"https://your-bucket.example.com/styles/mug-ref-02.jpg"
]
}
Практические советы:
- Начните без референсов. Сначала прогоните промпт «голым». Затем добавьте один референс и посмотрите на разницу, потом два. Изменение по одному за раз даёт гораздо больше информации, чем попытка сразу использовать целый набор стилей.
- Держите референсы доступными. Размещайте их там, где сервис сможет надёжно их получить — публичный бакет или подписанный URL с достаточным сроком действия — а не ссылку, которая истекает через несколько минут.
- Держите набор согласованным. Согласованные между собой референсы (похожее освещение, палитра, текстуры) обычно дают более стабильный результат, чем разнородная куча, которой модели приходится примирять противоречия.
- Версионируйте референсы. Храните их под стабильными ключами. Когда через месяц вывод пойдёт не так, вам нужно точно знать, какие файлы референсов тогда использовались.
Сверьтесь со справочной документацией hiapi для этой модели, чтобы подтвердить, передаются ли стилевые референсы как URL, загруженные ресурсы или именованные пресеты, и какие ограничения есть на их количество и формат.
Тот же вызов на Python
Вызов curl напрямую переносится. Оберните его в небольшие функции — их можно переиспользовать как этап конвейера.
import os
import requests
HIAPI_BASE_URL = os.environ["HIAPI_BASE_URL"]
HIAPI_API_KEY = os.environ["HIAPI_API_KEY"]
def submit_generation(prompt: str, style_references: list[str] | None = None) -> str:
"""Отправить задачу текст-в-изображение и вернуть id задачи."""
payload = {
"model": "recraft-v4-styles-pro/text-to-image",
"prompt": prompt,
"style_references": style_references or [],
}
response = requests.post(
f"{HIAPI_BASE_URL}/generate",
headers={
"Authorization": f"Bearer {HIAPI_API_KEY}",
"Content-Type": "application/json",
},
json=payload,
timeout=30,
)
response.raise_for_status()
data = response.json()
return data["job_id"]
Замечания по дизайну:
- Всегда задавайте таймаут. Бесконечно зависшая отправка заблокирует ваш рабочий процесс так же эффективно, как и падение.
raise_for_status()превращает не-2xx ответы в исключения, которые можно перехватить и залогировать, вместо того чтобы молча продолжать с некорректным телом ответа.- Возвращайте только id. Id задачи — это контракт между отправкой и опросом. Оставив остальную часть ответа за пределами вызывающего кода, вы упростите написание следующего раздела.
Уточните фактические имена полей ответа в справочной документации hiapi и соответственно скорректируйте data["job_id"] — именование полей — то место, где примеры из этой статьи вероятнее всего разойдутся с реальностью.
Опрос статуса завершения задачи
Генерация занимает время. Опрашивайте с фиксированным интервалом, останавливайтесь на терминальном статусе и в конце концов сдавайтесь.
import time
def wait_for_job(job_id: str, timeout: float = 300, interval: float = 3) -> dict:
deadline = time.monotonic() + timeout
while time.monotonic() < deadline:
response = requests.get(
f"{HIAPI_BASE_URL}/jobs/{job_id}",
headers={"Authorization": f"Bearer {HIAPI_API_KEY}"},
timeout=30,
)
response.raise_for_status()
job = response.json()
status = job["status"]
if status == "succeeded":
return job
if status == "failed":
raise RuntimeError(f"Job {job_id} failed: {job.get('error')}")
time.sleep(interval)
raise TimeoutError(f"Job {job_id} did not finish within {timeout}s")
Не столь очевидные моменты:
- Три исхода, а не два. В ожидании, успех, ошибка. Считайте любой нераспознанный статус «в ожидании» и пишите строку в журнал, чтобы добавленный позже статус не уронил рабочий процесс.
- Один общий дедлайн на всё ожидание. Дедлайн на
time.monotonic()не подвержен корректировкам часов, в отличие от арифметики по «настенным» часам. - Не запрашивайте слишком часто. Для генерации изображений нескольких секунд между проверками достаточно. Если нужно опрашивать быстрее, добавляйте задержку между попытками, а не сокращайте интервал.
- Принудительно ограничьте время ожидания. Задача, которая никогда не завершится, должна проявляться как ошибка, по которой можно поднять тревогу, а не как цикл, работающий до тех пор, пока контейнер не убьют.
Если вы запускаете много задач, отправляйте их пакетами и опрашивайте параллельно — с помощью одного цикла событий или пула потоков с разнесёнными интервалами — а не запускайте отдельный опросчик для каждой задачи в тесном цикле.
Скачивание и сохранение результата
Завершённая задача даёт вам ссылку на изображение, обычно URL. Скачивайте своевременно, поскольку у этих ссылок может быть ограничение по времени.
def save_image(job: dict, path: str) -> None:
url = job["output"]["image_url"]
for attempt in range(3):
try:
with requests.get(url, stream=True, timeout=60) as r:
r.raise_for_status()
with open(path, "wb") as f:
for chunk in r.iter_content(chunk_size=8192):
f.write(chunk)
return
except requests.RequestException:
if attempt == 2:
raise
time.sleep(2 ** attempt)
Практики, которые стоит применять в продакшене:
- Скачивайте потоком. Сгенерированные изображения не маленькие; без причины загружать их целиком в память — расточительство.
- Пишите во временный путь, затем переименовывайте. Падение посреди записи не должно оставлять усечённый файл там, где конвейер ожидает валидное изображение.
- Повторяйте скачивание, а не генерацию. Повторная попытка при нестабильном получении из бакета обходится дёшево; тратить генерацию впустую — нет. Ограничьте число повторов и используйте экспоненциальную задержку.
- Сохраняйте id задачи вместе с файлом. Когда кто-то спросит, откуда взялось изображение, ответ должен требовать одного запроса, а не рытья в журналах.
Для объектного хранилища замените open() потоковой загрузкой вашего SDK, сохранив ту же обёртку с повторами.
Ошибки, повторы и проверка обоснованности затрат
Режимы сбоев, с которыми вы столкнётесь первыми, и способы обращения с каждым:
- 401 / ошибка аутентификации — ключ отсутствует, написан с опечаткой или не экспортирован в shell, запускающий скрипт. Проверьте окружение, прежде чем трогать нагрузку.
- Ошибки валидации 4xx — обычно опечатка в id модели, отсутствующий
promptили некорректный стилевой референс. Логируйте тело ответа дословно; сообщения валидации здесь — самый быстрый путь к исправлению. - 429 / ограничение скорости — используйте задержку с джиттером, а не немедленный повтор. Очередь перед функцией отправки лучше, чем шторм повторов.
- Таймаут задачи — сработал дедлайн опроса. Сознательно решите, переотправлять ли; слепая переотправка удваивает расходы без повышения вероятности успеха.
- Кратковременные сетевые ошибки — повторяйте отправку и скачивание с ограниченной экспоненциальной задержкой. Скачивание повторяйте свободно; генерацию — осторожно.
Дисциплина затрат, с практической точки зрения:
- Оплата следует за реально выполненной моделью работой, поэтому неудачные задачи и заброшенные пакеты — это скрытые затраты. Записывайте каждую отправку с хешем промпта и id задачи, чтобы позже можно было учесть использование.
- Итерируйте с максимально дешёвыми промптами. Настраивайте формулировки и стилевые референсы на небольших быстрых прогонах, прежде чем вкладываться в крупные пакеты.
- Дедуплицируйте. Если одинаковый промпт и набор стилей запрошены дважды, отдавайте результат первого из собственного кэша.
- Добавьте жёсткий лимит параллелизма в рабочий процесс. Поднять лимит проще, чем объяснять неожиданный счёт.
Сделав отправку, опрос и сохранение тремя независимыми тестируемыми функциями, вы сможете чисто встроить этот эндпоинт в любой конвейер. О точных именах полей, статусах и текущих ценах смотрите страницу модели recraft-v4-styles-pro/text-to-image на 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
Практическая демонстрация с упором на запросы: построение вызова от промпта до видеоклипа, отправка запроса, опрос статуса завершения и скачивание результата