-
Notifications
You must be signed in to change notification settings - Fork 3
Expand file tree
/
Copy pathgenerate_new_example.py
More file actions
297 lines (226 loc) · 9.98 KB
/
generate_new_example.py
File metadata and controls
297 lines (226 loc) · 9.98 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
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
from pydantic import BaseModel, Field
from google import genai
import os
from rich import print as rprint
from rich.prompt import Prompt
from pathlib import Path
import requests
from bs4 import BeautifulSoup
import re
GEMINI_API_KEY = os.getenv("GEMINI_API_KEY")
GEMINI_MODEL = "gemini-2.5-pro-preview-03-25"
class GeminiExample(BaseModel):
"""Represents a code example for the Gemini by Example site."""
python_code: str = Field(description="The Python code to be displayed and executed")
shell_code: str = Field(
description="Shell commands to run the Python code and sample outputs"
)
requests_code: str = Field(
description="Python code using the requests library that replicates any curl examples in the documentation",
default=None,
)
requires_image: bool = Field(
description="Whether this example needs an image to be displayed (i.e. if it involves image generation)",
)
def fetch_url_content(url: str) -> str:
"""Fetch and parse content from a URL."""
try:
response = requests.get(url)
response.raise_for_status()
soup = BeautifulSoup(response.text, "html.parser")
# Remove script and style elements
for script in soup(["script", "style"]):
script.extract()
return soup.get_text()
except Exception as e:
rprint(f"[bold red]Error fetching {url}: {e}[/bold red]")
return ""
def get_example_files_content():
"""Get content from example files."""
python_example = Path("examples/002-streaming-text/streaming-text.py").read_text()
shell_example = Path("examples/002-streaming-text/streaming-text.sh").read_text()
requests_example = Path(
"examples/002-streaming-text/streaming-text_requests.py"
).read_text()
return python_example, shell_example, requests_example
def get_contributing_guidelines():
"""Extract formatting guidelines from CONTRIBUTING.md."""
contributing_text = Path("CONTRIBUTING.md").read_text()
# Extract formatting sections
python_format = re.search(
r"### 2\. Add Python File.*?```python(.*?)```", contributing_text, re.DOTALL
).group(1)
shell_format = re.search(
r"### 3\. Add Shell Script.*?```bash(.*?)```", contributing_text, re.DOTALL
).group(1)
formatting_rules = re.search(
r"#### Formatting Rules:(.*?)###", contributing_text, re.DOTALL
).group(1)
shell_format_rules = re.search(
r"#### Shell Script Format:(.*?)###", contributing_text, re.DOTALL
).group(1)
return python_format, shell_format, formatting_rules, shell_format_rules
def generate_example(prompt: str) -> GeminiExample:
client = genai.Client(api_key=GEMINI_API_KEY)
response = client.models.generate_content(
model="gemini-2.0-flash",
contents=prompt,
config={
"response_mime_type": "application/json",
"response_schema": GeminiExample,
},
)
return response.parsed
def get_next_example_number() -> int:
"""Determine the next available example number based on existing examples."""
examples_dir = Path("examples")
if not examples_dir.exists():
return 1 # Start with 001 if examples directory doesn't exist
# Get all example directories that match the pattern NNN-*
example_dirs = [
d for d in examples_dir.iterdir() if d.is_dir() and re.match(r"^\d{3}-", d.name)
]
if not example_dirs:
return 1 # Start with 001 if no examples exist
# Extract the numeric portion and find the max
max_number = 0
for dir_path in example_dirs:
match = re.match(r"^(\d{3})-", dir_path.name)
if match:
number = int(match.group(1))
max_number = max(max_number, number)
return max_number + 1
def main():
rprint("[bold blue]Welcome to the Gemini Example Generator![/bold blue]")
# Automatically determine the next example number
next_number = get_next_example_number()
# Ask for the text portion of the folder name
example_name = Prompt.ask(
"[yellow]Enter the name for this example[/yellow] (e.g., hello-world)"
)
# Validate example name format (should be like hello-world)
while not re.match(r"^[a-z0-9-]+$", example_name):
rprint(
"[bold red]Example name should only contain lowercase letters, numbers, and hyphens[/bold red]"
)
example_name = Prompt.ask(
"[yellow]Enter the name for this example[/yellow] (e.g., hello-world)"
)
# Construct the full folder name with numeric prefix
folder_name = f"{next_number:03d}-{example_name}"
rprint(f"[green]Creating example in folder: {folder_name}[/green]")
# Ask for focus area
focus = Prompt.ask(
"[yellow]What specific aspect should this example focus on?[/yellow] (e.g., streaming text, multi-turn chat, etc.)"
)
# Ask for topical theme
theme = Prompt.ask(
"[yellow]Do you want a specific topical theme for this example?[/yellow] (e.g., cats, astronomy, cooking, etc. Leave blank for no theme)",
default="",
)
# Ask for documentation URLs
urls = []
rprint(
"[yellow]Enter documentation URLs related to this example (press Enter when done)[/yellow]"
)
while True:
url = Prompt.ask("URL", default="")
if not url:
break
urls.append(url)
if not urls:
rprint("[bold red]No URLs provided. At least one URL is required.[/bold red]")
return
# Fetch content from URLs
rprint("\n[blue]Fetching content from URLs...[/blue]")
docs_content = ""
for url in urls:
content = fetch_url_content(url)
if content:
docs_content += f"\n\n--- Content from {url} ---\n\n{content}"
# Get example files and contributing guidelines
python_example, shell_example, requests_example = get_example_files_content()
python_format, shell_format, formatting_rules, shell_format_rules = (
get_contributing_guidelines()
)
# Create the prompt
prompt = f"""
You are an expert devrel with years of experience in creating code examples that help developers learn new technologies.
Your task today is to take some documentation from the Google Gemini SDK docs and turn it into a simple illustrative example using code.
## Focus Area
This example should specifically focus on: {focus}
{f"## Topical Theme\nThis example should incorporate the thematic elements of: {theme}" if theme else ""}
## Documentation Content
{docs_content}
## Formatting / Output rules
You will output the following:
- Python code formatted according to the guidelines below
- Shell code/output formatted according to the guidelines below
- Python requests code that replicates any curl examples found in the documentation, using the requests library (only if curl examples are present in the documentation). Note: This is stored in a separate file and is not used in the site build.
- A boolean as to whether you think it needs an image to illustrate the output (i.e., if image generation or editing is involved)
### Python File Format:
{python_format}
Python Formatting Rules:
{formatting_rules}
### Shell Script Format:
{shell_format}
Shell Script Formatting Rules:
{shell_format_rules}
## Examples
Here's an example of the Python code format:
```python
{python_example}
```
Here's an example of the shell code format:
```bash
{shell_example}
```
Here's an example of the requests code format:
```python
{requests_example}
```
Based on the documentation provided, please generate a concise, illustrative
example that demonstrates the key concepts clearly, focusing specifically on
{focus}. If the documentation contains multiple examples or topics, prioritize
content related to {focus} and ignore unrelated sections. The title line (i.e.
the first line of the Python file) should be very concise and focus on the core
thing we're focusing on (e.g. "Streaming text", "Image generation", "Editing images", "Object detection").
{f"Try to incorporate elements of the theme: {theme} in your example where it makes sense, such as in prompts, variables, or example text." if theme else ""}
For the requests_code, ONLY include this if you find actual curl examples in the documentation. If curl examples exist, translate them to Python code using the requests library. Do NOT create requests code if there are no curl examples in the documentation.
"""
# Generate the example
rprint("\n[blue]Generating example using Gemini...[/blue]")
try:
result = generate_example(prompt)
# Create the directory structure
example_dir = Path("examples") / folder_name
example_dir.mkdir(parents=True, exist_ok=True)
# Extract the example name from the folder (e.g., "basic-generation" from "001-basic-generation")
example_name = folder_name.split("-", 1)[1]
# Save Python file
python_file = example_dir / f"{example_name}.py"
python_file.write_text(result.python_code)
# Save Shell file
shell_file = example_dir / f"{example_name}.sh"
shell_file.write_text(result.shell_code)
# Save Requests file if curl examples were found
if result.requests_code:
requests_file = example_dir / f"{example_name}_requests.py"
requests_file.write_text(result.requests_code)
# Save documentation URLs to a text file
if urls:
docs_file = example_dir / f"{example_name}_links.txt"
docs_file.write_text("\n".join(urls))
rprint(f"[blue]Saved documentation links to {docs_file}[/blue]")
rprint(
f"\n[bold green]Successfully created example in {example_dir}[/bold green]"
)
# Notify if an image is needed
if result.requires_image:
rprint(
f"\n[bold red]NOTE: This example requires an image named '{example_name}.png' in the example directory.[/bold red]"
)
except Exception as e:
rprint(f"[bold red]Error generating example: {e}[/bold red]")
if __name__ == "__main__":
main()