Руководство
Как использовать nano-banana-pro через API HiAPI: примеры на curl и Python
Что nano-banana-pro на HiAPI может вам дать
nano-banana-pro — это модель генерации изображений, доступная через унифицированный API HiAPI. Вам не нужно интегрироваться напрямую с поставщиком модели: достаточно отправить в HiAPI запрос в унифицированном формате, и вы получите сгенерированное изображение — как и с моделями других платформ, с той же аутентификацией, теми же соглашениями об эндпоинтах и той же обёрткой ответа.
nano-banana-pro спроектирована для генерации изображений на основе промптов и позволяет прикладывать к текстовому промпту референсные изображения. Референсные изображения дают возможность направлять вывод визуальным контекстом (субъект, стиль, композиция), не описывая всё словами. Результат выдаётся в разрешении 2K, поэтому модель лучше подходит для производственных ассетов, а не для быстрых набросков.
После прохождения этого руководства у вас будет полностью рабочая интеграция, которая умеет:
- отправлять промпт в nano-banana-pro через HiAPI с помощью проверенного запроса
curl; - воспроизводить тот же вызов на Python без изменения тела запроса;
- прикладывать референсные изображения к запросу;
- отправлять асинхронные задачи, опрашивать их до завершения и корректно обрабатывать повторные попытки;
- скачивать готовое 2K-изображение и сохранять его в собственную инфраструктуру.
Каждый раздел строится на предыдущем, поэтому самый надёжный путь — идти по порядку: сначала вручную убедиться в корректности запроса, затем перенести его в код.
Перед отправкой первого запроса
Перед первым вызовом вам понадобятся три вещи.
API-ключ
Создайте API-ключ в своей учётной записи HiAPI и не допускайте его попадания в систему контроля версий. Обращайтесь с ним как с любым другим секретом: загружайте из переменной окружения (HIAPI_API_KEY) или из менеджера секретов и никогда не прописывайте жёстко в файлах, которые можете закоммитить. Если ключ утёк, смените его в панели управления, а не пытайтесь вычистить из истории.
HTTP-клиент
Подойдёт любой инструмент, способный отправлять HTTPS-запросы. Для первого запроса curl в командной строке — идеальный выбор, потому что между вами и сетью нет фреймворка: виден каждый заголовок и каждый байт тела ответа. Для части на Python достаточно стандартной библиотеки urllib.request; если вы уже используете requests или httpx, соответствие такое же. В этом руководстве Python ограничен стандартной библиотекой, поэтому ничего дополнительно устанавливать не нужно.
Место для сохранения вывода
Поскольку задачи nano-banana-pro асинхронны, с самого начала продумайте каталог или бакет для хранения готовых изображений. Для разработки подойдёт локальная папка output/; в продакшене стоит ориентироваться на объектное хранилище.
Устанавливать SDK поставщика не нужно. HiAPI работает через обычные HTTPS-вызовы, поэтому запрос, который вы соберёте в curl, будет в точности тем же, что отправит ваш Python-клиент.
Рабочий запрос curl, по шагам
Самый быстрый способ убедиться, что ключ, эндпоинт и тело запроса корректны, — отправить запрос вручную. Прежде чем вводить его, разберите его на части.
Эндпоинт и метод
Все вызовы моделей идут на один базовый URL HiAPI; модель указывается в теле запроса, а не в пути. Для запроса генерации используется POST.
Заголовки
В каждом вызове важны три заголовка:
Authorization: Bearer $HIAPI_API_KEY— ваш ключ, передаваемый как bearer-токен.Content-Type: application/json— для запросов, содержащих только промпт.Accept: application/json— чтобы получить структурированный ответ, а не HTML-страницу ошибки.
Тело запроса
JSON-тело содержит имя модели и параметры генерации. Как минимум нужно отправить идентификатор модели и ваш промпт:
curl -sS -X POST "$HIAPI_BASE_URL" \
-H "Authorization: Bearer $HIAPI_API_KEY" \
-H "Content-Type: application/json" \
-H "Accept: application/json" \
-d '{
"model": "nano-banana-pro",
"input": {
"prompt": "стеклянный террариум на подоконнике в лучах солнца, мягкий утренний свет, малая глубина резкости"
}
}'
Перед выполнением этой команды задайте в оболочке HIAPI_BASE_URL и HIAPI_API_KEY. Хранение URL в переменной означает, что позже вы сможете направить тот же скрипт на staging- или sandbox-URL, не меняя команду.
Чтение ответа
Успешная отправка возвращает JSON-объект, идентифицирующий задачу. Ключевое поле — идентификатор задачи; он понадобится вам на шаге опроса. Поскольку генерация занимает время, не ожидайте получить само изображение в первом ответе: nano-banana-pro работает асинхронно, и этот вызов — лишь часть взаимодействия, отвечающая за отправку.
Если команда вернула ошибку, остановитесь здесь и исправьте её до написания любого кода. Проверенный запрос curl — ваша эталонная реализация: каждый последующий шаг должен порождать тот же HTTP-запрос.
Перенос запроса на Python
Перенос механический: URL, метод, заголовки и JSON-тело остаются прежними. Меняется только клиент.
Тот же запрос с urllib
import json
import os
import urllib.request
api_key = os.environ["HIAPI_API_KEY"]
base_url = os.environ["HIAPI_BASE_URL"]
payload = {
"model": "nano-banana-pro",
"input": {
"prompt": "стеклянный террариум на подоконнике в лучах солнца, мягкий утренний свет, малая глубина резкости"
},
}
request = urllib.request.Request(
base_url,
data=json.dumps(payload).encode("utf-8"),
method="POST",
headers={
"Authorization": f"Bearer {api_key}",
"Content-Type": "application/json",
"Accept": "application/json",
},
)
with urllib.request.urlopen(request, timeout=60) as response:
body = json.loads(response.read().decode("utf-8"))
print(body)
Правила соответствия
При переходе от curl легко ошибиться в трёх деталях:
- Тело запроса должно быть байтами.
json.dumpsсоздаёт строку; перед передачей в объект запроса её нужно закодировать. - Заголовки — это словарь, а не флаги. Каждая строка
-Hпревращается в пару ключ/значение. Сохраняйте префиксBearerи пробел после него. - Метод нужно указать явно. При наличии данных
urllib.requestпо умолчанию используетPOST, но явное указаниеmethod="POST"делает намерение понятнее и защищает от сюрпризов, если вы позже уберёте тело запроса.
Если вы используете requests, эквивалент такой: requests.post(base_url, headers=headers, json=payload, timeout=60) — json= позаботится о сериализации и типе содержимого за вас. Если используете httpx, форма вызова та же.
Небольшая вспомогательная функция, которая пригодится
Оберните вызов отправки в функцию, принимающую промпт и возвращающую идентификатор задачи. Каждый следующий раздел — референсные изображения, опрос, скачивание — строится на этой функции, и хранение её в одном месте означает, что изменения формы запроса происходят только один раз.
Отправка референсных изображений вместе с промптом
Референсные изображения меняют форму запроса, поэтому решите как можно раньше, какой способ ввода будет использовать ваше приложение.
Два практичных варианта
Ввод по URL. Если референсное изображение уже доступно по HTTPS, вы можете приложить его URL к промпту в теле запроса. Это сохраняет запрос в формате application/json — наиболее удобную для повторных попыток и логирования форму.
Загрузка файла. Если изображение находится на клиенте или в приватном хранилище, его можно отправить как файловую часть в запросе multipart/form-data. В этом случае заголовок Content-Type: application/json заменяется multipart-типом содержимого — позвольте вашему HTTP-клиенту сгенерировать его, чтобы границы были корректными — а JSON-поля становятся полями формы в том же запросе.
Для большинства серверных интеграций ввод по URL проще: ваши изображения уже лежат в объектном хранилище, запрос остаётся JSON, и при повторных попытках вы избегаете повторной отправки больших тел запроса.
Согласованность промпта и референсного изображения
Промпт должен описывать назначение референсного изображения, а не только его содержимое. «Повтори освещение и цветовую тональность референса; замени субъект на керамическую вазу» даёт модели чёткую задачу. Промпт, игнорирующий референс, тратит ввод впустую.
Проверка перед отправкой
Референсные изображения — самая частая причина ошибок в запросах. Проверьте, доступен ли URL публично (или согласуйте время жизни подписанного URL между обеими частями вашей системы), принимает ли модель этот тип файла и не настолько ли велико изображение, что загрузка уйдёт в таймаут. Выполните эти проверки сначала в собственном коде — отладка ошибки клиентской валидации обходится гораздо дешевле отклонённого запроса.
Работа с асинхронными задачами и опрос результатов
Генерация в nano-banana-pro асинхронна. Стройте клиент вокруг трёх отдельных шагов: отправка, опрос, скачивание. Смешивание их в одной функции усложняет осмысление повторных попыток и таймаутов.
Шаг 1: отправка
Отправьте описанный выше запрос и сохраните возвращённый идентификатор задачи. Сохраните этот идентификатор в надёжном месте — строке базы данных или сообщении очереди, — потому что ваш процесс может перезапуститься между отправкой и завершением.
Шаг 2: опрос
Используя тот же базовый URL и тот же заголовок Authorization, запросите статус задачи, передав её идентификатор. Опрашивайте с интервалом, а не в тесном цикле; несколько секунд между проверками — типичный вариант, а если несколько проверок подряд возвращают состояние ожидания, следует применять экспоненциальную задержку.
import time
TERMINAL = {"succeeded", "failed"}
def wait_for_job(job_id, timeout=300, interval=3):
deadline = time.monotonic() + timeout
while time.monotonic() < deadline:
status = get_job_status(job_id) # same headers as submit
if status in TERMINAL:
return status
time.sleep(interval)
raise TimeoutError(f"job {job_id} did not finish in time")
Шаг 3: учёт статуса
Рассматривайте поле статуса как перечисление. Задача либо всё ещё выполняется, либо успешно завершена, либо завершилась с ошибкой. Обрабатывайте все три случая явно: при успехе переходите к скачиванию; при ошибке читайте сообщение об ошибке и определяйте, в чём проблема — во входных данных или в промпте; при таймауте прекращайте опрос и сохраняйте идентификатор задачи для последующего разбора.
Повторные попытки на двух уровнях
Сетевые повторные попытки следует применять к вызову отправки и к каждому запросу опроса, задав ограниченное число попыток. Повторные попытки на уровне задачи — другое дело: если задача провалилась из-за плохого промпта или референсного изображения, повторная отправка того же тела запроса провалится так же. Повторяйте саму задачу только после изменения входных данных.
Распространённый продакшен-паттерн — выделенный worker, отвечающий за цикл опроса, чтобы веб-запросы никогда не блокировались генерацией. Отправляйте задачу из обработчика вашего API, передавайте идентификатор задачи worker'у и уведомляйте клиента, когда worker завершит работу.
Скачивание и хранение 2K-вывода
Финальный ответ задачи указывает на сгенерированное изображение, а не содержит его, поэтому скачивание — шаг, за который отвечаете вы.
Получение изображения
Когда задача сообщает об успехе, ответ содержит расположение вывода. Получите его обычным GET-запросом, затем запишите байты в файл или передайте потоком в хранилище. При разработке сохраняйте в локальный каталог под предсказуемым именем, построенным из идентификатора задачи, чтобы связать файл с записью о задаче.
import pathlib
import urllib.request
def save_image(url, job_id, out_dir="output"):
pathlib.Path(out_dir).mkdir(exist_ok=True)
target = pathlib.Path(out_dir) / f"nano-banana-pro-{job_id}.png"
with urllib.request.urlopen(url, timeout=60) as response:
target.write_bytes(response.read())
return target
Правильное хранение
В продакшене передавайте ответ потоком напрямую в объектное хранилище, а не пишите на локальный диск, чтобы поведение было одинаковым независимо от того, какой worker обрабатывает задачу. Записывайте ключ объекта и идентификатор задачи в базу данных и проверяйте, что тип содержимого и расширение файла соответствуют тому, что генерирует модель. Если изображение будет отдаваться в вебе, создавайте миниатюры в том же конвейере, чтобы публичные страницы никогда не загружали полный файл в разрешении 2K.
Планируйте политику хранения
Сгенерированный вывод — ваши данные. Определите, как долго его хранить, нужна ли версионность и сможет ли конечное хранилище восстановить его, если оно будет потеряно. Если ответ отрицательный, сохраняйте вместе с изображением и тело запроса, чтобы будущие баги или изменения модели никогда не лишили вас возможности воспроизвести результат.
Частые точки отказа и способы отладки
Большинство первых интеграций терпят неудачу по нескольким причинам. Прежде чем предполагать проблему в модели, проверьте этот список по пунктам.
- Ошибки авторизации. Отсутствует префикс
Bearer, ключ содержит завершающий перевод строки из-за копирования из env-файла, или используемый ключ относится к окружению, отличному от заданного базового URL. - Несовпадение типа содержимого. Отправка JSON-полей с multipart-заголовком или файла с
application/json— самая частая причина отклонения запросов с референсными изображениями. Для multipart-тела позвольте клиенту задать заголовок. - Неверный метод или форма тела. Использование GET вместо POST или
promptверхнего уровня вместо вложенного объектаinputпорождает ошибки валидации, которые выглядят совершенно не связанными с причиной. Сравните ваш запрос байт за байтом с проверенным вызовомcurl—curl -vпоказывает фактически отправляемые заголовки. - Слишком частый опрос или его отсутствие. Частые запросы к эндпоинту статуса приводят к ограничению скорости; без опроса вы вообще ничего не получите. Используйте фиксированный интервал с экспоненциальной задержкой и жёсткий таймаут.
- Истечение срока действия URL вывода. Если слишком долго ждать между завершением задачи и скачиванием, подписанный URL вывода может истечь. Скачивайте сразу после успеха или предусмотрите путь повторного получения нового расположения.
- Молчаливые сбои в коде. Всегда логируйте HTTP-статус и тело ответа при ошибке. Общие сообщения исключений от HTTP-клиента скрывают полезную часть ответа.
Когда что-то неясно, возвращайтесь к проверенному запросу curl из первого раздела. Если он работает, а ваш вызов на Python — нет, то баг — в различиях между ними.
Похожие статьи
Все статьи →-
Руководство
Как вызвать 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
Практическая демонстрация с упором на запросы: построение вызова от промпта до видеоклипа, отправка запроса, опрос статуса завершения и скачивание результата