# Nano Banana Pro API : tutoriel Python, édition d'image et prix

> Appeler Nano Banana Pro depuis Python : identifiant du modèle, champs de taille et input.image, option 4K, prix par image chez Google et JSON renvoyé.

- Canonical HTML: https://omniakey.com/fr/blog/nano-banana-pro-api
- Markdown: https://omniakey.com/fr/blog/nano-banana-pro-api.md
- Published: 2026-11-03 (updated 2026-11-03)
- Author: Kiki, COO at OmniaKey
- Language: fr
- Category: API setup
- Reading time: 9 min
- All posts: https://omniakey.com/blog/llms.txt

---

Nano Banana Pro, c'est `gemini-3-pro-image` de Google, et sur OmniaKey vous l'appelez avec un seul `POST /v1/media/tasks`. Nos trois essais en 3:4 sont revenus en 896x1200, 1792x2400 et 3584x4800, et chaque mot de l'affiche était correctement orthographié.

## Réponse courte

- **Modèle :** `gemini-3-pro-image` est l'identifiant GA de Google. La fiche du modèle chez Vertex indique une date de sortie au 28 mai 2026.
- **Appel :** envoyez `POST https://api.omniakey.com/v1/media/tasks` avec une `Idempotency-Key`, interrogez `GET /v1/media/tasks/{id}` jusqu'au statut succeeded, puis téléchargez `assets[0].url`.
- **Paramètres :** `parameters.aspect_ratio` et `parameters.image_size` ; les valeurs de taille sont 1K, 2K et 4K, avec un K en majuscule.
- **Limite de requête :** 1 MiB pour tout le corps, données d'image en Base64 comprises.
- **Prix Google :** $0.134 par image 1K/2K et $0.24 par image 4K, d'après la page tarifaire de l'API Gemini.
- **Nos jetons :** les trois tâches ont déclaré 1,133, 1,225 et 2,480 jetons de sortie. À $120 par million de jetons d'image, cela fait $0.136, $0.147 et $0.298.
- **Retouche :** utilisez `operation: "edit"` et placez l'image source dans `input.image` sous la forme `{data, mime_type}`.

La [page du modèle Nano Banana Pro](https://omniakey.com/fr/gemini-3-pro-image) sur OmniaKey accepte aussi `gemini-3-pro-image-preview`, l'ancien identifiant d'instantané, au même prix.

## L'identifiant du modèle et ce qu'il vous faut

L'identifiant à écrire dans votre code est `gemini-3-pro-image`. La [fiche du modèle chez Vertex](https://cloud.google.com/vertex-ai/generative-ai/docs/models/gemini/3-pro-image) le liste en GA avec une date de sortie au 28 mai 2026. Il produit des images en 1K, 2K et 4K.

L'identifiant -preview désigne le même modèle. Le [tableau des modèles d'image](https://docs.omniakey.com/en/media/image) d'OmniaKey décrit `gemini-3-pro-image-preview` comme « Same model, -preview snapshot id », au même tarif par appel.

Il vous faut deux choses :

1. Une clé d'API OmniaKey, exportée pour que le script la lise : `export OMNIAKEY_API_KEY="your-key"`.
2. Python 3. Le script ci-dessous n'utilise que la bibliothèque standard : urllib, json, time, uuid, base64 et pathlib. Aucun SDK à installer.

## Le script Python

Trois étapes : créer la tâche, l'interroger, télécharger l'image. Enregistrez-le sous `nano_banana.py` et lancez `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` accepte 1K, 2K ou 4K. Le guide image de Google est explicite : « You must use an uppercase 'K' … Lowercase parameters (e.g., 1k) will be rejected. » Envoyez 2K, pas 2k.

`Idempotency-Key` est obligatoire. Un UUID neuf par requête est la règle simple ; ne réutilisez une clé que pour renvoyer exactement le même corps. OmniaKey renvoie alors la tâche d'origine en HTTP 200 au lieu de facturer deux fois, et répond 409 si la même clé arrive avec un corps différent.

L'appel de création renvoie 202 avec un id. La [documentation des tâches média](https://docs.omniakey.com/en/media/overview) d'OmniaKey décrit tout le cycle ; la tâche terminée porte les champs que vous lisez :

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

Lisez `assets[0].url` et téléchargez tout de suite : le lien signé dure environ une heure, et l'enregistrement de la tâche reste 24 heures. Le champ `mime_type` donne le format ; les modèles Gemini renvoient le plus souvent du JPEG.

Le même script en 1:1 et 2K, avec une consigne d'enseigne en chinois, a donné ceci :

![Une enseigne en métal sombre sur un mur de briques, avec trois lignes de texte chinois et un numéro de téléphone](https://omniakey.com/_img/blog/nano-banana-pro-api/g2-sign.7e3e8e4d.1600.webp)

_2K, 1:1 : 2048x2048 en 47.2 s. Les trois lignes chinoises et le 010-6789 4321 sont revenus justes ; la rouille couvre une partie du premier 0._

## Retoucher une image existante

Mettez `operation: "edit"` et passez l'image source dans `input.image` sous la forme `{data, mime_type}`. Le script ci-dessus le fait déjà quand vous lui donnez un 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",
)
```

Voici le corps réellement envoyé :

```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"}
}
```

L'image source de l'exemple est un PNG, donc le script l'étiquette `image/png` ; changez cette étiquette pour un JPEG. Pour plusieurs références, utilisez `input.images` avec la même forme `{data, mime_type}` pour chaque entrée. Le guide de Google fixe la limite à 14 images de référence ; pour `gemini-3-pro-image`, la répartition est de 6 images d'objet, 5 de personnage et 3 de style.

Gardez le corps sous 1 MiB. Le Base64 grossit le fichier d'environ un tiers : réduisez ou compressez la source avant de l'encoder. Notre retouche a utilisé l'affiche en 2K et a conservé chaque mot et la mise en page :

![L'affiche du train de nuit dans un cadre noir sur un mur, avec une lampe de tableau au-dessus et une plante à droite](https://omniakey.com/_img/blog/nano-banana-pro-api/g3-edit.98011b5c.1600.webp)

_2K, retouche 1:1 : 2048x2048 en 49.9 s. Le texte et le graphisme de l'affiche ont survécu ; le cadre est un rectangle net._

## 1K, 2K et 4K : ce que chacun apporte

Nous avons lancé la même consigne d'affiche en 3:4 dans les trois tailles. Les pixels correspondaient exactement au tableau de Google pour le 3:4 : 896x1200 en 1K, 1792x2400 en 2K et 3584x4800 en 4K. Le texte de l'affiche était juste à chaque taille.

![L'affiche du train de nuit en 1K : train à vapeur sur un pont de pierre, montagnes enneigées et ciel bleu profond](https://omniakey.com/_img/blog/nano-banana-pro-api/g1-1k.12bc0ed0.896.webp)

_1K, 3:4 : 896x1200 en 28.4 s. Les quatre lignes de l'affiche sont bonnes ; les fanaux et les bielles de la locomotive se serrent._

![La même affiche du train de nuit en 2K, avec un village et deux clochers ajoutés sur le versant de droite](https://omniakey.com/_img/blog/nano-banana-pro-api/g1-2k.38a932bb.1600.webp)

_2K, 3:4 : 1792x2400 en 48.2 s. Même texte, plus un village et deux clochers sur le versant de droite._

![La même affiche du train de nuit en 4K, avec trois voitures et le tender dessinés derrière la locomotive](https://omniakey.com/_img/blog/nano-banana-pro-api/g1-4k.6c8048ad.1600.webp)

_4K, 3:4 : 3584x4800 en 66.9 s. Trois voitures et le tender sont dessinés ; les joints de briques varient en épaisseur._

Ce qui change avec la taille, c'est le détail, pas l'orthographe :

- **1K :** l'avant du train est encombré : fanaux, roues et bielles se touchent presque.
- **2K :** le village et ses deux clochers apparaissent sur le versant de droite, la cheminée fume d'un filet pâle et le pont montre sept arches.
- **4K :** les trois voitures et le tender sont séparés, et la pierre montre des joints d'épaisseur inégale. La mécanique sous la locomotive reste simplifiée.

La durée montait avec la taille : 28.4 s, 48.2 s et 66.9 s. Chaque taille n'a tourné qu'une fois, lisez donc ces secondes comme une seule passe.

Google facture la sortie d'image à $120 par million de jetons, et son tableau donne 1,120 jetons pour le 1K comme pour le 2K et 2,000 jetons pour le 4K. D'où son estimation :

```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
```

Nos tâches ont déclaré plus de jetons que les exemples de Google. Voici le même calcul avec nos chiffres :

```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
```

|Taille|Pixels, 3:4|Notre durée|Nos jetons|Estimation Google|
|-|-|-|-|-|
|1K|896x1200|28.4 s|1,133|$0.134|
|2K|1792x2400|48.2 s|1,225|$0.134|
|4K|3584x4800|66.9 s|2,480|$0.24|

OmniaKey facture un appel d'image à forfait, pas au jeton : son montant ne bouge donc pas avec ces compteurs. Le tarif actuel par appel est sur la [page du modèle](https://omniakey.com/fr/gemini-3-pro-image), et une tâche échouée est remboursée. L'estimation de Google au tarif des jetons pour les mêmes trois images est de $0.134, $0.134 et $0.24.

## Les erreurs que vous allez rencontrer

Les échecs listés ici se résument presque toujours à un nom de champ ou à une taille de fichier, pas au modèle. Voici ceux que la documentation média d'OmniaKey indique pour ce point d'entrée :

|HTTP|Code ou statut|Ce que ça veut dire|Que faire|
|-|-|-|-|
|400|`invalid_request`|Corps mal formé, opération non prise en charge ou paramètre invalide|Vérifiez le JSON et les noms de champs ci-dessous|
|503|`no_available_channel`|Aucun canal ne sert ce modèle en ce moment|Changez de modèle ; réessayer n'y changera rien|
|—|`failed`|La tâche s'est terminée sans résultat|Lisez `error.code` et `error.message`|

Une tâche échouée n'est pas une erreur HTTP : l'appel de création a réussi, donc interrogez la tâche et lisez son objet `error`. Les tâches échouées ou annulées sont remboursées automatiquement.

Une source en pleine résolution envoyée en Base64 peut pousser le corps au-delà de 1 MiB. Réduisez d'abord, puis vérifiez la longueur encodée, pas seulement la taille du fichier.

Le guide de Google refuse un `1k` en minuscules. Utilisez 1K, 2K ou 4K.

La documentation image d'OmniaKey refuse aussi `size` et un `mime_type` de premier niveau sur les modèles Gemini, car ce ne sont pas des paramètres Gemini. Utilisez `parameters.aspect_ratio` et `parameters.image_size`, et lisez le format de sortie dans le champ `mime_type` de la réponse.

## Questions fréquentes

### Quel est l'identifiant du modèle de l'API Nano Banana Pro ?

`gemini-3-pro-image`. La fiche Vertex de Google le donne en GA avec une date de sortie au 28 mai 2026, et OmniaKey accepte le même identifiant. L'ancien identifiant `gemini-3-pro-image-preview` fonctionne toujours sur OmniaKey et désigne le même modèle.

### Combien coûte une image Nano Banana Pro ?

Google estime $0.134 pour une image 1K ou 2K et $0.24 pour une image 4K, à $120 par million de jetons d'image. Nos tâches ont déclaré 1,133, 1,225 et 2,480 jetons, soit $0.136, $0.147 et $0.298 à ce tarif. La page du modèle sur OmniaKey affiche son propre tarif par appel.

### Nano Banana Pro sait-il dessiner du texte chinois ?

Oui. Notre enseigne en 2K est revenue avec trois lignes chinoises justes — 同福客栈, 住宿 餐饮 茶水 et 010-6789 4321 — avec les 11 chiffres et le trait d'union.

### Faut-il demander du 1K, du 2K ou du 4K ?

Pour une affiche comme la nôtre, 2K est le bon milieu. Les trois tailles ont écrit notre affiche correctement : le 4K achète donc du détail plus fin — voitures séparées, joints de briques — et non un meilleur texte. Prenez 1K pour les brouillons où 896x1200 suffit.

### Pourquoi ma retouche a-t-elle renvoyé 400 invalid\_request ?

Les causes habituelles : un corps de plus de 1 MiB, la source dans le mauvais champ, ou un modèle Gemini qui reçoit `size` ou un `mime_type` de premier niveau. Placez l'image dans `input.image` sous la forme `{data, mime_type}`, gardez le corps encodé sous 1 MiB et utilisez `aspect_ratio` et `image_size`.

## Sources vérifiées

- [Google Cloud : fiche du modèle Gemini 3 Pro Image](https://cloud.google.com/vertex-ai/generative-ai/docs/models/gemini/3-pro-image) — vérifiée le 3 novembre 2026.
- [Google : guide de génération d'images de l'API Gemini](https://ai.google.dev/gemini-api/docs/image-generation) — vérifié le 3 novembre 2026.
- [Google : tarifs de l'API Gemini](https://ai.google.dev/gemini-api/docs/pricing) — vérifiés le 3 novembre 2026.
- [Google : annonce de Nano Banana Pro](https://blog.google/technology/ai/nano-banana-pro/) — vérifiée le 3 novembre 2026.

## Journal des mises à jour

- 2026-11-03 : première version ; cinq appels de test passés ce jour-là via OmniaKey.
