How to Use Gemini Nano Banana 2.1 in Python for 4K Images
Ask for 4k in lowercase and the API rejects it. Ask for 4K and it bills $0.113 for the image. This nano banana 2.1 Python guide takes you from a first call to 4K output, multi-turn edits and a batch job, using the google-genai SDK and the gemini-nano-banana-2.1 model.
At the end you will have a script that renders a 4K image, sets the thinking level, edits the result in conversation, and queues bulk work at half the standard rate.
Install the google-genai SDK and set a paid API key
This model has no free tier, so use a key from a project with billing enabled.
pip install -U google-genai pillow
export GEMINI_API_KEY=<your-api-key>
Pillow is only needed for the thought-image step below. The docs' examples for this model all use the Interactions API (client.interactions.create), so that is what this guide uses.
1. Generate your first image with client.interactions.create
import base64
from google import genai
client = genai.Client()
def save_image(interaction, path):
image = interaction.output_image
if not image:
print(interaction.output_text) # the model answered with text only
return
with open(path, 'wb') as f:
f.write(base64.b64decode(image.data))
interaction = client.interactions.create(
model='gemini-nano-banana-2.1',
input='A nano banana dish in a fancy restaurant with a Gemini theme',
)
save_image(interaction, 'first.png')
genai.Client() reads your key from the environment. The image comes back base64-encoded on interaction.output_image.data. With no settings you get the 1K default, billed at $0.0336.
2. Request 4K output with image_size and aspect_ratio
interaction = client.interactions.create(
model='gemini-nano-banana-2.1',
input='Da Vinci style anatomical sketch of a dissected Monarch butterfly on textured parchment, with notes in English.',
response_format={
'type': 'image',
'mime_type': 'image/jpeg',
'aspect_ratio': '16:9',
'image_size': '4K',
},
)
save_image(interaction, 'butterfly_4k.jpg')
The options are 1K, 2K and 4K, with an uppercase K. The docs' sample asks for image/jpeg, so save with a matching extension. Google says this release fixed tiling artifacts on the wide ratios (1:4, 4:1, 1:8, 8:1) at 2K and 4K, so panoramas are worth trying.
3. Set the thinking level and inspect thought images
import io
from PIL import Image
interaction = client.interactions.create(
model='gemini-nano-banana-2.1',
input='A futuristic city built inside a giant glass bottle floating in space',
generation_config={'thinking_level': 'high'},
)
for step in interaction.steps:
if step.type == 'thought':
for block in step.summary:
if block.type == 'text':
print(block.text)
elif block.type == 'image':
Image.open(io.BytesIO(base64.b64decode(block.data))).show()
The levels are minimal, medium (the default) and high. Thinking can't be switched off. The model may draw up to two interim thought images, and those are not charged. Thinking text is billed at the $7.50 per million token text rate, so try minimal for simple prompts.
4. Edit the image across turns with previous_interaction_id
first = client.interactions.create(
model='gemini-nano-banana-2.1',
input='Create a vibrant infographic that explains photosynthesis as a recipe for a plant, styled like a kids cookbook page.',
)
save_image(first, 'photosynthesis.png')
second = client.interactions.create(
model='gemini-nano-banana-2.1',
input='Update this infographic to be in Spanish. Do not change any other elements of the image.',
previous_interaction_id=first.id,
response_format={
'type': 'image',
'mime_type': 'image/jpeg',
'aspect_ratio': '16:9',
'image_size': '2K',
},
)
save_image(second, 'photosynthesis_es.jpg')
The server keeps the conversation, so you pass an ID instead of re-uploading the image. The docs' second turn declares response_format again, so do the same. Each turn returns a new image, so budget one image price per turn.
5. Batch nano banana 2.1 jobs at half the price
The pricing page lists the batch rate at half of standard:
| Size | Standard | Batch | |---|---|---| | 1K | $0.0336 | $0.0168 | | 2K | $0.0504 | $0.0252 | | 4K | $0.113 | $0.0567 |
The Batch API docs target 24 hours of turnaround, though most jobs finish sooner. Their image sample uses gemini-3-pro-image-preview and does not print one for this model. The model page does list Batch API as supported. The snippet below is the documented shape with this model's ID swapped in:
import time
prompts = ['A lighthouse at dawn, watercolor', 'A paper crane on a server rack']
inline_requests = [
{
'contents': [{'parts': [{'text': p}]}],
'config': {'response_modalities': ['TEXT', 'IMAGE']},
}
for p in prompts
]
batch_job = client.batches.create(
model='gemini-nano-banana-2.1',
src=inline_requests,
config={'display_name': 'nano-banana-2-1-test'},
)
done = {'JOB_STATE_SUCCEEDED', 'JOB_STATE_FAILED', 'JOB_STATE_CANCELLED', 'JOB_STATE_EXPIRED'}
while batch_job.state.name not in done:
time.sleep(30)
batch_job = client.batches.get(name=batch_job.name)
if batch_job.state.name == 'JOB_STATE_SUCCEEDED':
for i, item in enumerate(batch_job.dest.inlined_responses):
for part in item.response.candidates[0].content.parts:
if part.inline_data:
part.as_image().save(f'batch_{i + 1}.png')
Run two prompts first. The docs' batch sample sets no image size, so confirm how to request 4K in a batch before you queue thousands, then check the line item on your bill. Inline requests suit batches under 20MB. Above that, upload a JSONL file of up to 2GB through the File API.
Gotchas
- No free tier. Standard output images cost $30 per million tokens, which works out to the per-image prices above.
- Lowercase sizes fail, and there is no 512px. Only Gemini 3.1 Flash Image offers 0.5K.
- Unsupported features: function calling, structured outputs, caching, code execution, URL context, the Live API, and flex or priority inference. You can't force JSON or cache a long prompt, so validate outputs yourself.
- SynthID watermark is on every generated image. Tell your customer before they ask where it came from.
- Search grounding is billed separately after 5,000 free requests a month, at $14 per 1,000.
- Batch limits: jobs pending or running for 48 hours expire with no results, and results stay downloadable for 6 weeks.
A 4K image costs about 3.4 times a 1K one, and the missing caching and structured outputs mean cost control and QA live in your own code, so measure both on a small batch before a customer's catalog run.