|

4 ключевых различия между синхронными и асинхронными вызовами Nano Banana Pro API

При вызове Nano Banana Pro API для генерации изображений, в чем разница между синхронным и асинхронным вызовами? На данный момент и APIYI, и официальный Gemini поддерживают только синхронный режим, но APIYI значительно улучшил пользовательский опыт, предоставляя вывод изображений через OSS URL. В этой статье мы системно разберем ключевые различия между синхронным и асинхронным подходами, а также изучим оптимизации формата вывода на платформе APIYI.

Основная ценность: Прочитав этот материал, вы поймете фундаментальную разницу между синхронными и асинхронными вызовами в дизайне API, узнаете о преимуществах OSS URL в APIYI перед кодировкой base64 и научитесь выбирать оптимальную схему получения изображений для вашего проекта.

nano-banana-pro-sync-async-api-comparison-ru 图示

Сравнение режимов вызова API Nano Banana Pro

Характеристика Синхронный вызов (Synchronous) Асинхронный вызов (Asynchronous) Текущая поддержка APIYI
Режим соединения Удержание HTTP-соединения до завершения Немедленный возврат ID задачи, закрытие соединения ✅ Синхронный вызов
Способ ожидания Блокирующее ожидание (30–170 сек) Неблокирующее: опрос (polling) или Webhook ✅ Синхронно (блокирующее ожидание)
Риск таймаута Высокий (нужен таймаут 300–600 сек) Низкий (короткий таймаут только для отправки) ⚠️ Требуется настройка таймаута
Сложность реализации Низкая (выполняется за один запрос) Средняя (нужен опрос или Webhook) ✅ Просто и удобно
Сценарии использования Генерация в реальном времени, мгновенный показ Пакетная обработка, фоновые задачи ✅ Генерация в реальном времени
Оптимизация затрат Стандартная цена Google Batch API экономит до 50%

Как работает синхронный вызов

Синхронный вызов (Synchronous Call) работает по модели Запрос — Ожидание — Ответ:

  1. Клиент инициирует запрос: Отправляет запрос на генерацию изображения на сервер.
  2. Удержание HTTP-соединения: Клиент держит TCP-соединение открытым, ожидая, пока сервер закончит инференс.
  3. Блокирующее ожидание: В течение 30–170 секунд, пока идет генерация, клиент не может выполнять другие операции в рамках этого потока.
  4. Получение полного ответа: Сервер возвращает данные сгенерированного изображения (base64 или URL).
  5. Закрытие соединения: После завершения HTTP-соединение закрывается.

Ключевая особенность: Синхронный вызов является блокирующим (Blocking). Клиент обязан дождаться ответа сервера, прежде чем продолжить выполнение кода. Это требует установки достаточно длинного времени ожидания (рекомендуется 300 секунд для 1K/2K и 600 секунд для 4K), чтобы соединение не оборвалось до завершения генерации.

Как работает асинхронный вызов

Асинхронный вызов (Asynchronous Call) работает по модели Запрос — Принятие — Уведомление:

  1. Клиент отправляет задачу: Передает запрос на генерацию на сервер.
  2. Мгновенный возврат ID задачи: Сервер принимает запрос, выдает ID задачи (например, task_abc123) и тут же закрывает соединение.
  3. Фоновый инференс: Сервер генерирует изображение в фоновом режиме, а клиент в это время может заниматься другими делами.
  4. Получение результата: Клиент узнает о готовности одним из двух способов:
    • Опрос (Polling): Периодически запрашивает статус через /tasks/task_abc123/status.
    • Webhook: По завершении задачи сервер сам «стучится» по URL-адресу обратного вызова, предоставленному клиентом.
  5. Загрузка изображения: После завершения задачи изображение скачивается по полученной ссылке.

Ключевая особенность: Асинхронный вызов является неблокирующим (Non-blocking). Клиент может обрабатывать другие запросы сразу после отправки задачи, не поддерживая соединение долго. Это идеально подходит для пакетной обработки и сценариев, где не важна мгновенная реакция интерфейса.

💡 Технический совет: Платформа APIYI на данный момент поддерживает только синхронный режим вызова. Однако благодаря оптимизации таймаутов и выводу через OSS URL, нам удалось добиться отличного пользовательского опыта. Если вам нужно генерировать изображения пачками, рекомендуем использовать платформу APIYI (apiyi.com) — она предоставляет стабильные HTTP-интерфейсы с грамотно настроенными таймаутами и поддержкой высокой нагрузки при синхронных вызовах.

nano-banana-pro-sync-async-api-comparison-ru 图示

Основное отличие 1: Время удержания соединения и настройка тайм-аутов

Требования к удержанию соединения при синхронном вызове

Синхронный вызов требует, чтобы клиент поддерживал HTTP-соединение открытым на протяжении всего процесса генерации изображения. Это создает следующие технические сложности:

Сложность Влияние Решение
Длительный простой соединения Промежуточное сетевое оборудование (NAT, брандмауэры) может разорвать соединение Настройка TCP Keep-Alive
Сложная настройка тайм-аутов Необходимо точно настраивать время ожидания в зависимости от разрешения 1K/2K: 300 сек, 4K: 600 сек
Чувствительность к сетевым колебаниям В нестабильных сетях соединение часто обрывается Реализация механизмов повторов (retry)
Ограничение параллельных соединений Браузеры по умолчанию поддерживают не более 6 параллельных соединений Использование серверных вызовов или пула соединений

Пример синхронного вызова на Python:

import requests
import time

def generate_image_sync(prompt: str, size: str = "4096x4096") -> dict:
    """
    Синхронный вызов API Nano Banana Pro для генерации изображения

    Args:
        prompt: промпт для изображения
        size: размер изображения

    Returns:
        Результат ответа API
    """
    start_time = time.time()

    # Синхронный вызов: удерживаем соединение до завершения генерации
    response = requests.post(
        "http://api.apiyi.com:16888/v1/images/generations",
        json={
            "prompt": prompt,
            "size": size,
            "model": "nano-banana-pro",
            "n": 1,
            "response_format": "url"  # APIYI поддерживает вывод URL
        },
        headers={"Authorization": "Bearer YOUR_API_KEY"},
        timeout=(10, 600)  # Таймаут соединения 10 сек, чтения — 600 сек
    )

    elapsed = time.time() - start_time
    print(f"⏱️ Затрачено времени на синхронный вызов: {elapsed:.2f} сек")
    print(f"🔗 Статус соединения: оставалось открытым {elapsed:.2f} сек")

    return response.json()


# Пример использования
result = generate_image_sync(
    prompt="A futuristic cityscape at sunset",
    size="4096x4096"
)

print(f"✅ URL изображения: {result['data'][0]['url']}")

Ключевые наблюдения:

  • Клиент полностью заблокирован на 100-170 секунд времени инференса (вывода модели).
  • HTTP-соединение остается открытым, потребляя системные ресурсы.
  • Если тайм-аут настроен неправильно (например, 60 секунд), соединение разорвется до завершения генерации.

Преимущества коротких соединений при асинхронном вызове

Асинхронный вызов устанавливает короткие соединения только в моменты отправки задачи и проверки статуса, что значительно сокращает время удержания соединения:

Этап Время соединения Настройка тайм-аута
Отправка задачи 1-3 сек 30 сек достаточно
Опрос статуса 1-2 сек за раз 10 сек достаточно
Загрузка изображения 5-10 сек 60 сек достаточно
Итого 10-20 сек (суммарно) Гораздо меньше, чем при синхронном вызове

Пример асинхронного вызова на Python (имитация будущей поддержки APIYI):

import requests
import time

def generate_image_async(prompt: str, size: str = "4096x4096") -> str:
    """
    Асинхронный вызов API Nano Banana Pro для генерации изображения (будущий функционал)

    Args:
        prompt: промпт для изображения
        size: размер изображения

    Returns:
        ID задачи
    """
    # Шаг 1: Отправка задачи (короткое соединение)
    response = requests.post(
        "http://api.apiyi.com:16888/v1/images/generations/async",  # Будущий эндпоинт
        json={
            "prompt": prompt,
            "size": size,
            "model": "nano-banana-pro",
            "n": 1,
            "response_format": "url"
        },
        headers={"Authorization": "Bearer YOUR_API_KEY"},
        timeout=(10, 30)  # Для отправки задачи достаточно 30 секунд
    )

    task_data = response.json()
    task_id = task_data["task_id"]
    print(f"✅ Задача отправлена: {task_id}")
    print(f"🔓 Соединение закрыто, можно выполнять другие задачи")

    return task_id


def poll_task_status(task_id: str, max_wait: int = 300) -> dict:
    """
    Опрос статуса задачи до завершения

    Args:
        task_id: ID задачи
        max_wait: Максимальное время ожидания (сек)

    Returns:
        Результат генерации
    """
    start_time = time.time()
    poll_interval = 5  # Опрос каждые 5 секунд

    while time.time() - start_time < max_wait:
        # Запрос статуса задачи (короткое соединение)
        response = requests.get(
            f"http://api.apiyi.com:16888/v1/tasks/{task_id}",  # Будущий эндпоинт
            headers={"Authorization": "Bearer YOUR_API_KEY"},
            timeout=(10, 10)  # Для запроса статуса достаточно 10 секунд
        )

        status_data = response.json()
        status = status_data["status"]

        if status == "completed":
            elapsed = time.time() - start_time
            print(f"✅ Задача выполнена! Общее время: {elapsed:.2f} сек")
            return status_data["result"]

        elif status == "failed":
            raise Exception(f"Ошибка задачи: {status_data.get('error')}")

        else:
            print(f"⏳ Статус задачи: {status}, ожидание {poll_interval} сек перед повтором...")
            time.sleep(poll_interval)

    raise TimeoutError(f"Время ожидания задачи истекло: {task_id}")


# Пример использования
task_id = generate_image_async(
    prompt="A serene mountain landscape",
    size="4096x4096"
)

# Во время ожидания можно обрабатывать другие задачи
print("🚀 Можно параллельно обрабатывать другие запросы...")

# Опрос статуса задачи
result = poll_task_status(task_id, max_wait=600)
print(f"✅ URL изображения: {result['data'][0]['url']}")
Посмотреть пример режима Webhook (будущий функционал)
from flask import Flask, request, jsonify
import requests

app = Flask(__name__)

# Глобальный словарь для хранения результатов задач
task_results = {}


@app.route('/webhook/image_completed', methods=['POST'])
def handle_webhook():
    """Прием Webhook-уведомления о завершении асинхронной задачи APIYI"""
    data = request.json

    task_id = data['task_id']
    status = data['status']
    result = data.get('result')

    if status == 'completed':
        task_results[task_id] = result
        print(f"✅ Задача {task_id} завершена: {result['data'][0]['url']}")
    else:
        print(f"❌ Задача {task_id} провалена: {data.get('error')}")

    return jsonify({"received": True}), 200


def generate_image_with_webhook(prompt: str, size: str = "4096x4096") -> str:
    """
    Асинхронная генерация изображения с использованием Webhook

    Args:
        prompt: промпт для изображения
        size: размер изображения

    Returns:
        ID задачи
    """
    response = requests.post(
        "http://api.apiyi.com:16888/v1/images/generations/async",
        json={
            "prompt": prompt,
            "size": size,
            "model": "nano-banana-pro",
            "n": 1,
            "response_format": "url",
            "webhook_url": "https://your-domain.com/webhook/image_completed"  # URL для обратного вызова
        },
        headers={"Authorization": "Bearer YOUR_API_KEY"},
        timeout=(10, 30)
    )

    task_id = response.json()["task_id"]
    print(f"✅ Задача отправлена: {task_id}")
    print(f"📞 Webhook придет на: https://your-domain.com/webhook/image_completed")

    return task_id


# Запуск Flask-сервера для прослушивания Webhook
if __name__ == '__main__':
    app.run(host='0.0.0.0', port=5000)

🎯 Текущее ограничение: В настоящее время и APIYI, и официальный API Gemini поддерживают только синхронный режим. Асинхронные вызовы планируется внедрить в будущих версиях. Если вам нужна высокая параллельность при генерации изображений, рекомендуем использовать многопоточность или многопроцессорность для вызова синхронных интерфейсов через платформу APIYI (apiyi.com), не забывая о разумных тайм-аутах.

Основное отличие 2: Параллельная обработка и потребление ресурсов

Ограничения параллелизма при синхронных вызовах

Синхронные вызовы в сценариях с высокой нагрузкой сталкиваются с серьезными проблемами потребления ресурсов:

Проблема блокировки одного потока:

import time

# ❌ ОШИБКА: Последовательный вызов в одном потоке, общее время = время одного вызова × кол-во задач
def generate_multiple_images_sequential(prompts: list) -> list:
    results = []
    start_time = time.time()

    for prompt in prompts:
        result = generate_image_sync(prompt, size="4096x4096")
        results.append(result)

    elapsed = time.time() - start_time
    print(f"❌ Время последовательной генерации {len(prompts)} изображений: {elapsed:.2f} сек")
    # Если на одно фото уходит 120 сек, то 10 фото = 1200 сек (20 минут!)

    return results

Оптимизация с помощью многопоточности:

from concurrent.futures import ThreadPoolExecutor, as_completed
import time

# ✅ ПРАВИЛЬНО: Многопоточный вызов, эффективно использующий время ожидания I/O
def generate_multiple_images_concurrent(prompts: list, max_workers: int = 5) -> list:
    """
    Многопоточная параллельная генерация нескольких изображений

    Args:
        prompts: список промптов
        max_workers: максимальное количество потоков

    Returns:
        Список результатов генерации
    """
    results = []
    start_time = time.time()

    with ThreadPoolExecutor(max_workers=max_workers) as executor:
        # Отправляем все задачи
        future_to_prompt = {
            executor.submit(generate_image_sync, prompt, "4096x4096"): prompt
            for prompt in prompts
        }

        # Ждем завершения всех задач
        for future in as_completed(future_to_prompt):
            prompt = future_to_prompt[future]
            try:
                result = future.result()
                results.append(result)
                print(f"✅ Готово: {prompt[:30]}...")
            except Exception as e:
                print(f"❌ Ошибка: {prompt[:30]}... - {e}")

    elapsed = time.time() - start_time
    print(f"✅ Время параллельной генерации {len(prompts)} изображений: {elapsed:.2f} сек")
    # Допустим, на одно фото 120 сек, 10 фото ≈ 120-150 сек (2-2.5 минуты)

    return results


# Пример использования
prompts = [
    "A cyberpunk city at night",
    "A serene forest landscape",
    "An abstract geometric pattern",
    "A futuristic space station",
    "A vintage car in the desert",
    # ...и так далее
]

results = generate_multiple_images_concurrent(prompts, max_workers=5)
print(f"🎉 Сгенерировано {len(results)} изображений")
Способ параллелизма Время для 10 изображений 4K Потребление ресурсов Подходящий сценарий
Последовательно 1200 сек (20 мин) Низкое (1 соединение) Одно изображение, real-time
Многопоточность (5 потоков) 250 сек (4 мин) Среднее (5 соединений) Небольшие партии (10-50 шт)
Многопроцессорность (10 проц.) 150 сек (2.5 мин) Высокое (10 соединений) Большие партии (50+ шт)
Асинхронно (в будущем) 120 сек + опрос Низкое (короткие опросы) Массовая обработка (100+ шт)

Преимущества асинхронного параллелизма

Асинхронные вызовы дают огромное преимущество при пакетной обработке:

Пакетная отправка + Пакетный опрос:

def generate_batch_async(prompts: list) -> list:
    """
    Пакетная асинхронная генерация изображений (будущий функционал)

    Args:
        prompts: список промптов

    Returns:
        Список ID задач
    """
    task_ids = []

    # Шаг 1: Быстрая пакетная отправка всех задач (каждая по 1-3 сек)
    for prompt in prompts:
        task_id = generate_image_async(prompt, size="4096x4096")
        task_ids.append(task_id)

    print(f"✅ Пакетно отправлено {len(task_ids)} задач, затрачено около {len(prompts) * 2} сек")

    # Шаг 2: Пакетный опрос статуса задач
    results = []
    for task_id in task_ids:
        result = poll_task_status(task_id, max_wait=600)
        results.append(result)

    return results
Показатель Синхронный (многопоточность) Асинхронный (будущее) Разница
Время этапа отправки 1200 сек (ожидание) 20 сек (быстрая отправка) Асинхронный в 60 раз быстрее
Общее время 250 сек (5 потоков) 120 сек + опрос Асинхронный в 2 раза быстрее
Пик соединений 5 длинных соединений 1 короткое (в момент отправки) Асинхронный экономит 80%
Другие задачи ❌ Потоки заблокированы ✅ Полностью неблокирующий Асинхронный гибче

nano-banana-pro-sync-async-api-comparison-ru 图示

💰 Оптимизация затрат: Google Gemini API предлагает режим Batch API, который поддерживает асинхронную обработку со скидкой 50% (стандартная цена $0.133-$0.24 за фото, через Batch API — $0.067-$0.12). Однако при этом нужно быть готовым к ожиданию результата до 24 часов. Это отличный вариант для задач, где не требуется мгновенная выдача изображения.

Ключевое отличие 3: Преимущества вывода через OSS URL на платформе APIYI

Сравнение кодировки base64 и вывода через URL

API Nano Banana Pro поддерживает два формата вывода изображений:

Особенность Кодировка base64 Вывод через OSS URL (эксклюзивно для APIYI) Рекомендация
Размер тела ответа 6-8 МБ (для 4K) ~200 байт (только URL) URL ✅
Время передачи 5-10 сек (еще медленнее при плохом соединении) < 1 сек URL ✅
Кэширование в браузере ❌ Невозможно ✅ Стандартное HTTP-кэширование URL ✅
CDN-ускорение ❌ Недоступно ✅ Глобальное ускорение через CDN URL ✅
Оптимизация изображений ❌ Нет поддержки WebP и др. ✅ Поддержка конвертации форматов URL ✅
Прогрессивная загрузка ❌ Только полная загрузка ✅ Поддержка прогрессивной загрузки URL ✅
Мобильная производительность ❌ Высокое потребление памяти ✅ Оптимизированный поток загрузки URL ✅

Проблемы производительности base64:

  1. Раздувание тела ответа на 33%: кодировка base64 увеличивает объем данных примерно на треть.

    • Исходное 4K-изображение: около 6 МБ.
    • После кодирования в base64: около 8 МБ.
  2. Невозможность использования CDN: строка base64 встроена в JSON-ответ, поэтому её нельзя закэшировать через CDN.

  3. Нагрузка на память мобильных устройств: декодирование строки base64 требует дополнительных ресурсов памяти и процессора.

Преимущества вывода через OSS URL в APIYI:

import requests

# ✅ Рекомендовано: использование вывода через OSS URL в APIYI
response = requests.post(
    "http://api.apiyi.com:16888/v1/images/generations",
    json={
        "prompt": "A beautiful sunset over mountains",
        "size": "4096x4096",
        "model": "nano-banana-pro",
        "n": 1,
        "response_format": "url"  # Указываем вывод URL
    },
    headers={"Authorization": "Bearer YOUR_API_KEY"},
    timeout=(10, 600)
)

result = response.json()

# Тело ответа содержит только URL, размер около 200 байт
print(f"Размер тела ответа: {len(response.content)} байт")
# Вывод: Размер тела ответа: 234 байт

# Пример OSS URL
image_url = result['data'][0]['url']
print(f"URL изображения: {image_url}")
# Вывод: https://apiyi-oss.oss-cn-beijing.aliyuncs.com/nano-banana/abc123.png

# Далее загружаем изображение через стандартный HTTP-запрос, используя преимущества CDN
image_response = requests.get(image_url)
with open("output.png", "wb") as f:
    f.write(image_response.content)

Для сравнения: проблемы производительности при выводе в base64:

# ❌ Не рекомендуется: вывод в кодировке base64
response = requests.post(
    "https://api.example.com/v1/images/generations",
    json={
        "prompt": "A beautiful sunset over mountains",
        "size": "4096x4096",
        "model": "nano-banana-pro",
        "n": 1,
        "response_format": "b64_json"  # Кодировка base64
    },
    headers={"Authorization": "Bearer YOUR_API_KEY"},
    timeout=(10, 600)
)

result = response.json()

# Тело ответа содержит полную строку base64, размер около 8 МБ
print(f"Размер тела ответа: {len(response.content)} байт")
# Вывод: Размер тела ответа: 8388608 байт (8 МБ!)

# Требуется декодирование строки base64
import base64
image_b64 = result['data'][0]['b64_json']
image_bytes = base64.b64decode(image_b64)

with open("output.png", "wb") as f:
    f.write(image_bytes)
Показатель сравнения Кодировка base64 APIYI OSS URL Прирост производительности
Размер ответа API 8 МБ 200 байт Меньше на 99.998%
Время ответа API 125 сек + 5-10 сек передачи 125 сек + < 1 сек Экономия 5-10 сек
Способ загрузки фото Встроено в JSON Отдельный HTTP-запрос Возможна параллельная загрузка
Кэш браузера Не кэшируется Стандартный HTTP-кэш Мгновенное открытие при повторном доступе
CDN-ускорение Не поддерживается Глобальные узлы CDN Ускорение при международном доступе

🚀 Рекомендуемая конфигурация: При вызове Nano Banana Pro API на платформе APIYI всегда используйте response_format: "url" для получения OSS URL вместо кодировки base64. Это не только значительно уменьшит размер ответа API и время передачи, но и позволит в полной мере использовать CDN-ускорение и кэширование браузера, улучшая пользовательский опыт.

Ключевое отличие 4: Сценарии использования и планы на будущее

Лучшие сценарии для синхронных вызовов

Рекомендуемые сценарии:

  1. Генерация изображений в реальном времени: отображение результата пользователю сразу после ввода промпта.
  2. Мелкосерийная обработка: генерация 1–10 изображений; параллельных вызовов достаточно для обеспечения производительности.
  3. Простая интеграция: нет необходимости реализовывать опрос (polling) или вебхуки, что снижает сложность разработки.
  4. Интерактивные приложения: инструменты для рисования на базе ИИ, редакторы изображений и другие сценарии, требующие мгновенной обратной связи.

Типовой шаблон кода:

from flask import Flask, request, jsonify
import requests

app = Flask(__name__)

@app.route('/generate', methods=['POST'])
def generate_image():
    """Интерфейс генерации изображений в реальном времени"""
    data = request.json
    prompt = data['prompt']
    size = data.get('size', '1024x1024')

    # Синхронный вызов, пользователь ждет завершения генерации
    response = requests.post(
        "http://api.apiyi.com:16888/v1/images/generations",
        json={
            "prompt": prompt,
            "size": size,
            "model": "nano-banana-pro",
            "n": 1,
            "response_format": "url"
        },
        headers={"Authorization": "Bearer YOUR_API_KEY"},
        timeout=(10, 300 if size != '4096x4096' else 600)
    )

    result = response.json()
    return jsonify({
        "success": True,
        "image_url": result['data'][0]['url']
    })

if __name__ == '__main__':
    app.run(host='0.0.0.0', port=8000)

Будущие сценарии для асинхронных вызовов

Применимые сценарии (будущая поддержка):

  1. Массовая генерация: создание более 100 изображений (например, карточки товаров для e-commerce, библиотеки дизайнерских материалов).
  2. Фоновые задачи по расписанию: ежедневная автоматическая генерация определенных типов изображений, не требующая мгновенного ответа.
  3. Бюджетная обработка: использование Google Batch API для получения скидки 50% при готовности ждать выполнения до 24 часов.
  4. Высококонкурентные сценарии: сотни пользователей одновременно отправляют запросы, что позволяет избежать исчерпания пула соединений.

Типовой шаблон кода (в перспективе):

from flask import Flask, request, jsonify
from celery import Celery
import requests

app = Flask(__name__)
celery = Celery('tasks', broker='redis://localhost:6379/0')

@celery.task
def generate_image_task(prompt: str, size: str, user_id: str):
    """Задача Celery: асинхронная генерация изображения"""
    # Отправка асинхронной задачи в APIYI
    response = requests.post(
        "http://api.apiyi.com:16888/v1/images/generations/async",  # Будущий интерфейс
        json={
            "prompt": prompt,
            "size": size,
            "model": "nano-banana-pro",
            "n": 1,
            "response_format": "url",
            "webhook_url": f"https://your-domain.com/webhook/{user_id}"
        },
        headers={"Authorization": "Bearer YOUR_API_KEY"},
        timeout=(10, 30)
    )

    task_id = response.json()["task_id"]
    return task_id


@app.route('/generate_async', methods=['POST'])
def generate_image_async():
    """Интерфейс асинхронной генерации изображений"""
    data = request.json
    prompt = data['prompt']
    size = data.get('size', '1024x1024')
    user_id = data['user_id']

    # Запуск задачи Celery и мгновенный возврат ответа
    task = generate_image_task.delay(prompt, size, user_id)

    return jsonify({
        "success": True,
        "message": "Задача принята, уведомление придет через Webhook по завершении",
        "task_id": task.id
    })


@app.route('/webhook/<user_id>', methods=['POST'])
def handle_webhook(user_id: str):
    """Прием обратного вызова Webhook от APIYI о завершении задачи"""
    data = request.json
    task_id = data['task_id']
    result = data['result']

    # Уведомление пользователя о завершении (email, push-уведомление и т.д.)
    notify_user(user_id, result['data'][0]['url'])

    return jsonify({"received": True}), 200

Планы развития платформы APIYI

Функция Текущий статус Планы на будущее Ожидаемый срок
Синхронный вызов ✅ Поддерживается Оптимизация настроек таймаута
Вывод через OSS URL ✅ Поддерживается Увеличение количества узлов CDN 2-й кв. 2026
Асинхронный вызов (опрос) ❌ Не поддерживается Поддержка отправки задач + проверка статуса 2-й кв. 2026
Асинхронный вызов (Webhook) ❌ Не поддерживается Поддержка уведомлений о завершении задачи 2-й кв. 2026
Интеграция Batch API ❌ Не поддерживается Интеграция с Google Batch API 4-й кв. 2026

💡 Совет для разработчиков: APIYI планирует запустить функционал асинхронных вызовов в третьем квартале 2026 года, включая отправку задач, опрос статуса и уведомления через Webhook. Для текущих потребностей в массовой обработке рекомендуем использовать многопоточность для вызова синхронных интерфейсов через платформу APIYI (apiyi.com), которая предоставляет стабильные HTTP-порты и оптимизированные настройки таймаута.

Часто задаваемые вопросы

Q1: Почему ни APIYI, ни официальный Gemini не поддерживают асинхронные вызовы?

Технические причины:

  1. Ограничения инфраструктуры Google: Базовая инфраструктура Google Gemini API на данный момент поддерживает только синхронный режим вывода. Асинхронные вызовы требуют дополнительных систем очередей задач и управления состоянием.

  2. Сложность разработки: Для реализации асинхронности нужно внедрить:

    • Управление очередями задач
    • Постоянное хранение (персистентность) статуса задач
    • Механизм Webhook-уведомлений
    • Логику повторных попыток и компенсации сбоев
  3. Приоритеты пользователей: Большинству пользователей генерация изображений нужна в реальном времени. Синхронные вызовы закрывают более 80% всех сценариев.

Решения:

  • Сейчас: используйте многопоточность или многопроцессность для параллельного вызова синхронных интерфейсов.
  • В будущем: APIYI планирует запустить поддержку асинхронных вызовов во втором квартале (Q2) 2026 года.
Q2: Будут ли изображения по OSS URL от APIYI храниться вечно?

Стратегия хранения:

Срок хранения Описание Подходящие сценарии
7 дней Хранятся 7 дней по умолчанию, затем удаляются Временный предпросмотр, тесты
30 дней Для платных пользователей срок может быть продлен до 30 дней Краткосрочные проекты, материалы для акций
Бессрочно Пользователь сам скачивает файл в свое хранилище OSS Длительное использование, коммерческие проекты

Рекомендуемый подход:

import requests

# Генерируем изображение и получаем URL
result = generate_image_sync(prompt="A beautiful landscape", size="4096x4096")
temp_url = result['data'][0]['url']
print(f"Временный URL: {temp_url}")

# Скачиваем изображение локально или в свой OSS
image_response = requests.get(temp_url)
with open("permanent_image.png", "wb") as f:
    f.write(image_response.content)

# Или загружаем в свой OSS (на примере Alibaba Cloud OSS)
import oss2
auth = oss2.Auth('YOUR_ACCESS_KEY', 'YOUR_SECRET_KEY')
bucket = oss2.Bucket(auth, 'oss-cn-beijing.aliyuncs.com', 'your-bucket')
bucket.put_object('images/permanent_image.png', image_response.content)

Обратите внимание: URL-адреса OSS, предоставляемые APIYI, предназначены для временного хранения. Это удобно для быстрого просмотра и отладки. Если изображение нужно вам надолго, не забудьте вовремя скачать его на свой компьютер или в облако.

Q3: Как избежать тайм-аутов при синхронном вызове?

3 ключевых настройки, чтобы всё работало без сбоев:

  1. Правильно настройте время ожидания (timeout):

    # ✅ Правильно: раздельно настраиваем таймаут на соединение и на чтение
    timeout=(10, 600)  # (подключение — 10 сек, ожидание ответа — 600 сек)
    
    # ❌ Неправильно: установка одного общего значения
    timeout=600  # может сработать только для установки соединения
    
  2. Используйте интерфейс через HTTP-порт:

    # ✅ Рекомендуется: используйте HTTP-порт APIYI, чтобы избежать затрат на HTTPS-рукопожатие
    url = "http://api.apiyi.com:16888/v1/images/generations"
    
    # ⚠️ Опционально: HTTPS-интерфейс, увеличивает время TLS-рукопожатия
    url = "https://api.apiyi.com/v1/images/generations"
    
  3. Реализуйте механизм повторных попыток:

    from requests.adapters import HTTPAdapter
    from requests.packages.urllib3.util.retry import Retry
    
    # Настройка стратегии ретраев
    retry_strategy = Retry(
        total=3,  # максимум 3 попытки
        status_forcelist=[429, 500, 502, 503, 504],  # повторять только при этих кодах
        backoff_factor=2  # экспоненциальная задержка: 2с, 4с, 8с
    )
    
    adapter = HTTPAdapter(max_retries=retry_strategy)
    session = requests.Session()
    session.mount("http://", adapter)
    
    # Используем сессию для запроса
    response = session.post(
        "http://api.apiyi.com:16888/v1/images/generations",
        json={...},
        timeout=(10, 600)
    )
    
Q4: Как вызывать Nano Banana Pro API напрямую из фронтенда?

Почему мы НЕ рекомендуем вызывать API прямо из браузера:

  1. Риск утечки API Key: ваш ключ станет доступен любому пользователю через код страницы.
  2. Ограничения браузера на параллелизм: браузеры обычно ограничивают количество одновременных соединений с одним доменом (до 6).
  3. Лимиты по времени: у fetch в браузере часто стоят короткие таймауты по умолчанию, которых может не хватить для долгой генерации.

Рекомендуемая архитектура: режим проксирования через бэкенд:

// Код фронтенда (пример на React)
async function generateImage(prompt, size) {
  // Вызываем свой бэкенд
  const response = await fetch('https://your-backend.com/api/generate', {
    method: 'POST',
    headers: {
      'Content-Type': 'application/json',
      'Authorization': 'Bearer YOUR_USER_TOKEN'  // Токен вашего пользователя
    },
    body: JSON.stringify({ prompt, size })
  });

  const result = await response.json();
  return result.image_url;  // Получаем URL от OSS APIYI
}

// Использование
const imageUrl = await generateImage("A futuristic city", "4096x4096");
document.getElementById('result-image').src = imageUrl;
# Код бэкенда (пример на Flask)
from flask import Flask, request, jsonify
import requests

app = Flask(__name__)

@app.route('/api/generate', methods=['POST'])
def generate():
    # Проверяем токен пользователя
    user_token = request.headers.get('Authorization')
    if not verify_user_token(user_token):
        return jsonify({"error": "Unauthorized"}), 401

    data = request.json

    # Бэкенд вызывает API APIYI (ключ в безопасности и не виден фронтенду)
    response = requests.post(
        "http://api.apiyi.com:16888/v1/images/generations",
        json={
            "prompt": data['prompt'],
            "size": data['size'],
            "model": "nano-banana-pro",
            "n": 1,
            "response_format": "url"
        },
        headers={"Authorization": "Bearer YOUR_APIYI_API_KEY"},  # Ключ хранится в секретах бэкенда
        timeout=(10, 600)
    )

    result = response.json()
    return jsonify({"image_url": result['data'][0]['url']})

Итоги

Основные моменты по синхронным и асинхронным вызовам Nano Banana Pro API:

  1. Особенности синхронного вызова: HTTP-соединение удерживается до завершения генерации. Ожидание может длиться от 30 до 170 секунд, поэтому важно настроить длинные таймауты (300–600 секунд).
  2. Преимущества асинхронности: Мгновенный возврат ID задачи, отсутствие блокировки, идеально для пакетной обработки. Однако на данный момент ни APIYI, ни официальный Gemini это не поддерживают.
  3. Вывод через OSS URL: По сравнению с кодировкой base64, размер тела ответа уменьшается на 99,998%. Поддерживается ускорение через CDN и кэширование в браузере, что заметно повышает производительность.
  4. Лучшие практики сегодня: Используйте синхронные вызовы + многопоточность + вывод через OSS URL. Для оптимизации таймаутов лучше подключаться через специальный HTTP-порт APIYI.
  5. Планы на будущее: APIYI планирует запустить полноценную асинхронность во втором квартале 2026 года (с очередями, проверкой статуса и Webhook-ами).

Для быстрой интеграции Nano Banana Pro API рекомендуем использовать платформу APIYI (apiyi.com). Там уже доступны оптимизированные HTTP-интерфейсы (http://api.apiyi.com:16888/v1), эксклюзивный вывод картинок через OSS URL и правильно настроенные конфигурации таймаутов, что идеально подходит как для генерации в реальном времени, так и для массовой обработки.


Автор: Техническая команда APIYI | Если у вас остались вопросы, заходите на apiyi.com, чтобы узнать больше о вариантах подключения различных моделей ИИ.

Похожие записи