GPT-6 Sol и Claude Opus 5.5 уже доступныGPT-6 Sol вдвое дешевле 5.6 Sol

Nano Banana Pro API: инструкция на Python, редактирование и цена

Один POST, один опрос, одно скачивание — скрипт для Nano Banana Pro, который работает.

Kiki, OmniaKey COO9 мин чтения
На этой странице

Nano Banana Pro — это gemini-3-pro-image от Google, и в OmniaKey он вызывается одним POST /v1/media/tasks. Наши три теста в формате 3:4 вернулись размером 896x1200, 1792x2400 и 3584x4800, и все слова на постере были написаны правильно.

Короткий ответ

  • Модель: gemini-3-pro-image — это GA-ID модели у Google. В карточке модели Vertex указана дата выхода 28 мая 2026 года.
  • Вызов: отправьте POST https://api.omniakey.com/v1/media/tasks с Idempotency-Key, опрашивайте GET /v1/media/tasks/{id} до статуса succeeded и скачайте assets[0].url.
  • Параметры: parameters.aspect_ratio и parameters.image_size; значения размера — 1K, 2K и 4K, с заглавной K.
  • Лимит запроса: 1 MiB на всё тело, включая изображение в Base64 внутри JSON.
  • Цена Google: $0.134 за изображение 1K/2K и $0.24 за 4K, по странице цен Gemini API.
  • Наши токены: три задачи отчитались о 1,133, 1,225 и 2,480 выходных токенах. При $120 за миллион токенов изображения это $0.136, $0.147 и $0.298.
  • Правка: укажите operation: "edit" и положите исходник в input.image в виде {data, mime_type}.

Страница модели Nano Banana Pro в OmniaKey принимает и gemini-3-pro-image-preview, старый ID снимка, по той же цене.

ID модели и что понадобится

В коде пишите gemini-3-pro-image. Карточка модели в Vertex указывает стадию GA и дату выхода 28 мая 2026 года. Модель поддерживает вывод в 1K, 2K и 4K.

ID с суффиксом -preview указывает на ту же модель. Таблица моделей изображений в OmniaKey описывает gemini-3-pro-image-preview как "Same model, -preview snapshot id", с той же ценой за вызов.

Понадобятся две вещи:

  1. Ключ OmniaKey API в переменной окружения, чтобы скрипт его прочитал: export OMNIAKEY_API_KEY="your-key".
  2. Python 3. Скрипт ниже использует только стандартную библиотеку: urllib, json, time, uuid, base64 и pathlib. SDK ставить не нужно.

Скрипт на Python

Три шага: создать задачу, опросить её, скачать изображение. Сохраните файл как nano_banana.py и запустите python3 nano_banana.py.

python
import base64
import json
import os
import time
import urllib.request
import uuid
from pathlib import Path

API = "https://api.omniakey.com/v1/media/tasks"
HEADERS = {
    "Authorization": f"Bearer {os.environ['OMNIAKEY_API_KEY']}",
    "Content-Type": "application/json",
}


def call(url, payload=None, headers=None, method=None):
    body = json.dumps(payload).encode() if payload is not None else None
    req = urllib.request.Request(url, data=body, headers=headers or HEADERS, method=method)
    with urllib.request.urlopen(req, timeout=60) as resp:
        return resp.status, json.loads(resp.read())


def create_task(prompt, aspect_ratio="3:4", image_size="2K", image_path=None):
    body = {
        "model": "gemini-3-pro-image",
        "type": "image",
        "operation": "generate" if image_path is None else "edit",
        "input": {"prompt": prompt},
        "parameters": {"aspect_ratio": aspect_ratio, "image_size": image_size},
    }
    if image_path:
        encoded = base64.b64encode(Path(image_path).read_bytes()).decode("utf-8")
        body["input"]["image"] = {"data": encoded, "mime_type": "image/png"}
    headers = {**HEADERS, "Idempotency-Key": str(uuid.uuid4())}
    status, task = call(API, body, headers, "POST")
    print("created", task["id"], "HTTP", status)
    return task


def wait(task_id, interval=3, timeout=300):
    deadline = time.time() + timeout
    while time.time() < deadline:
        _, task = call(f"{API}/{task_id}")
        print(task["status"], task["progress"]["percent"])
        if task["status"] in ("succeeded", "failed", "canceled"):
            return task
        time.sleep(interval)
    # A timeout is not a failure: keep the task id and poll it again.
    raise TimeoutError(f"task {task_id} is still running")


def download(task, out_path):
    asset = task["assets"][0]
    with urllib.request.urlopen(asset["url"], timeout=120) as resp:
        Path(out_path).write_bytes(resp.read())
    print("saved", out_path, asset["mime_type"], asset["byte_size"], "bytes")


if __name__ == "__main__":
    task = create_task(
        "A vintage travel poster for the Night Train from Zürich to Milano, "
        "departing 21:40 from platform 7. A steam train crosses a stone arch "
        "bridge below snowy mountains under a deep blue night sky, with a cream "
        "border. Spell every word exactly as written.",
        aspect_ratio="3:4",
        image_size="2K",
    )
    task = wait(task["id"])
    if task["status"] != "succeeded":
        raise SystemExit(f"{task['status']}: {task.get('error')}")
    download(task, "night-train.jpg")

image_size принимает 1K, 2K или 4K. Руководство Google по изображениям говорит прямо: "You must use an uppercase 'K' … Lowercase parameters (e.g., 1k) will be rejected." Отправляйте 2K, а не 2k.

Idempotency-Key обязателен. Самое простое правило — новый UUID на каждый запрос; повторяйте ключ только когда отправляете ровно то же тело заново. OmniaKey вернёт исходную задачу с HTTP 200 вместо повторного списания, а на тот же ключ с другим телом ответит 409.

Вызов создания возвращает 202 и id. Документация по медиазадачам OmniaKey описывает весь цикл; у готовой задачи есть поля, которые вы читаете:

json
{
  "id": "task_AbMRVqzSnVh0VwBj0S7NuMUxy5sZtfHP",
  "status": "succeeded",
  "progress": {"percent": 100, "stage": "completed"},
  "usage": {"total_tokens": 1133},
  "assets": [
    {
      "kind": "image",
      "mime_type": "…",
      "url": "https://…signed-url…"
    }
  ]
}

Прочитайте assets[0].url и скачайте сразу: подписанная ссылка живёт около часа, а запись задачи хранится 24 часа. Формат подскажет поле mime_type; модели Gemini обычно возвращают JPEG.

Тот же скрипт в 1:1 и 2K, с китайской вывеской в промпте, вернул вот это:

Тёмная металлическая вывеска на кирпичной стене, три строки китайского текста и номер телефона
2K, 1:1: 2048x2048 за 47.2 с. Все три китайские строки и 010-6789 4321 вернулись правильными; ржавчина закрывает часть первого 0.

Как отредактировать готовое изображение

Укажите operation: "edit" и передайте исходник в input.image в виде {data, mime_type}. Скрипт выше делает это сам, когда получает image_path:

python
task = create_task(
    "Hang this poster in a thin black frame on a warm white wall, with a brass "
    "picture light above it, a low wooden cabinet below and a trailing plant on "
    "the right. Keep the poster exactly as it is.",
    aspect_ratio="1:1",
    image_size="2K",
    image_path="night-train-2k.png",
)

Тело запроса выглядит так:

json
{
  "model": "gemini-3-pro-image",
  "type": "image",
  "operation": "edit",
  "input": {
    "prompt": "Hang this poster in a thin black frame on a warm white wall…",
    "image": {"data": "…base64…", "mime_type": "image/png"}
  },
  "parameters": {"aspect_ratio": "1:1", "image_size": "2K"}
}

Исходник в примере — PNG, поэтому скрипт ставит image/png; для JPEG поменяйте эту метку. Если нужно несколько референсов, используйте input.images и давайте каждому элементу ту же форму {data, mime_type}. Руководство Google ограничивает число референсов 14 изображениями; у gemini-3-pro-image расклад такой: 6 изображений объектов, 5 персонажей и 3 референса стиля.

Держите тело меньше 1 MiB. Base64 увеличивает файл примерно на треть, поэтому уменьшите или сожмите исходник до кодирования. Наша правка использовала постер 2K и сохранила каждое слово и вёрстку:

Постер ночного поезда в чёрной рамке на стене, сверху лампа для картины, справа растение
2K, правка 1:1: 2048x2048 за 49.9 с. Текст и рисунок постера сохранились; рамка получилась ровным прямоугольником.

1K, 2K и 4K: что даёт каждый размер

Мы прогнали один и тот же промпт постера в 3:4 во всех трёх размерах. Пиксели точно совпали с таблицей Google для 3:4: 896x1200 в 1K, 1792x2400 в 2K и 3584x4800 в 4K. Текст постера был правильным во всех размерах.

Постер ночного поезда в 1K: паровоз на каменном мосту, заснеженные горы и глубокое синее небо
1K, 3:4: 896x1200 за 28.4 с. Все четыре строки постера верны; фонари и дышла паровоза теснят друг друга.
Тот же постер ночного поезда в 2K, на правом склоне добавлены деревня и две башни
2K, 3:4: 1792x2400 за 48.2 с. Тот же текст плюс деревня и две башни на правом склоне.
Тот же постер ночного поезда в 4K, за паровозом нарисованы три вагона и тендер
4K, 3:4: 3584x4800 за 66.9 с. Три вагона и тендер прорисованы; швы кирпичной кладки разной толщины.

С размером меняется детализация, а не орфография:

  • 1K: передняя часть поезда тесная: фонари, колёса и дышла стоят вплотную.
  • 2K: на правом склоне появляются деревня и две башни, из трубы тянется бледная струйка дыма, у моста видно семь арок.
  • 4K: три вагона и тендер разделены, а в кладке видны швы разной толщины. Механизмы под паровозом всё ещё упрощены.

Скорость росла вместе с размером: 28.4 с, 48.2 с и 66.9 с. Каждый размер мы запускали один раз, так что эти секунды — один прогон.

Google считает вывод изображений по $120 за миллион токенов, и в его таблице 1,120 токенов и для 1K, и для 2K, а для 4K — 2,000 токенов. Отсюда его собственная оценка:

text
1,120 × $120 ÷ 1,000,000 = $0.134 per 1K image
1,120 × $120 ÷ 1,000,000 = $0.134 per 2K image
2,000 × $120 ÷ 1,000,000 = $0.24  per 4K image

Наши задачи отчитались о большем числе токенов, чем примеры Google. Вот та же арифметика на наших числах:

text
1,133 × $120 ÷ 1,000,000 = $0.136 per 1K image
1,225 × $120 ÷ 1,000,000 = $0.147 per 2K image
2,480 × $120 ÷ 1,000,000 = $0.298 per 4K image
РазмерПиксели, 3:4Наше времяНаши токеныОценка Google
1K896x120028.4 с1,133$0.134
2K1792x240048.2 с1,225$0.134
4K3584x480066.9 с2,480$0.24

OmniaKey берёт за вызов изображения фиксированную плату, а не по токенам, поэтому его сумма не меняется от этих счётчиков; актуальная цена за вызов есть на странице модели, а неудачная задача возвращается на счёт. Оценка Google по токенам для тех же трёх изображений — $0.134, $0.134 и $0.24.

Ошибки, которые встретятся

Почти все сбои здесь сводятся к имени поля или размеру файла, а не к модели. Вот те, что перечислены в документации OmniaKey по медиа для этого эндпоинта:

HTTPКод или статусЧто это значитЧто делать
400invalid_requestТело не разобрано, операция не поддерживается или параметр неверныйПроверьте JSON и имена полей ниже
503no_available_channelСейчас эту модель не обслуживает ни один каналСмените модель; повтор запроса не поможет
—failedЗадача закончилась без результатаПрочитайте error.code и error.message

Задача failed — не HTTP-ошибка: вызов создания прошёл успешно, поэтому опросите задачу и прочитайте её объект error. Неудачные и отменённые задачи возвращаются автоматически.

Исходник в полном разрешении в Base64 легко выталкивает тело за 1 MiB. Сначала уменьшите картинку и проверьте длину после кодирования, а не только размер файла.

Руководство Google отвергает строчную 1k. Пишите 1K, 2K или 4K.

Документация OmniaKey по изображениям также отвергает size и mime_type верхнего уровня у моделей Gemini: это не параметры Gemini. Используйте parameters.aspect_ratio и parameters.image_size, а формат вывода читайте в поле mime_type ответа.

Частые вопросы

Какой ID модели у Nano Banana Pro API?

gemini-3-pro-image. Карточка модели Vertex указывает GA и дату выхода 28 мая 2026 года, и OmniaKey принимает тот же ID. Старый gemini-3-pro-image-preview в OmniaKey тоже работает и указывает на ту же модель.

Сколько стоит одно изображение Nano Banana Pro?

Google оценивает 1K или 2K изображение в $0.134, а 4K — в $0.24, при $120 за миллион токенов изображения. Наши задачи отчитались о 1,133, 1,225 и 2,480 токенах, то есть $0.136, $0.147 и $0.298 по этому тарифу. Страница модели в OmniaKey показывает свою цену за вызов.

Nano Banana Pro умеет рисовать китайский текст?

Да. Наша вывеска в 2K вернулась с тремя правильными китайскими строками — 同福客栈, 住宿 餐饮 茶水 и 010-6789 4321 — включая все 11 цифр и дефис.

Что просить: 1K, 2K или 4K?

Для постера, как у нас, 2K — полезная середина. Все три размера написали постер правильно, поэтому 4K покупает более мелкую детализацию — отдельные вагоны, швы кладки, — а не лучший текст. Для черновиков, где хватает 896x1200, берите 1K.

Почему правка вернула 400 invalid_request?

Обычные причины: тело больше 1 MiB, исходник в неверном поле или модель Gemini получает size либо mime_type верхнего уровня. Положите изображение в input.image в виде {data, mime_type}, держите тело после кодирования меньше 1 MiB и используйте aspect_ratio и image_size.

Проверенные источники

Журнал обновлений

  • 2026-11-03: первая версия; в тот день через OmniaKey прошло пять тестовых вызовов.

Модели в этой статье

Nano Banana ProGemini изображенияAPI изображенийPythonТуториал по API

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

Недавние статьи

Популярные руководства