From a076f9567c788890078a13a85220dcfd1671db96 Mon Sep 17 00:00:00 2001 From: realpython-bot Date: Thu, 6 Aug 2026 10:17:13 +0000 Subject: [PATCH 1/3] Add materials for "How to Generate Images With the OpenAI API" Sample code for the tutorial on generating images with the OpenAI API using the GPT Image models. Replaces the DALL-E workflow in openai-dalle/, which no longer runs since OpenAI retired dall-e-2 and dall-e-3 on May 12, 2026 along with the image variations endpoint. Co-Authored-By: Claude Opus 5 (1M context) --- generate-images-openai/README.md | 44 +++++++++++++++++++++++++ generate-images-openai/convert.py | 18 ++++++++++ generate-images-openai/create.py | 24 ++++++++++++++ generate-images-openai/create_png.py | 18 ++++++++++ generate-images-openai/edit.py | 29 ++++++++++++++++ generate-images-openai/requirements.txt | 16 +++++++++ 6 files changed, 149 insertions(+) create mode 100644 generate-images-openai/README.md create mode 100644 generate-images-openai/convert.py create mode 100644 generate-images-openai/create.py create mode 100644 generate-images-openai/create_png.py create mode 100644 generate-images-openai/edit.py create mode 100644 generate-images-openai/requirements.txt diff --git a/generate-images-openai/README.md b/generate-images-openai/README.md new file mode 100644 index 0000000000..13189b7396 --- /dev/null +++ b/generate-images-openai/README.md @@ -0,0 +1,44 @@ +# How to Generate Images With the OpenAI API + +Learn to use the OpenAI Python library to create images with the GPT Image models. In the associated tutorial on [generating images with the OpenAI API](https://realpython.com/generate-images-openai/), you'll create images from text prompts, tune the size and quality of your results, and edit an image with a follow-up prompt. You'll learn how to interact with the Images API and incorporate this functionality into your Python scripts. + +## Setup + +Create and activate a virtual environment, then install the `openai` package: + +```console +$ python --version +Python 3.14.6 +$ python -m venv venv +$ source venv/bin/activate +(venv) $ python -m pip install openai +``` + +You need to be on Python 3.10 or higher. + +The scripts read your API key from the `OPENAI_API_KEY` environment variable: + +```console +(venv) $ export OPENAI_API_KEY="" +``` + +## Create and Edit Images + +Follow the instructions in [the tutorial](https://realpython.com/generate-images-openai/) to create images from text prompts, edit an image with a follow-up prompt, and convert a Base64 JSON response to a PNG image file. + +You can find the code for each of these steps in dedicated scripts: + +- `create_png.py`: Create an image from a text prompt and write it straight to a PNG file. +- `create.py`: Create an image from a text prompt and save the whole JSON response to a file. +- `convert.py`: Convert a Base64-encoded PNG image delivered in a JSON response to a PNG image file. +- `edit.py`: Read Base64-encoded image data and make an API request to edit that image with a prompt. + +In the tutorial, you'll walk through each of these scripts and their functionality and output in more detail. + +Note that `convert.py` and `edit.py` read a saved response from the `responses/` directory. Run `create.py` first, then update the `JSON_FILE` and `SOURCE_FILE` constants to match the filename that it wrote. + +## A Note on Models + +The GPT Image models replaced DALL·E, which OpenAI [retired on May 12, 2026](https://developers.openai.com/api/docs/deprecations) along with the image variations endpoint. These scripts call `gpt-image-2`. + +OpenAI retires image models on a regular schedule, so if a script starts failing with a message like `The model 'gpt-image-2' does not exist`, then check the deprecations page and swap the model name. diff --git a/generate-images-openai/convert.py b/generate-images-openai/convert.py new file mode 100644 index 0000000000..2d9a24a125 --- /dev/null +++ b/generate-images-openai/convert.py @@ -0,0 +1,18 @@ +import json +from base64 import b64decode +from pathlib import Path + +DATA_DIR = Path.cwd() / "responses" +JSON_FILE = DATA_DIR / "An ec-1786009967.json" +IMAGE_DIR = Path.cwd() / "images" / JSON_FILE.stem + +IMAGE_DIR.mkdir(parents=True, exist_ok=True) + +with open(JSON_FILE, mode="r", encoding="utf-8") as file: + response = json.load(file) + +for index, image_dict in enumerate(response["data"]): + image_data = b64decode(image_dict["b64_json"]) + image_file = IMAGE_DIR / f"{JSON_FILE.stem}-{index}.png" + with open(image_file, mode="wb") as png: + png.write(image_data) diff --git a/generate-images-openai/create.py b/generate-images-openai/create.py new file mode 100644 index 0000000000..2d5386ece2 --- /dev/null +++ b/generate-images-openai/create.py @@ -0,0 +1,24 @@ +import json +from pathlib import Path + +from openai import OpenAI + +client = OpenAI() + +PROMPT = "An eco-friendly computer from the 90s in the style of vaporwave" +DATA_DIR = Path.cwd() / "responses" + +DATA_DIR.mkdir(exist_ok=True) + +response = client.images.generate( + model="gpt-image-2", + prompt=PROMPT, + n=1, + size="1024x1024", + quality="low", +) + +file_name = DATA_DIR / f"{PROMPT[:5]}-{response.created}.json" + +with open(file_name, mode="w", encoding="utf-8") as file: + json.dump(response.to_dict(), file) diff --git a/generate-images-openai/create_png.py b/generate-images-openai/create_png.py new file mode 100644 index 0000000000..0f067736c6 --- /dev/null +++ b/generate-images-openai/create_png.py @@ -0,0 +1,18 @@ +from base64 import b64decode + +from openai import OpenAI + +client = OpenAI() + +PROMPT = "A vaporwave computer" + +response = client.images.generate( + model="gpt-image-2", + prompt=PROMPT, + n=1, + size="1024x1024", + quality="low", +) + +with open("vaporwave.png", mode="wb") as png: + png.write(b64decode(response.data[0].b64_json)) diff --git a/generate-images-openai/edit.py b/generate-images-openai/edit.py new file mode 100644 index 0000000000..f16bd5b3d3 --- /dev/null +++ b/generate-images-openai/edit.py @@ -0,0 +1,29 @@ +import json +from base64 import b64decode +from pathlib import Path + +from openai import OpenAI + +client = OpenAI() + +DATA_DIR = Path.cwd() / "responses" +SOURCE_FILE = DATA_DIR / "An ec-1786009967.json" +EDIT_PROMPT = "Add a large potted plant growing out of the computer" + +with open(SOURCE_FILE, mode="r", encoding="utf-8") as json_file: + saved_response = json.load(json_file) + image_data = b64decode(saved_response["data"][0]["b64_json"]) + +response = client.images.edit( + model="gpt-image-2", + image=("image.png", image_data), + prompt=EDIT_PROMPT, + n=3, + size="1024x1024", + quality="low", +) + +new_file_name = f"edit-{SOURCE_FILE.stem[:5]}-{response.created}.json" + +with open(DATA_DIR / new_file_name, mode="w", encoding="utf-8") as file: + json.dump(response.to_dict(), file) diff --git a/generate-images-openai/requirements.txt b/generate-images-openai/requirements.txt new file mode 100644 index 0000000000..df6c476ae2 --- /dev/null +++ b/generate-images-openai/requirements.txt @@ -0,0 +1,16 @@ +annotated-types==0.8.0 +anyio==4.14.2 +certifi==2026.7.22 +distro==1.9.0 +h11==0.16.0 +httpcore==1.0.9 +httpx==0.28.1 +idna==3.18 +jiter==0.16.0 +openai==2.53.0 +pydantic==2.13.4 +pydantic-core==2.46.4 +sniffio==1.3.1 +tqdm==4.70.0 +typing-extensions==4.16.0 +typing-inspection==0.4.2 From 797c2fda08144053fbb27039c3b1ca40ec245968 Mon Sep 17 00:00:00 2001 From: Martin Breuss Date: Mon, 14 Sep 2026 10:15:44 +0000 Subject: [PATCH 2/3] Switch generate-images-openai scripts to gpt-image-2.5-flare Update the model name in create.py, create_png.py, and edit.py, refresh the saved-response filename constants, and pin openai 3.13.0 with its httpx2-based dependencies. All scripts were re-run against the live API. Co-Authored-By: Claude Fable 5.1 --- generate-images-openai/README.md | 4 ++-- generate-images-openai/convert.py | 2 +- generate-images-openai/create.py | 2 +- generate-images-openai/create_png.py | 2 +- generate-images-openai/edit.py | 4 ++-- generate-images-openai/requirements.txt | 22 ++++++++++------------ 6 files changed, 17 insertions(+), 19 deletions(-) diff --git a/generate-images-openai/README.md b/generate-images-openai/README.md index 13189b7396..a8ca02ca8f 100644 --- a/generate-images-openai/README.md +++ b/generate-images-openai/README.md @@ -39,6 +39,6 @@ Note that `convert.py` and `edit.py` read a saved response from the `responses/` ## A Note on Models -The GPT Image models replaced DALL·E, which OpenAI [retired on May 12, 2026](https://developers.openai.com/api/docs/deprecations) along with the image variations endpoint. These scripts call `gpt-image-2`. +The GPT Image models replaced DALL·E, which OpenAI [retired on May 12, 2026](https://developers.openai.com/api/docs/deprecations) along with the image variations endpoint. These scripts call `gpt-image-2.5-flare`. -OpenAI retires image models on a regular schedule, so if a script starts failing with a message like `The model 'gpt-image-2' does not exist`, then check the deprecations page and swap the model name. +OpenAI retires image models on a regular schedule, so if a script starts failing with a message like `The model 'gpt-image-2.5-flare' does not exist`, then check the deprecations page and swap the model name. diff --git a/generate-images-openai/convert.py b/generate-images-openai/convert.py index 2d9a24a125..bc06510835 100644 --- a/generate-images-openai/convert.py +++ b/generate-images-openai/convert.py @@ -3,7 +3,7 @@ from pathlib import Path DATA_DIR = Path.cwd() / "responses" -JSON_FILE = DATA_DIR / "An ec-1786009967.json" +JSON_FILE = DATA_DIR / "An ec-1789379975.json" IMAGE_DIR = Path.cwd() / "images" / JSON_FILE.stem IMAGE_DIR.mkdir(parents=True, exist_ok=True) diff --git a/generate-images-openai/create.py b/generate-images-openai/create.py index 2d5386ece2..0648e17392 100644 --- a/generate-images-openai/create.py +++ b/generate-images-openai/create.py @@ -11,7 +11,7 @@ DATA_DIR.mkdir(exist_ok=True) response = client.images.generate( - model="gpt-image-2", + model="gpt-image-2.5-flare", prompt=PROMPT, n=1, size="1024x1024", diff --git a/generate-images-openai/create_png.py b/generate-images-openai/create_png.py index 0f067736c6..260c916a8d 100644 --- a/generate-images-openai/create_png.py +++ b/generate-images-openai/create_png.py @@ -7,7 +7,7 @@ PROMPT = "A vaporwave computer" response = client.images.generate( - model="gpt-image-2", + model="gpt-image-2.5-flare", prompt=PROMPT, n=1, size="1024x1024", diff --git a/generate-images-openai/edit.py b/generate-images-openai/edit.py index f16bd5b3d3..f0efc77068 100644 --- a/generate-images-openai/edit.py +++ b/generate-images-openai/edit.py @@ -7,7 +7,7 @@ client = OpenAI() DATA_DIR = Path.cwd() / "responses" -SOURCE_FILE = DATA_DIR / "An ec-1786009967.json" +SOURCE_FILE = DATA_DIR / "An ec-1789379975.json" EDIT_PROMPT = "Add a large potted plant growing out of the computer" with open(SOURCE_FILE, mode="r", encoding="utf-8") as json_file: @@ -15,7 +15,7 @@ image_data = b64decode(saved_response["data"][0]["b64_json"]) response = client.images.edit( - model="gpt-image-2", + model="gpt-image-2.5-flare", image=("image.png", image_data), prompt=EDIT_PROMPT, n=3, diff --git a/generate-images-openai/requirements.txt b/generate-images-openai/requirements.txt index df6c476ae2..474b71ac1d 100644 --- a/generate-images-openai/requirements.txt +++ b/generate-images-openai/requirements.txt @@ -1,16 +1,14 @@ annotated-types==0.8.0 -anyio==4.14.2 -certifi==2026.7.22 -distro==1.9.0 +anyio==4.15.1 h11==0.16.0 -httpcore==1.0.9 -httpx==0.28.1 -idna==3.18 -jiter==0.16.0 -openai==2.53.0 -pydantic==2.13.4 -pydantic-core==2.46.4 +httpcore2==2.12.0 +httpx2==2.12.0 +idna==3.19 +jiter==0.17.0 +openai==3.13.0 +pydantic-core==2.46.5 +pydantic==2.13.5 sniffio==1.3.1 -tqdm==4.70.0 +truststore==0.10.4 typing-extensions==4.16.0 -typing-inspection==0.4.2 +typing-inspection==0.4.4 From f15bf648d77f9eb6002027dba1fc899f5783d200 Mon Sep 17 00:00:00 2001 From: Martin Breuss Date: Mon, 14 Sep 2026 11:17:34 +0000 Subject: [PATCH 3/3] Pin openai in the generate-images-openai README install command Co-Authored-By: Claude Fable 5.1 --- generate-images-openai/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/generate-images-openai/README.md b/generate-images-openai/README.md index a8ca02ca8f..f8c94c247c 100644 --- a/generate-images-openai/README.md +++ b/generate-images-openai/README.md @@ -11,7 +11,7 @@ $ python --version Python 3.14.6 $ python -m venv venv $ source venv/bin/activate -(venv) $ python -m pip install openai +(venv) $ python -m pip install openai==3.13.0 ``` You need to be on Python 3.10 or higher.