This batch AI image editing workflow completes a creator job end to end: it sends each local image plus an edit instruction to Nano Banana’s hosted image API, saves one result per input, and keeps going after an individual request failure. It also gives you a focused way to fix AI image API errors instead of restarting the collection. The steps come from Google’s official image-generation examples and Nano Banana’s Python client; “local” describes the script and files, not the hosted model.
Turn one edit into batch AI image editing
The repository’s edit_image() helper provides a useful unit of automation. It checks the API key and input path, reads the file bytes, guesses a MIME type, base64-encodes the image, sends text plus the image through client.interactions.create, checks output_image, and decodes the returned data into an output file. A batch workflow keeps that contract for every asset but isolates a failed request so the remaining files can still run. The reference implementation provides the exact client structure used below.
- Inputs: Put source images in one directory and preserve the originals outside the run.
- Instruction: Start with one repeatable edit, such as a controlled background replacement.
- Requests: Base64-encode each file and attach it to a text instruction in the same
inputarray. - Outputs: Decode
output_image.dataand save a clearly named file for every successful edit. - Failures: Record the filename and full exception, continue with the next asset, and report a summary after the loop.
This separation is useful when a creator is processing a product set, portrait series, or campaign variations. Google’s official examples demonstrate individual images and multi-turn interactions, while the repository shows how to package one local file for the hosted API. The official documentation provides the underlying request and response format.
AI image API vs local model: choose the execution path
The provided client is careful about what “local” means. Its comment states that it sends an image and editing instruction to Google’s hosted Gemini image model and that the model itself does not run on the local machine. The request contains base64 image data, not a path that the hosted service can open. That is the central distinction in an AI image API vs local model decision. The Nano Banana client sends the request; it does not turn Gemini into an offline generator.
- Cloud API path: The SDK client runs on your computer, but
interactions.createsends the prompt and encoded image to Google’s hosted service. The response is decoded and written back to local storage. - Local open-weight path: A local workflow would use model weights and an inference runtime on the machine performing the edit. Neither supplied source implements that path, so output parity, dependencies, and hardware requirements remain unknown here.
For a cloud vs local AI image generator comparison, do not infer capabilities from the filename nano_api.py. If local execution is required, begin with the Nano Banana installation and troubleshooting guide. For the hosted path, use the Nano Banana quickstart. The supplied API client does not establish that a local model or offline procedure is available.
Prepare the batch without changing the API contract
Install the SDK and expose the key in the environment used to launch Python. The repository lists google-genai and accepts either GOOGLE_API_KEY or GEMINI_API_KEY. It reads those variables directly and does not load a key file automatically. The repository prerequisites show the supported setup.
python -m pip install -U google-genai
export GEMINI_API_KEY='your-key-here'
Keep inputs and outputs separate. For example:
inputs/
portrait.jpg
product.jpg
outputs/
The source client uses mimetypes.guess_type(), and the official examples show JPEG and PNG image inputs. Make extensions reflect the actual files rather than relying on the client’s PNG fallback for an unknown type. For the instruction itself, the Nano Banana prompt library provides a useful place to develop a precise, repeatable edit before applying it to a collection.
Run a fault-tolerant Python batch
Before copying code, note a difference between the supplied sources. Google’s official interaction example uses gemini-nano-banana-2.1, while the repository snapshot calls gemini-3.1-flash-image. The evidence does not explain compatibility between those identifiers. The sample below keeps the value shown in Google’s supplied example in a MODEL constant; confirm the identifier in the official Gemini documentation before a long run.
The code uses only the demonstrated API surface and sends one file at a time. It deliberately adds no automatic retry behavior because the supplied sources do not define a retry policy.
import base64
import mimetypes
import os
from pathlib import Path
from google import genai
MODEL = 'gemini-nano-banana-2.1'
def edit_batch(input_dir, output_dir, prompt):
api_key = os.getenv('GOOGLE_API_KEY') or os.getenv('GEMINI_API_KEY')
if not api_key:
raise RuntimeError(
'Set GOOGLE_API_KEY or GEMINI_API_KEY before running this script.'
)
client = genai.Client(api_key=api_key)
input_dir = Path(input_dir)
output_dir = Path(output_dir)
output_dir.mkdir(parents=True, exist_ok=True)
failures = []
for input_file in sorted(input_dir.iterdir()):
if not input_file.is_file():
continue
mime_type = mimetypes.guess_type(input_file.name)[0] or 'image/png'
if not mime_type.startswith('image/'):
failures.append(input_file.name)
print(f'[!] Unsupported input type: {mime_type}')
continue
image_bytes = input_file.read_bytes()
try:
interaction = client.interactions.create(
model=MODEL,
input=[
{'type': 'text', 'text': prompt},
{
'type': 'image',
'data': base64.b64encode(image_bytes).decode('utf-8'),
'mime_type': mime_type,
},
],
response_format={
'type': 'image',
'mime_type': 'image/png',
},
)
except Exception as error:
failures.append(input_file.name)
print(f'[!] API Error for {input_file.name}: {error}')
continue
if not interaction.output_image:
failures.append(input_file.name)
print('[!] No image returned. Check the prompt and safety filters.')
continue
output_path = output_dir / f'{input_file.stem}_edited.png'
output_path.write_bytes(
base64.b64decode(interaction.output_image.data)
)
print(f'[+] Saved: {output_path}')
if failures:
raise RuntimeError(
f'{len(failures)} image(s) failed: {failures}'
)
edit_batch(
'inputs',
'outputs',
'Replace the background with a neon cyberpunk city while preserving subject lighting.',
)
The final call applies the same instruction to every image. A request exception is recorded against its filename, a missing output_image is reported, and successful data is decoded to the matching PNG output. The summary error appears only after all files have been attempted, so a single bad request does not silently remove other outputs.
Control AI image output formats and revisions
Google’s official examples demonstrate a response_format with type image, MIME types image/jpeg and image/png, an aspect ratio of 16:9, and an image size of 2K. The supplied extract does not publish the complete allowed matrix, so treat these as demonstrated values rather than an exhaustive compatibility list. Check the current official image-generation documentation before changing format, ratio, or size.
- Keep the requested MIME type and file extension aligned; the example requests PNG and writes a
.pngfile. - Decode
output_image.databefore writing it rather than saving the base64 text as an image. - Record the model, prompt, and input filename with each result so a later correction can be reproduced deliberately.
For follow-up changes, Google describes multi-turn conversation as the recommended way to iterate on an image. Preserve interaction.id with the source filename, then pass it as previous_interaction_id in the next request:
revision = client.interactions.create(
model=MODEL,
input='Update this infographic to be in Spanish. Do not change other elements.',
previous_interaction_id=interaction.id,
response_format={
'type': 'image',
'mime_type': 'image/png',
'aspect_ratio': '16:9',
'image_size': '2K',
},
)
This ties a correction to the generated interaction instead of blindly rerunning the original source image. The same base64 decoding step can save the revised output.
Fix AI image API errors without restarting
The repository’s checks and error messages provide a concrete troubleshooting sequence:
- Missing API key: If Python raises
Set GOOGLE_API_KEY or GEMINI_API_KEY before running this script., set one of those variables in the process launching the script. Do not place the key in source code or diagnostic output. - Input file not found: The reference helper raises
FileNotFoundErrorwith the missing path. Check that the path is relative to the directory from which Python was launched, not necessarily the directory containing the script. - Unsupported input type: The helper rejects a detected MIME type that does not begin with
image/. If detection returns nothing, the source falls back toimage/png; do not use that fallback to disguise an unknown or incorrectly named file. - No returned image: When
interaction.output_imageis absent, the repository says to check the prompt and safety filters. Make the edit instruction more specific and test that single file before rerunning the collection. - Other API exception: The repository catches the exception and prints
[!] API Errorfollowed by its message. Preserve that complete text. Then reproduce the issue with one file using the referenceedit_image()helper: a working single-file request points toward batch logic, while the same failure in both paths points toward the request itself. - Python image API proxy error: The supplied
nano_api.pyis an SDK client, not a documented proxy. The evidence therefore cannot identify a proxy-specific cause. If another Python wrapper sits in front of it, retain the wrapper’s complete exception and diagnostic text, then compare a direct request with the proxied request before deciding which layer failed.
The supplied sources do not provide status-specific remedies, request limits, or retry rules, so avoid inventing them from a generic error message. Use the current official API documentation for those cases. For setup failures before a request is sent, the installation and troubleshooting guide is the right reference; for a valid request that returns no image, revisit the prompt library and isolate the instruction on one known-good input.