forked from bojieli/ai-agent-book
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathgen_cover.py
More file actions
executable file
·76 lines (66 loc) · 3.38 KB
/
Copy pathgen_cover.py
File metadata and controls
executable file
·76 lines (66 loc) · 3.38 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
#!/usr/bin/env python3
"""Generate the book cover image with an image-generation model.
This is, fittingly, the book eating its own dog food: the cover of a book about
AI agents is produced by calling an image-generation model. Run it once; the
cover (cover.tex) automatically switches to images/cover-image.png when present
— no other change needed. You can then note on the colophon that the cover was
generated by AI.
Usage (OpenAI, the default):
pip install openai
export OPENAI_API_KEY=sk-...
python gen_cover.py
"""
import os
# ── The prompt ────────────────────────────────────────────────────────────
PROMPT = (
"Vintage scientific engraving illustration of an octopus, in the classic style of "
"19th-century natural-history woodcuts and the O'Reilly animal book covers. Finely "
"detailed black pen-and-ink crosshatching and fine line work; pure black line art, "
"no color, no gray wash, no shading fills. The whole octopus rendered elegantly with "
"gracefully curling tentacles, anatomically believable, slightly stylized. Perfectly "
"clean pure white background, no scenery, no frame, no border, no text, no lettering, "
"no numbers. Centered composition, crisp, high detail."
)
OUT = os.path.join(os.path.dirname(os.path.abspath(__file__)), "images", "cover-image.png")
def generate_openai(prompt, out):
"""OpenAI Images API. Uses gpt-image-1 if available, else dall-e-3."""
api_key = os.environ.get("OPENAI_API_KEY")
if not api_key:
print("OPENAI_API_KEY environment variable not set. Skipping API image generation.")
print("Cover page will use default TikZ vector art in cover.tex.")
return False
from openai import OpenAI
import base64, urllib.parse, urllib.request
client = OpenAI()
try:
r = client.images.generate(model="gpt-image-1", prompt=prompt,
size="1024x1536", quality="high", n=1)
data = base64.b64decode(r.data[0].b64_json)
with open(out, "wb") as f:
f.write(data)
return True
except Exception as e:
print(f"gpt-image-1 unavailable ({e}); falling back to dall-e-3 …")
try:
r = client.images.generate(model="dall-e-3", prompt=prompt,
size="1024x1792", quality="hd",
style="natural", n=1)
url = r.data[0].url
parsed = urllib.parse.urlparse(url)
if parsed.scheme != "https" or not parsed.netloc:
raise ValueError(f"Invalid URL scheme or host for image download: {url}")
with urllib.request.urlopen(url, timeout=60) as resp:
with open(out, "wb") as f:
f.write(resp.read())
return True
except Exception as fallback_err:
print(f"dall-e-3 image generation failed ({fallback_err}). Falling back to default TikZ art in cover.tex.")
return False
def generate(prompt, out):
return generate_openai(prompt, out)
if __name__ == "__main__":
os.makedirs(os.path.dirname(OUT), exist_ok=True)
print("Generating cover image …")
if generate(PROMPT, OUT):
print(f"Saved {OUT}")
print("Now rebuild: bash build_pdf.sh (cover.tex auto-detects the image)")