Skip to content

Commit 89d3e93

Browse files
authored
Merge pull request #331 from realpython/openai-dalle
Add tutorial code
2 parents a538d97 + 50e7ac3 commit 89d3e93

File tree

8 files changed

+149
-0
lines changed

8 files changed

+149
-0
lines changed

openai-dalle/README.md

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
# Generate Images With DALL·E 2 and the OpenAI API
2+
3+
Learn to use the OpenAI Python library to create images with DALL·E, a state-of-the-art latent diffusion model. In the associated tutorial on [generating images with DALL·E 2 and the OpenAI API](https://realpython.com/generate-images-with-dalle-openai-api/), you explore image creation and generating image variations. You learn how to interact with DALL·E using API calls and incorporate this functionality into your Python scripts.
4+
5+
## Setup
6+
7+
Create and activate a virtual environment, then install the `openai` package:
8+
9+
```console
10+
$ python --version
11+
Python 3.11.0
12+
$ python -m venv venv
13+
$ source venv/bin/activate
14+
(venv) $ python -m pip install openai
15+
```
16+
17+
You need to be on Python 3.7.1 or higher.
18+
19+
## Create Images and Image Variations
20+
21+
Follow the instructions in [the tutorial](https://realpython.com/generate-images-with-dalle-openai-api/) to create images from text prompts, create image variations, and convert a Base64 JSON response to a PNG image file.
22+
23+
You can find the code for each of these steps in dedicated scripts:
24+
25+
- `create.py`: Create an image from a text prompt and save the image data to a file.
26+
- `convert.py`: Convert a Base64-encoded PNG image delivered in a JSON response to a PNG image file.
27+
- `vary.py`: Read Base64-encoded image data and make an API request to receive variations of that image.
28+
29+
In the tutorial, you'll walk through each of these scripts and their functionality and output in more detail.
30+
31+
## Edit Images (Inpainting and Outpainting)
32+
33+
The OpenAI Image API also allows you to [edit parts of an image](https://beta.openai.com/docs/guides/images/edits) using text prompts. For this, you need to create a mask with transparent image data in the area where you want to edit the image.
34+
35+
You can run `edit.py` to give this functionality a try.

openai-dalle/convert.py

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
import json
2+
from base64 import b64decode
3+
from pathlib import Path
4+
5+
JSON_FILE = Path("An ec-1668602437.json")
6+
IMAGE_DIR = Path.cwd() / "images" / JSON_FILE.stem
7+
DATA_DIR = Path.cwd() / "responses"
8+
9+
IMAGE_DIR.mkdir(parents=True, exist_ok=True)
10+
11+
with open(DATA_DIR / JSON_FILE, "r") as file:
12+
response = json.load(file)
13+
14+
for index, image_dict in enumerate(response["data"]):
15+
image_data = b64decode(image_dict["b64_json"])
16+
with open(IMAGE_DIR / f"{JSON_FILE.stem}-{index}.png", "wb") as png:
17+
png.write(image_data)

openai-dalle/create.py

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
import json
2+
import os
3+
from pathlib import Path
4+
5+
import openai
6+
7+
PROMPT = "An eco-friendly computer from the 90s in the style of vaporwave"
8+
DATA_DIR = Path.cwd() / "responses"
9+
10+
DATA_DIR.mkdir(exist_ok=True)
11+
12+
openai.api_key = os.getenv("OPENAI_API_KEY")
13+
14+
response = openai.Image.create(
15+
prompt=PROMPT,
16+
n=1,
17+
size="256x256",
18+
response_format="b64_json",
19+
)
20+
21+
file_name = DATA_DIR / f"{PROMPT[:5]}-{response['created']}.json"
22+
23+
with open(file_name, mode="w", encoding="utf-8") as file:
24+
json.dump(response, file)

openai-dalle/edit.py

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
import json
2+
import os
3+
from pathlib import Path
4+
5+
import openai
6+
7+
SOURCE_PATH = Path.cwd() / "images" / "An ec-1667994848"
8+
DESTINATION_PATH = Path.cwd() / "responses"
9+
PROMPT = "A 90s vaporwave computer showing Rick Astley on the screen"
10+
11+
SOURCE_PATH.mkdir(parents=True, exist_ok=True)
12+
DESTINATION_PATH.mkdir(parents=True, exist_ok=True)
13+
14+
openai.api_key = os.getenv("OPENAI_API_KEY")
15+
16+
response = openai.Image.create_edit(
17+
image=open(SOURCE_PATH / "computer.png", "rb"),
18+
mask=open(SOURCE_PATH / "mask.png", "rb"),
19+
prompt=PROMPT,
20+
n=1,
21+
size="256x256",
22+
response_format="b64_json",
23+
)
24+
25+
with open(
26+
DESTINATION_PATH / f"edit-{PROMPT[:5]}-{response['created']}.json",
27+
mode="w",
28+
encoding="utf-8",
29+
) as file:
30+
json.dump(response, file)
192 KB
Loading
79.1 KB
Loading

openai-dalle/requirements.txt

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
certifi==2022.9.24
2+
charset-normalizer==2.1.1
3+
et-xmlfile==1.1.0
4+
idna==3.4
5+
numpy==1.23.4
6+
openai==0.25.0
7+
openpyxl==3.0.10
8+
pandas==1.5.1
9+
pandas-stubs==1.2.0.62
10+
python-dateutil==2.8.2
11+
pytz==2022.6
12+
requests==2.28.1
13+
six==1.16.0
14+
tqdm==4.64.1
15+
typing_extensions==4.4.0
16+
urllib3==1.26.12

openai-dalle/vary.py

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
import json
2+
import os
3+
from base64 import b64decode
4+
from pathlib import Path
5+
6+
import openai
7+
8+
SOURCE_FILE = "A com-1667994848.json"
9+
DATA_DIR = Path.cwd() / "responses"
10+
11+
openai.api_key = os.getenv("OPENAI_API_KEY")
12+
13+
with open(DATA_DIR / SOURCE_FILE, "r") as json_file:
14+
saved_response = json.load(json_file)
15+
image_data = b64decode(saved_response["data"][0]["b64_json"])
16+
17+
response = openai.Image.create_variation(
18+
image=image_data,
19+
n=3,
20+
size="256x256",
21+
response_format="b64_json",
22+
)
23+
24+
new_file_name = f"vary-{SOURCE_FILE[:4]}-{response['created']}.json"
25+
26+
with open(DATA_DIR / new_file_name, mode="w", encoding="utf-8") as file:
27+
json.dump(response, file)

0 commit comments

Comments
 (0)