# Nano Banana Pro API: Python 호출, 이미지 편집, 가격

> Nano Banana Pro API를 Python으로 호출하는 방법, 모델 ID, 편집 필드, 1K/2K/4K 선택, 한 장 가격, 응답 JSON을 정리합니다.

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

---

Nano Banana Pro는 Google의 `gemini-3-pro-image`입니다. OmniaKey에서는 `POST /v1/media/tasks` 한 번으로 호출합니다. 3:4 비율로 세 장을 시험했고 결과는 896x1200, 1792x2400, 3584x4800이었으며 포스터의 글자는 하나도 틀리지 않았습니다.

## 먼저 결론

- **모델:** `gemini-3-pro-image`가 Google의 GA 모델 ID입니다. Vertex 모델 카드에는 출시일이 2026년 5월 28일로 적혀 있습니다.
- **호출:** `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 이미지도 포함됩니다.
- **Google 가격:** 1K/2K 한 장에 $0.134, 4K 한 장에 $0.24이며 Google Gemini API 가격 페이지의 값입니다.
- **실제 토큰 수:** 세 작업은 출력 토큰을 1,133, 1,225, 2,480개로 보고했습니다. 이미지 토큰 100만 개당 $120으로 계산하면 $0.136, $0.147, $0.298입니다.
- **편집:** `operation: "edit"`을 쓰고 원본 이미지를 `input.image`에 `{data, mime_type}` 형태로 넣습니다.

OmniaKey의 [Nano Banana Pro 모델 페이지](https://omniakey.com/ko/gemini-3-pro-image)에서는 예전 스냅샷 ID인 `gemini-3-pro-image-preview`도 같은 가격으로 됩니다.

## 모델 ID와 준비물

코드에는 `gemini-3-pro-image`를 씁니다. Google의 [Vertex 모델 카드](https://cloud.google.com/vertex-ai/generative-ai/docs/models/gemini/3-pro-image)는 이 모델을 GA로 올리고 출시일을 2026년 5월 28일로 적었으며, 1K·2K·4K 출력을 지원합니다.

`gemini-3-pro-image-preview`는 같은 모델을 가리키는 ID입니다. OmniaKey의 [이미지 모델 표](https://docs.omniakey.com/en/media/image)에도 "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 이미지 가이드는 "K는 반드시 대문자를 써야 하며, 소문자 파라미터(예: 1k)는 거부된다"고 분명히 적습니다. 2k가 아니라 2K를 보내십시오.

`Idempotency-Key`는 필수입니다. 요청마다 새 UUID를 만드는 것이 가장 간단합니다. 키를 다시 쓰는 경우는 똑같은 본문을 재시도할 때뿐입니다. OmniaKey는 원래 작업을 HTTP 200으로 돌려주므로 두 번 결제되지 않고, 같은 키에 본문이 다르면 409를 돌려줍니다.

생성 요청은 202와 id를 반환합니다. OmniaKey의 [미디어 작업 문서](https://docs.omniakey.com/en/media/overview)에 전체 흐름이 있습니다. 끝난 작업은 다음 필드를 담고 있습니다.

```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로 바꾸고 중국어 간판을 요청하면 이렇게 나옵니다.

![벽돌 벽에 걸린 어두운 금속 간판. 중국어 세 줄과 전화번호가 적혀 있다](https://omniakey.com/_img/blog/nano-banana-pro-api/g2-sign.7e3e8e4d.1600.webp)

_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 포스터를 썼고 글자와 배치가 그대로 남았습니다.

![벽에 걸린 검은 액자 속 야간 열차 포스터. 위에는 사진 조명, 오른쪽에는 화분](https://omniakey.com/_img/blog/nano-banana-pro-api/g3-edit.98011b5c.1600.webp)

_2K, 1:1 편집: 2048x2048, 49.9초. 포스터 글자와 디자인이 그대로 남았고 액자는 반듯한 직사각형입니다._

## 1K, 2K, 4K로 얻는 것

같은 3:4 포스터 프롬프트를 세 크기에서 한 번씩 돌렸습니다. 픽셀 수는 Google의 3:4 표와 정확히 맞았습니다. 1K는 896x1200, 2K는 1792x2400, 4K는 3584x4800입니다. 포스터 글자는 세 크기 모두 맞았습니다.

![1K 야간 열차 포스터. 돌다리 위 증기 기관차, 눈 덮인 산, 짙은 파란 밤하늘](https://omniakey.com/_img/blog/nano-banana-pro-api/g1-1k.12bc0ed0.896.webp)

_1K, 3:4: 896x1200, 28.4초. 포스터 네 줄이 모두 맞고 기관차의 램프와 연결봉이 서로 붙어 있습니다._

![같은 야간 열차 포스터의 2K 버전. 오른쪽 비탈에 마을과 첨탑 두 개가 더 있다](https://omniakey.com/_img/blog/nano-banana-pro-api/g1-2k.38a932bb.1600.webp)

_2K, 3:4: 1792x2400, 48.2초. 글자는 같고 오른쪽 비탈에 마을과 첨탑 두 개가 생겼습니다._

![같은 야간 열차 포스터의 4K 버전. 기관차 뒤에 객차 세 량과 석탄차가 그려져 있다](https://omniakey.com/_img/blog/nano-banana-pro-api/g1-4k.6c8048ad.1600.webp)

_4K, 3:4: 3584x4800, 66.9초. 객차 세 량과 석탄차까지 그려졌고 벽돌 줄눈 두께는 고르지 않습니다._

크기가 커지면 늘어나는 것은 세부 묘사이고 철자는 그대로입니다.

- **1K:** 기관차 앞부분이 빽빽합니다. 램프, 바퀴, 연결봉이 서로 가깝게 붙습니다.
- **2K:** 오른쪽 비탈에 마을과 첨탑 두 개가 나타나고, 굴뚝에서는 옅은 연기가 올라가며, 돌다리에 아치가 일곱 개 보입니다.
- **4K:** 객차 세 량과 석탄차가 따로 그려지고 석조의 줄눈 두께도 달라집니다. 기관차 아래 기계는 여전히 단순합니다.

속도는 크기를 따라 늘었습니다. 28.4초, 48.2초, 66.9초입니다. 크기마다 한 번씩만 돌렸으므로 이 초는 한 번의 결과로 읽으십시오.

Google은 이미지 출력을 100만 토큰당 $120으로 계산하고, 표에는 1K와 2K가 1,120 토큰, 4K가 2,000 토큰으로 나옵니다. Google 자신의 추정치는 이렇게 나옵니다.

```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 추정|
|-|-|-|-|-|
|1K|896x1200|28.4초|1,133|$0.134|
|2K|1792x2400|48.2초|1,225|$0.134|
|4K|3584x4800|66.9초|2,480|$0.24|

OmniaKey는 이미지 호출을 정액으로 청구하고 토큰으로 계산하지 않으므로 위 토큰 수에 따라 요금이 달라지지 않습니다. 현재 호출당 요금은 [모델 페이지](https://omniakey.com/ko/gemini-3-pro-image)에 있고 실패한 작업은 환불됩니다. 같은 세 장을 Google의 토큰 단가로 추정하면 $0.134, $0.134, $0.24입니다.

## 자주 만나는 오류

여기서 다루는 실패는 대부분 필드 이름이나 파일 크기 문제이고 모델 자체의 문제가 아닙니다. OmniaKey 미디어 문서에 적힌 것들입니다.

|HTTP|코드 또는 상태|뜻|할 일|
|-|-|-|-|
|400|`invalid_request`|본문 형식 오류, 지원하지 않는 작업, 잘못된 파라미터|JSON과 아래 필드 이름을 확인하십시오|
|503|`no_available_channel`|지금 이 모델을 처리하는 채널이 없음|모델을 바꾸십시오. 재시도로는 해결되지 않습니다|
|—|`failed`|작업이 끝났지만 결과가 없음|`error.code`와 `error.message`를 읽으십시오|

`failed`는 HTTP 오류가 아닙니다. 생성 요청은 이미 성공했으므로 작업을 폴링해서 `error` 객체를 읽어야 합니다. 실패와 취소 작업은 자동으로 환불됩니다.

원본을 그대로 Base64로 바꾸면 본문이 1 MiB를 넘기 쉽습니다. 먼저 줄이고 파일 크기가 아니라 인코딩 후 길이를 확인하십시오.

Google 가이드는 소문자 `1k`를 거부합니다. 1K, 2K, 4K 중 하나를 쓰십시오.

OmniaKey 이미지 문서도 Gemini 모델에서 `size`와 최상위 `mime_type`을 거부합니다. 둘 다 Gemini 파라미터가 아니기 때문입니다. 대신 `parameters.aspect_ratio`와 `parameters.image_size`를 쓰고 출력 형식은 응답의 `mime_type` 필드에서 읽으십시오.

## 자주 묻는 질문

### Nano Banana Pro API의 모델 ID는 무엇인가요?

`gemini-3-pro-image`입니다. Google의 Vertex 모델 카드가 GA와 출시일 2026년 5월 28일을 적고 있고 OmniaKey도 같은 ID를 받습니다. 예전 ID인 `gemini-3-pro-image-preview`도 OmniaKey에서 되며 같은 모델을 가리킵니다.

### Nano Banana Pro 이미지 한 장은 얼마인가요?

Google 추정치는 1K/2K가 $0.134, 4K가 $0.24입니다. 이미지 토큰 100만 개당 $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`만 쓰십시오.

## 확인한 출처

- [Google Cloud: Gemini 3 Pro Image 모델 카드](https://cloud.google.com/vertex-ai/generative-ai/docs/models/gemini/3-pro-image) — 2026년 11월 3일 확인.
- [Google: Gemini API 이미지 생성 가이드](https://ai.google.dev/gemini-api/docs/image-generation) — 2026년 11월 3일 확인.
- [Google: Gemini API 가격](https://ai.google.dev/gemini-api/docs/pricing) — 2026년 11월 3일 확인.
- [Google: Nano Banana Pro 발표](https://blog.google/technology/ai/nano-banana-pro/) — 2026년 11월 3일 확인.

## 업데이트 기록

- 2026-11-03: 첫 버전. 같은 날 OmniaKey로 테스트 다섯 번 실행.
