diff --git a/genai/batch_prediction/requirements.txt b/genai/batch_prediction/requirements.txt index 4f44a6593bb..ba2ccb4c987 100644 --- a/genai/batch_prediction/requirements.txt +++ b/genai/batch_prediction/requirements.txt @@ -1,3 +1,3 @@ google-cloud-bigquery==3.29.0 google-cloud-storage==2.19.0 -google-genai==1.42.0 +google-genai==2.29.0 diff --git a/genai/bounding_box/boundingbox_interactions_with_txt_img.py b/genai/bounding_box/boundingbox_interactions_with_txt_img.py new file mode 100644 index 00000000000..da8ce381bd4 --- /dev/null +++ b/genai/bounding_box/boundingbox_interactions_with_txt_img.py @@ -0,0 +1,120 @@ +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# https://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + + +def generate_content() -> str: + # [START googlegenaisdk_interactions_boundingbox_with_txt_img] + import json + import requests + from google import genai + from google.genai.interactions import ( + ImageContent, + TextContent, + TextResponseFormat, + ) + from PIL import Image, ImageColor, ImageDraw + from pydantic import BaseModel + + # Helper class to represent a bounding box + class BoundingBox(BaseModel): + """ + Represents a bounding box with its 2D coordinates and associated label. + + Attributes: + box_2d (list[int]): A list of integers representing the 2D coordinates of the bounding box, + typically in the format [y_min, x_min, y_max, x_max]. + label (str): A string representing the label or class associated with the object within the bounding box. + """ + + box_2d: list[int] + label: str + + # Helper function to plot bounding boxes on an image + def plot_bounding_boxes(image_uri: str, bounding_boxes: list[BoundingBox]) -> None: + """ + Plots bounding boxes on an image with labels, using PIL and normalized coordinates. + + Args: + image_uri: The URI of the image file. + bounding_boxes: A list of BoundingBox objects. Each box's coordinates are in + normalized [y_min, x_min, y_max, x_max] format. + """ + with Image.open(requests.get(image_uri, stream=True, timeout=10).raw) as im: + width, height = im.size + draw = ImageDraw.Draw(im) + + colors = list(ImageColor.colormap.keys()) + + for i, bbox in enumerate(bounding_boxes): + # Scale normalized coordinates to image dimensions + abs_y_min = int(bbox.box_2d[0] / 1000 * height) + abs_x_min = int(bbox.box_2d[1] / 1000 * width) + abs_y_max = int(bbox.box_2d[2] / 1000 * height) + abs_x_max = int(bbox.box_2d[3] / 1000 * width) + + color = colors[i % len(colors)] + + # Draw the rectangle using the correct (x, y) pairs + draw.rectangle( + ((abs_x_min, abs_y_min), (abs_x_max, abs_y_max)), + outline=color, + width=4, + ) + if bbox.label: + # Position the text at the top-left corner of the box + draw.text((abs_x_min + 8, abs_y_min + 6), bbox.label, fill=color) + + im.show() + + client = genai.Client() + image_uri = "https://storage.googleapis.com/generativeai-downloads/images/socks.jpg" + + system_instruction = """ + Return bounding boxes as an array with labels. + Never return masks. Limit to 25 objects. + If an object is present multiple times, give each object a unique label + according to its distinct characteristics (colors, size, position, etc..). + """ + + interaction = client.interactions.create( + model="gemini-3.8-flash", + system_instruction=system_instruction, + input=[ + ImageContent( + uri=image_uri, + mime_type="image/jpeg", + ), + TextContent( + text="Output the positions of the socks with a face. Label according to position in the image." + ), + ], + response_format=TextResponseFormat( + mime_type="application/json", + schema={ + "type": "array", + "items": BoundingBox.model_json_schema(), + }, + ), + ) + + print(interaction.output_text) + boxes = [BoundingBox(**b) for b in json.loads(interaction.output_text)] + plot_bounding_boxes(image_uri, boxes) + + # [END googlegenaisdk_interactions_boundingbox_with_txt_img] + return interaction.output_text + + +if __name__ == "__main__": + generate_content() diff --git a/genai/bounding_box/requirements.txt b/genai/bounding_box/requirements.txt index 75a39f7e582..1af6c711b57 100644 --- a/genai/bounding_box/requirements.txt +++ b/genai/bounding_box/requirements.txt @@ -1,2 +1,2 @@ -google-genai==1.42.0 +google-genai==2.29.0 pillow==12.3.0; python_version >= "3.10" diff --git a/genai/bounding_box/test_bounding_box_examples.py b/genai/bounding_box/test_bounding_box_examples.py index 39b0056e7a3..88845706f44 100644 --- a/genai/bounding_box/test_bounding_box_examples.py +++ b/genai/bounding_box/test_bounding_box_examples.py @@ -18,6 +18,7 @@ import os +import boundingbox_interactions_with_txt_img import boundingbox_with_txt_img os.environ["GOOGLE_GENAI_USE_ENTERPRISE"] = "True" @@ -29,3 +30,9 @@ def test_boundingbox_with_txt_img() -> None: response = boundingbox_with_txt_img.generate_content() assert response + + +def test_boundingbox_interactions_with_txt_img() -> None: + response = boundingbox_interactions_with_txt_img.generate_content() + assert response + diff --git a/genai/code_execution/codeexecution_interactions_annotateimage_with_txt_gcsimg.py b/genai/code_execution/codeexecution_interactions_annotateimage_with_txt_gcsimg.py new file mode 100644 index 00000000000..1e083691be3 --- /dev/null +++ b/genai/code_execution/codeexecution_interactions_annotateimage_with_txt_gcsimg.py @@ -0,0 +1,67 @@ +# Copyright 2026 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# https://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + + +def generate_content() -> bool: + # [START googlegenaisdk_interactions_codeexecution_annotateimage_with_txt_gcsimg] + import base64 + import io + from PIL import Image + from google import genai + from google.genai.interactions import CodeExecution, ImageContent, TextContent + + client = genai.Client() + + interaction = client.interactions.create( + model="gemini-3.8-flash", + input=[ + ImageContent( + uri="https://storage.googleapis.com/cloud-samples-data/generative-ai/image/robotic.jpeg", + mime_type="image/jpeg", + ), + TextContent( + text="Annotate on the image with arrows of different colors, which object should go into which bin." + ), + ], + tools=[CodeExecution()], + ) + + img_count = 0 + for step in interaction.steps: + if step.type == "code_execution_call": + print("####################### 1. Generate Python Code #######################") + print(step.arguments.code) + elif step.type == "code_execution_result": + print("####################### 2. Executing Python Code #######################") + print(step.result) + + if interaction.output_image: + print("####################### 3. Save Output #######################") + img_count += 1 + output_location = f"robotic-annotate-output-{img_count}.jpg" + image_bytes = base64.b64decode(interaction.output_image.data) + image = Image.open(io.BytesIO(image_bytes)) + image = image.convert("RGB") + image.save(output_location) + print(f"Output is saved to {output_location}") + + if interaction.output_text: + print(interaction.output_text) + + # [END googlegenaisdk_interactions_codeexecution_annotateimage_with_txt_gcsimg] + return True + + +if __name__ == "__main__": + generate_content() diff --git a/genai/code_execution/codeexecution_interactions_barplot_with_txt_img.py b/genai/code_execution/codeexecution_interactions_barplot_with_txt_img.py new file mode 100644 index 00000000000..cebcfe2b75f --- /dev/null +++ b/genai/code_execution/codeexecution_interactions_barplot_with_txt_img.py @@ -0,0 +1,68 @@ +# Copyright 2026 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# https://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + + +def generate_content() -> bool: + # [START googlegenaisdk_interactions_codeexecution_barplot_with_txt_img] + import base64 + import io + from PIL import Image + from google import genai + from google.genai.interactions import CodeExecution, ImageContent, TextContent + + client = genai.Client() + + interaction = client.interactions.create( + model="gemini-3.8-flash", + input=[ + ImageContent( + uri="https://storage.googleapis.com/cloud-samples-data/generative-ai/image/benchmark.jpeg", + mime_type="image/jpeg", + ), + TextContent( + text="Make a bar chart of per-category performance, normalize prior SOTA as 1.0 for each task," + "then take average per-category. Plot using matplotlib with nice style." + ), + ], + tools=[CodeExecution()], + ) + + img_count = 0 + for step in interaction.steps: + if step.type == "code_execution_call": + print("####################### 1. Generate Python Code #######################") + print(step.arguments.code) + elif step.type == "code_execution_result": + print("####################### 2. Executing Python Code #######################") + print(step.result) + + if interaction.output_image: + print("####################### 3. Save Output #######################") + img_count += 1 + output_location = f"output-barplot-{img_count}.jpg" + image_bytes = base64.b64decode(interaction.output_image.data) + image = Image.open(io.BytesIO(image_bytes)) + image = image.convert("RGB") + image.save(output_location) + print(f"Output is saved to {output_location}") + + if interaction.output_text: + print(interaction.output_text) + + # [END googlegenaisdk_interactions_codeexecution_barplot_with_txt_img] + return True + + +if __name__ == "__main__": + generate_content() diff --git a/genai/code_execution/codeexecution_interactions_cropimage_with_txt_img.py b/genai/code_execution/codeexecution_interactions_cropimage_with_txt_img.py new file mode 100644 index 00000000000..112eba58050 --- /dev/null +++ b/genai/code_execution/codeexecution_interactions_cropimage_with_txt_img.py @@ -0,0 +1,65 @@ +# Copyright 2026 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# https://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + + +def generate_content() -> bool: + # [START googlegenaisdk_interactions_codeexecution_cropimage_with_txt_img] + import base64 + import io + import requests + from PIL import Image + from google import genai + from google.genai.interactions import CodeExecution, ImageContent, TextContent + + # Download the input image + image_path = "https://storage.googleapis.com/cloud-samples-data/generative-ai/image/chips.jpeg" + image_bytes = requests.get(image_path).content + b64_image = base64.b64encode(image_bytes).decode("utf-8") + + client = genai.Client() + + interaction = client.interactions.create( + model="gemini-3.8-flash", + input=[ + ImageContent(data=b64_image, mime_type="image/jpeg"), + TextContent(text="Locate the ESMT chip. What are the numbers on the chip?"), + ], + tools=[CodeExecution()], + ) + + for step in interaction.steps: + if step.type == "code_execution_call": + print("####################### 1. Generate Python Code #######################") + print(step.arguments.code) + elif step.type == "code_execution_result": + print("####################### 2. Executing Python Code #######################") + print(step.result) + + if interaction.output_image: + print("####################### 3. Save Output #######################") + image_data = base64.b64decode(interaction.output_image.data) + image = Image.open(io.BytesIO(image_data)) + output_location = "ESMT-chip-output.jpg" + image.save(output_location) + print(f"Output is saved to {output_location}") + + if interaction.output_text: + print(interaction.output_text) + + # [END googlegenaisdk_interactions_codeexecution_cropimage_with_txt_img] + return True + + +if __name__ == "__main__": + generate_content() diff --git a/genai/code_execution/test_codeexecution.py b/genai/code_execution/test_codeexecution.py index ea978643c7c..eb7e8ce1c14 100644 --- a/genai/code_execution/test_codeexecution.py +++ b/genai/code_execution/test_codeexecution.py @@ -16,6 +16,9 @@ import codeexecution_annotateimage_with_txt_gcsimg import codeexecution_barplot_with_txt_img import codeexecution_cropimage_with_txt_img +import codeexecution_interactions_annotateimage_with_txt_gcsimg +import codeexecution_interactions_barplot_with_txt_img +import codeexecution_interactions_cropimage_with_txt_img os.environ["GOOGLE_GENAI_USE_ENTERPRISE"] = "True" os.environ["GOOGLE_CLOUD_LOCATION"] = "global" # "us-central1" @@ -33,3 +36,16 @@ def test_codeexecution_barplot_with_txt_img() -> None: def test_codeexecution_cropimage_with_txt_img() -> None: assert codeexecution_cropimage_with_txt_img.generate_content() + + +def test_codeexecution_interactions_annotateimage_with_txt_gcsimg() -> None: + assert codeexecution_interactions_annotateimage_with_txt_gcsimg.generate_content() + + +def test_codeexecution_interactions_barplot_with_txt_img() -> None: + assert codeexecution_interactions_barplot_with_txt_img.generate_content() + + +def test_codeexecution_interactions_cropimage_with_txt_img() -> None: + assert codeexecution_interactions_cropimage_with_txt_img.generate_content() + diff --git a/genai/content_cache/requirements.txt b/genai/content_cache/requirements.txt index 1efe7b29dbc..ad433f48578 100644 --- a/genai/content_cache/requirements.txt +++ b/genai/content_cache/requirements.txt @@ -1 +1 @@ -google-genai==1.42.0 +google-genai==2.29.0 diff --git a/genai/controlled_generation/ctrlgen_interactions_with_class_schema.py b/genai/controlled_generation/ctrlgen_interactions_with_class_schema.py new file mode 100644 index 00000000000..bc141cbdea9 --- /dev/null +++ b/genai/controlled_generation/ctrlgen_interactions_with_class_schema.py @@ -0,0 +1,50 @@ +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# https://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + + +def generate_content() -> str: + # [START googlegenaisdk_interactions_ctrlgen_with_class_schema] + import json + from google import genai + from google.genai.interactions import TextResponseFormat + from pydantic import BaseModel + + class Recipe(BaseModel): + recipe_name: str + ingredients: list[str] + + client = genai.Client() + interaction = client.interactions.create( + model="gemini-3.8-flash", + input="List a few popular cookie recipes.", + response_format=TextResponseFormat( + mime_type="application/json", + schema={ + "type": "array", + "items": Recipe.model_json_schema(), + }, + ), + ) + + # Use the response as a JSON string + print(interaction.output_text) + # Parse the response JSON into Pydantic models + recipes = [Recipe(**r) for r in json.loads(interaction.output_text)] + print(recipes) + # [END googlegenaisdk_interactions_ctrlgen_with_class_schema] + return interaction.output_text + + +if __name__ == "__main__": + generate_content() diff --git a/genai/controlled_generation/ctrlgen_interactions_with_enum_class_schema.py b/genai/controlled_generation/ctrlgen_interactions_with_enum_class_schema.py new file mode 100644 index 00000000000..c2d86f4b768 --- /dev/null +++ b/genai/controlled_generation/ctrlgen_interactions_with_enum_class_schema.py @@ -0,0 +1,48 @@ +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# https://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + + +def generate_content() -> str: + # [START googlegenaisdk_interactions_ctrlgen_with_enum_class_schema] + import enum + from google import genai + from google.genai.interactions import TextResponseFormat + + class InstrumentClass(enum.Enum): + PERCUSSION = "Percussion" + STRING = "String" + WOODWIND = "Woodwind" + BRASS = "Brass" + KEYBOARD = "Keyboard" + + client = genai.Client() + interaction = client.interactions.create( + model="gemini-3.8-flash", + input="What type of instrument is a guitar?", + response_format=TextResponseFormat( + mime_type="text/x.enum", + schema={ + "type": "string", + "enum": [e.value for e in InstrumentClass], + }, + ), + ) + + print(interaction.output_text) + # [END googlegenaisdk_interactions_ctrlgen_with_enum_class_schema] + return interaction.output_text + + +if __name__ == "__main__": + generate_content() diff --git a/genai/controlled_generation/ctrlgen_interactions_with_enum_schema.py b/genai/controlled_generation/ctrlgen_interactions_with_enum_schema.py new file mode 100644 index 00000000000..9975c897f57 --- /dev/null +++ b/genai/controlled_generation/ctrlgen_interactions_with_enum_schema.py @@ -0,0 +1,40 @@ +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# https://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + + +def generate_content() -> str: + # [START googlegenaisdk_interactions_ctrlgen_with_enum_schema] + from google import genai + from google.genai.interactions import TextResponseFormat + + client = genai.Client() + interaction = client.interactions.create( + model="gemini-3.8-flash", + input="What type of instrument is an oboe?", + response_format=TextResponseFormat( + mime_type="text/x.enum", + schema={ + "type": "string", + "enum": ["Percussion", "String", "Woodwind", "Brass", "Keyboard"], + }, + ), + ) + + print(interaction.output_text) + # [END googlegenaisdk_interactions_ctrlgen_with_enum_schema] + return interaction.output_text + + +if __name__ == "__main__": + generate_content() diff --git a/genai/controlled_generation/ctrlgen_interactions_with_nested_class_schema.py b/genai/controlled_generation/ctrlgen_interactions_with_nested_class_schema.py new file mode 100644 index 00000000000..c480f7db429 --- /dev/null +++ b/genai/controlled_generation/ctrlgen_interactions_with_nested_class_schema.py @@ -0,0 +1,54 @@ +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# https://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + + +def generate_content() -> str: + # [START googlegenaisdk_interactions_ctrlgen_with_nested_class_schema] + import enum + from google import genai + from google.genai.interactions import TextResponseFormat + from pydantic import BaseModel + + class Grade(str, enum.Enum): + A_PLUS = "a+" + A = "a" + B = "b" + C = "c" + D = "d" + F = "f" + + class Recipe(BaseModel): + recipe_name: str + rating: Grade + + client = genai.Client() + interaction = client.interactions.create( + model="gemini-3.8-flash", + input="List about 10 home-baked cookies and give them grades based on tastiness.", + response_format=TextResponseFormat( + mime_type="application/json", + schema={ + "type": "array", + "items": Recipe.model_json_schema(), + }, + ), + ) + + print(interaction.output_text) + # [END googlegenaisdk_interactions_ctrlgen_with_nested_class_schema] + return interaction.output_text + + +if __name__ == "__main__": + generate_content() diff --git a/genai/controlled_generation/ctrlgen_interactions_with_nullable_schema.py b/genai/controlled_generation/ctrlgen_interactions_with_nullable_schema.py new file mode 100644 index 00000000000..bcbc1349b99 --- /dev/null +++ b/genai/controlled_generation/ctrlgen_interactions_with_nullable_schema.py @@ -0,0 +1,68 @@ +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# https://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + + +def generate_content() -> str: + # [START googlegenaisdk_interactions_ctrlgen_with_nullable_schema] + from google import genai + from google.genai.interactions import TextResponseFormat + + response_schema = { + "type": "object", + "properties": { + "forecast": { + "type": "array", + "items": { + "type": "object", + "properties": { + "Day": {"type": "string", "nullable": True}, + "Forecast": {"type": "string", "nullable": True}, + "Temperature": {"type": "integer", "nullable": True}, + "Humidity": {"type": "string", "nullable": True}, + "Wind Speed": {"type": "integer", "nullable": True}, + }, + "required": ["Day", "Temperature", "Forecast", "Wind Speed"], + }, + } + }, + } + + prompt = """ + The week ahead brings a mix of weather conditions. + Sunday is expected to be sunny with a temperature of 77°F and a humidity level of 50%. Winds will be light at around 10 km/h. + Monday will see partly cloudy skies with a slightly cooler temperature of 72°F and the winds will pick up slightly to around 15 km/h. + Tuesday brings rain showers, with temperatures dropping to 64°F and humidity rising to 70%. + Wednesday may see thunderstorms, with a temperature of 68°F. + Thursday will be cloudy with a temperature of 66°F and moderate humidity at 60%. + Friday returns to partly cloudy conditions, with a temperature of 73°F and the Winds will be light at 12 km/h. + Finally, Saturday rounds off the week with sunny skies, a temperature of 80°F, and a humidity level of 40%. Winds will be gentle at 8 km/h. + """ + + client = genai.Client() + interaction = client.interactions.create( + model="gemini-3.8-flash", + input=prompt, + response_format=TextResponseFormat( + mime_type="application/json", + schema=response_schema, + ), + ) + + print(interaction.output_text) + # [END googlegenaisdk_interactions_ctrlgen_with_nullable_schema] + return interaction.output_text + + +if __name__ == "__main__": + generate_content() diff --git a/genai/controlled_generation/ctrlgen_interactions_with_resp_schema.py b/genai/controlled_generation/ctrlgen_interactions_with_resp_schema.py new file mode 100644 index 00000000000..76d23cb2a5b --- /dev/null +++ b/genai/controlled_generation/ctrlgen_interactions_with_resp_schema.py @@ -0,0 +1,53 @@ +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# https://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + + +def generate_content() -> str: + # [START googlegenaisdk_interactions_ctrlgen_with_resp_schema] + from google import genai + from google.genai.interactions import TextResponseFormat + + response_schema = { + "type": "array", + "items": { + "type": "object", + "properties": { + "recipe_name": {"type": "string"}, + "ingredients": {"type": "array", "items": {"type": "string"}}, + }, + "required": ["recipe_name", "ingredients"], + }, + } + + prompt = """ + List a few popular cookie recipes. + """ + + client = genai.Client() + interaction = client.interactions.create( + model="gemini-3.8-flash", + input=prompt, + response_format=TextResponseFormat( + mime_type="application/json", + schema=response_schema, + ), + ) + + print(interaction.output_text) + # [END googlegenaisdk_interactions_ctrlgen_with_resp_schema] + return interaction.output_text + + +if __name__ == "__main__": + generate_content() diff --git a/genai/controlled_generation/requirements.txt b/genai/controlled_generation/requirements.txt index 1efe7b29dbc..ad433f48578 100644 --- a/genai/controlled_generation/requirements.txt +++ b/genai/controlled_generation/requirements.txt @@ -1 +1 @@ -google-genai==1.42.0 +google-genai==2.29.0 diff --git a/genai/controlled_generation/test_controlled_generation_examples.py b/genai/controlled_generation/test_controlled_generation_examples.py index 2bd518be054..5bf4f3df57f 100644 --- a/genai/controlled_generation/test_controlled_generation_examples.py +++ b/genai/controlled_generation/test_controlled_generation_examples.py @@ -18,6 +18,12 @@ import os +import ctrlgen_interactions_with_class_schema +import ctrlgen_interactions_with_enum_class_schema +import ctrlgen_interactions_with_enum_schema +import ctrlgen_interactions_with_nested_class_schema +import ctrlgen_interactions_with_nullable_schema +import ctrlgen_interactions_with_resp_schema import ctrlgen_with_class_schema import ctrlgen_with_enum_class_schema import ctrlgen_with_enum_schema @@ -53,3 +59,28 @@ def test_ctrlgen_with_nullable_schema() -> None: def test_ctrlgen_with_resp_schema() -> None: assert ctrlgen_with_resp_schema.generate_content() + + +def test_ctrlgen_interactions_with_class_schema() -> None: + assert ctrlgen_interactions_with_class_schema.generate_content() + + +def test_ctrlgen_interactions_with_enum_class_schema() -> None: + assert ctrlgen_interactions_with_enum_class_schema.generate_content() + + +def test_ctrlgen_interactions_with_enum_schema() -> None: + assert ctrlgen_interactions_with_enum_schema.generate_content() + + +def test_ctrlgen_interactions_with_nested_class_schema() -> None: + assert ctrlgen_interactions_with_nested_class_schema.generate_content() + + +def test_ctrlgen_interactions_with_nullable_schema() -> None: + assert ctrlgen_interactions_with_nullable_schema.generate_content() + + +def test_ctrlgen_interactions_with_resp_schema() -> None: + assert ctrlgen_interactions_with_resp_schema.generate_content() + diff --git a/genai/count_tokens/requirements.txt b/genai/count_tokens/requirements.txt index 726dd09178a..0fa4fa1b71c 100644 --- a/genai/count_tokens/requirements.txt +++ b/genai/count_tokens/requirements.txt @@ -1,2 +1,2 @@ -google-genai==1.42.0 +google-genai==2.29.0 sentencepiece==0.2.1 diff --git a/genai/express_mode/requirements.txt b/genai/express_mode/requirements.txt index 1efe7b29dbc..ad433f48578 100644 --- a/genai/express_mode/requirements.txt +++ b/genai/express_mode/requirements.txt @@ -1 +1 @@ -google-genai==1.42.0 +google-genai==2.29.0 diff --git a/genai/image_generation/imggen_interactions_mmflash_edit_img_with_txt_img.py b/genai/image_generation/imggen_interactions_mmflash_edit_img_with_txt_img.py new file mode 100644 index 00000000000..2fcc00eaf9f --- /dev/null +++ b/genai/image_generation/imggen_interactions_mmflash_edit_img_with_txt_img.py @@ -0,0 +1,51 @@ +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# https://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + + +def generate_content() -> str: + # [START googlegenaisdk_interactions_imggen_mmflash_edit_img_with_txt_img] + import base64 + from io import BytesIO + from google import genai + from google.genai.interactions import ImageContent, ImageResponseFormat, TextContent + from PIL import Image + + client = genai.Client() + + # Using an image of Eiffel tower, with fireworks in the background. + with open("test_resources/example-image-eiffel-tower.png", "rb") as image_file: + b64_image = base64.b64encode(image_file.read()).decode("utf-8") + + interaction = client.interactions.create( + model="gemini-nano-banana-2.1", + input=[ + ImageContent(data=b64_image, mime_type="image/png"), + TextContent(text="Edit this image to make it look like a cartoon."), + ], + response_format=ImageResponseFormat(), + ) + + if interaction.output_text: + print(interaction.output_text) + + if interaction.output_image: + image = Image.open(BytesIO(base64.b64decode(interaction.output_image.data))) + image.save("output_folder/bw-example-image.png") + + # [END googlegenaisdk_interactions_imggen_mmflash_edit_img_with_txt_img] + return "output_folder/bw-example-image.png" + + +if __name__ == "__main__": + generate_content() diff --git a/genai/image_generation/imggen_interactions_mmflash_img_with_vid.py b/genai/image_generation/imggen_interactions_mmflash_img_with_vid.py new file mode 100644 index 00000000000..120ec730f21 --- /dev/null +++ b/genai/image_generation/imggen_interactions_mmflash_img_with_vid.py @@ -0,0 +1,53 @@ +# Copyright 2026 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# https://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + + +def generate_content() -> str: + # [START googlegenaisdk_interactions_imggen_mmflash_img_with_vid] + import base64 + from io import BytesIO + from google import genai + from google.genai.interactions import ImageResponseFormat, TextContent, VideoContent + from PIL import Image + + client = genai.Client() + + # A video on 'The ABCs of agent building' + video = "https://www.youtube.com/watch?v=rjoMZyxncUI" + + interaction = client.interactions.create( + model="gemini-nano-banana-2.1", + input=[ + VideoContent( + uri=video, + mime_type="video/mp4", + ), + TextContent(text="Generate an infographic of the topics covered in this video."), + ], + response_format=ImageResponseFormat(), + ) + + if interaction.output_text: + print(interaction.output_text) + + if interaction.output_image: + image = Image.open(BytesIO(base64.b64decode(interaction.output_image.data))) + image.save("output_folder/video-image.png") + + # [END googlegenaisdk_interactions_imggen_mmflash_img_with_vid] + return "output_folder/video-image.png" + + +if __name__ == "__main__": + generate_content() diff --git a/genai/image_generation/imggen_interactions_mmflash_locale_aware_with_txt.py b/genai/image_generation/imggen_interactions_mmflash_locale_aware_with_txt.py new file mode 100644 index 00000000000..82d9486978c --- /dev/null +++ b/genai/image_generation/imggen_interactions_mmflash_locale_aware_with_txt.py @@ -0,0 +1,44 @@ +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# https://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + + +def generate_content() -> str: + # [START googlegenaisdk_interactions_imggen_mmflash_locale_aware_with_txt] + import base64 + from io import BytesIO + from google import genai + from google.genai.interactions import ImageResponseFormat + from PIL import Image + + client = genai.Client() + + interaction = client.interactions.create( + model="gemini-nano-banana-2.1", + input="Generate a photo of a breakfast meal.", + response_format=ImageResponseFormat(), + ) + + if interaction.output_text: + print(interaction.output_text) + + if interaction.output_image: + image = Image.open(BytesIO(base64.b64decode(interaction.output_image.data))) + image.save("output_folder/example-breakfast-meal.png") + + # [END googlegenaisdk_interactions_imggen_mmflash_locale_aware_with_txt] + return "output_folder/example-breakfast-meal.png" + + +if __name__ == "__main__": + generate_content() diff --git a/genai/image_generation/imggen_interactions_mmflash_multiple_imgs_with_txt.py b/genai/image_generation/imggen_interactions_mmflash_multiple_imgs_with_txt.py new file mode 100644 index 00000000000..b16627a8faf --- /dev/null +++ b/genai/image_generation/imggen_interactions_mmflash_multiple_imgs_with_txt.py @@ -0,0 +1,62 @@ +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# https://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + + +def generate_content() -> list[str]: + # [START googlegenaisdk_interactions_imggen_mmflash_multiple_imgs_with_txt] + import base64 + from io import BytesIO + from google import genai + from google.genai.interactions import ImageResponseFormat, TextResponseFormat + from PIL import Image + + client = genai.Client() + + interaction = client.interactions.create( + model="gemini-nano-banana-2.1", + input="Generate 3 images of a cat sitting on a chair.", + response_format=[ + ImageResponseFormat(), + TextResponseFormat(), + ], + ) + + saved_files = [] + image_counter = 1 + + for step in interaction.steps: + if step.type == "model_output": + for content in step.content: + if content.type == "text": + print(content.text) + elif content.type == "image": + image = Image.open(BytesIO(base64.b64decode(content.data))) + filename = f"output_folder/example-cats-0{image_counter}.png" + image.save(filename) + saved_files.append(filename) + image_counter += 1 + + # Fallback to output_image if no step-level images collected + if not saved_files and interaction.output_image: + image = Image.open(BytesIO(base64.b64decode(interaction.output_image.data))) + filename = "output_folder/example-cats-01.png" + image.save(filename) + saved_files.append(filename) + + # [END googlegenaisdk_interactions_imggen_mmflash_multiple_imgs_with_txt] + return saved_files + + +if __name__ == "__main__": + generate_content() diff --git a/genai/image_generation/imggen_interactions_mmflash_txt_and_img_with_txt.py b/genai/image_generation/imggen_interactions_mmflash_txt_and_img_with_txt.py new file mode 100644 index 00000000000..ffb57c5a5d8 --- /dev/null +++ b/genai/image_generation/imggen_interactions_mmflash_txt_and_img_with_txt.py @@ -0,0 +1,65 @@ +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# https://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + + +def generate_content() -> bool: + # [START googlegenaisdk_interactions_imggen_mmflash_txt_and_img_with_txt] + import base64 + from io import BytesIO + import os + from google import genai + from google.genai.interactions import ImageResponseFormat, TextResponseFormat + from PIL import Image + + client = genai.Client() + + interaction = client.interactions.create( + model="gemini-nano-banana-2.1", + input=( + "Generate an illustrated recipe for a paella. " + "Create images to go alongside the text as you generate the recipe." + ), + response_format=[ + TextResponseFormat(), + ImageResponseFormat(), + ], + ) + + os.makedirs("output_folder", exist_ok=True) + img_counter = 1 + with open("output_folder/paella-recipe.md", "w") as fp: + for step in interaction.steps: + if step.type == "model_output": + for content in step.content: + if content.type == "text": + fp.write(content.text) + elif content.type == "image": + image = Image.open(BytesIO(base64.b64decode(content.data))) + img_path = f"output_folder/example-image-{img_counter}.png" + image.save(img_path) + fp.write(f"![image]({img_path})\n") + img_counter += 1 + + if img_counter == 1 and interaction.output_image: + image = Image.open(BytesIO(base64.b64decode(interaction.output_image.data))) + img_path = "output_folder/example-image-1.png" + image.save(img_path) + fp.write(f"![image]({img_path})\n") + + # [END googlegenaisdk_interactions_imggen_mmflash_txt_and_img_with_txt] + return True + + +if __name__ == "__main__": + generate_content() diff --git a/genai/image_generation/imggen_interactions_mmflash_with_txt.py b/genai/image_generation/imggen_interactions_mmflash_with_txt.py new file mode 100644 index 00000000000..dd2425f037d --- /dev/null +++ b/genai/image_generation/imggen_interactions_mmflash_with_txt.py @@ -0,0 +1,48 @@ +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# https://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + + +def generate_content() -> str: + # [START googlegenaisdk_interactions_imggen_mmflash_with_txt] + import base64 + import os + from io import BytesIO + + from google import genai + from google.genai.interactions import ImageResponseFormat + from PIL import Image + + client = genai.Client() + + interaction = client.interactions.create( + model="gemini-nano-banana-2.1", + input="Generate an image of the Eiffel tower with fireworks in the background.", + response_format=ImageResponseFormat(), + ) + + if interaction.output_text: + print(interaction.output_text) + + if interaction.output_image: + image = Image.open(BytesIO(base64.b64decode(interaction.output_image.data))) + output_dir = "output_folder" + os.makedirs(output_dir, exist_ok=True) + image.save(os.path.join(output_dir, "example-image-eiffel-tower.png")) + + # [END googlegenaisdk_interactions_imggen_mmflash_with_txt] + return True + + +if __name__ == "__main__": + generate_content() diff --git a/genai/image_generation/requirements.txt b/genai/image_generation/requirements.txt index 75a39f7e582..1af6c711b57 100644 --- a/genai/image_generation/requirements.txt +++ b/genai/image_generation/requirements.txt @@ -1,2 +1,2 @@ -google-genai==1.42.0 +google-genai==2.29.0 pillow==12.3.0; python_version >= "3.10" diff --git a/genai/image_generation/test_image_generation_mmflash.py b/genai/image_generation/test_image_generation_mmflash.py index 1b6b46bae70..98226597841 100644 --- a/genai/image_generation/test_image_generation_mmflash.py +++ b/genai/image_generation/test_image_generation_mmflash.py @@ -18,6 +18,12 @@ import os +import imggen_interactions_mmflash_edit_img_with_txt_img +import imggen_interactions_mmflash_img_with_vid +import imggen_interactions_mmflash_locale_aware_with_txt +import imggen_interactions_mmflash_multiple_imgs_with_txt +import imggen_interactions_mmflash_txt_and_img_with_txt +import imggen_interactions_mmflash_with_txt import imggen_mmflash_edit_img_with_txt_img import imggen_mmflash_img_with_vid import imggen_mmflash_locale_aware_with_txt @@ -53,3 +59,28 @@ def test_imggen_mmflash_multiple_imgs_with_txt() -> None: def test_imggen_mmflash_img_with_vid() -> None: assert imggen_mmflash_img_with_vid.generate_content() + + +def test_imggen_interactions_mmflash_with_txt() -> None: + assert imggen_interactions_mmflash_with_txt.generate_content() + + +def test_imggen_interactions_mmflash_edit_img_with_txt_img() -> None: + assert imggen_interactions_mmflash_edit_img_with_txt_img.generate_content() + + +def test_imggen_interactions_mmflash_txt_and_img_with_txt() -> None: + assert imggen_interactions_mmflash_txt_and_img_with_txt.generate_content() + + +def test_imggen_interactions_mmflash_locale_aware_with_txt() -> None: + assert imggen_interactions_mmflash_locale_aware_with_txt.generate_content() + + +def test_imggen_interactions_mmflash_multiple_imgs_with_txt() -> None: + assert imggen_interactions_mmflash_multiple_imgs_with_txt.generate_content() + + +def test_imggen_interactions_mmflash_img_with_vid() -> None: + assert imggen_interactions_mmflash_img_with_vid.generate_content() + diff --git a/genai/live/requirements.txt b/genai/live/requirements.txt index 477952fc6d7..b20a2df28a8 100644 --- a/genai/live/requirements.txt +++ b/genai/live/requirements.txt @@ -1,4 +1,4 @@ -google-genai==1.42.0 +google-genai==2.29.0 scipy==1.18.1 websockets==15.0.1 numpy==2.5.3 diff --git a/genai/model_optimizer/requirements.txt b/genai/model_optimizer/requirements.txt index 1efe7b29dbc..ad433f48578 100644 --- a/genai/model_optimizer/requirements.txt +++ b/genai/model_optimizer/requirements.txt @@ -1 +1 @@ -google-genai==1.42.0 +google-genai==2.29.0 diff --git a/genai/provisioned_throughput/requirements.txt b/genai/provisioned_throughput/requirements.txt index 1efe7b29dbc..ad433f48578 100644 --- a/genai/provisioned_throughput/requirements.txt +++ b/genai/provisioned_throughput/requirements.txt @@ -1 +1 @@ -google-genai==1.42.0 +google-genai==2.29.0 diff --git a/genai/safety/requirements.txt b/genai/safety/requirements.txt index 1efe7b29dbc..ad433f48578 100644 --- a/genai/safety/requirements.txt +++ b/genai/safety/requirements.txt @@ -1 +1 @@ -google-genai==1.42.0 +google-genai==2.29.0 diff --git a/genai/template_folder/requirements.txt b/genai/template_folder/requirements.txt index 1efe7b29dbc..ad433f48578 100644 --- a/genai/template_folder/requirements.txt +++ b/genai/template_folder/requirements.txt @@ -1 +1 @@ -google-genai==1.42.0 +google-genai==2.29.0 diff --git a/genai/text_generation/requirements.txt b/genai/text_generation/requirements.txt index 1efe7b29dbc..ad433f48578 100644 --- a/genai/text_generation/requirements.txt +++ b/genai/text_generation/requirements.txt @@ -1 +1 @@ -google-genai==1.42.0 +google-genai==2.29.0 diff --git a/genai/text_generation/test_text_generation_examples.py b/genai/text_generation/test_text_generation_examples.py index d859b4ff73b..bd1d1f9c966 100644 --- a/genai/text_generation/test_text_generation_examples.py +++ b/genai/text_generation/test_text_generation_examples.py @@ -24,6 +24,24 @@ import textgen_chat_with_txt import textgen_code_with_pdf import textgen_config_with_txt +import textgen_interactions_async_with_txt +import textgen_interactions_chat_stream_with_txt +import textgen_interactions_chat_with_txt +import textgen_interactions_code_with_pdf +import textgen_interactions_config_with_txt +import textgen_interactions_sys_instr_with_txt +import textgen_interactions_transcript_with_gcs_audio +import textgen_interactions_with_gcs_audio +import textgen_interactions_with_local_video +import textgen_interactions_with_multi_img +import textgen_interactions_with_multi_local_img +import textgen_interactions_with_mute_video +import textgen_interactions_with_pdf +import textgen_interactions_with_txt +import textgen_interactions_with_txt_img +import textgen_interactions_with_txt_stream +import textgen_interactions_with_video +import textgen_interactions_with_youtube_video import textgen_sys_instr_with_txt import textgen_transcript_with_gcs_audio import textgen_with_gcs_audio @@ -37,6 +55,7 @@ import textgen_with_txt_stream import textgen_with_video import textgen_with_youtube_video +import thinking_textgen_interactions_with_txt import thinking_textgen_with_txt os.environ["GOOGLE_GENAI_USE_ENTERPRISE"] = "True" @@ -142,6 +161,104 @@ def test_textgen_code_with_pdf() -> None: response = textgen_code_with_pdf.generate_content() assert response + +def test_textgen_interactions_with_txt_stream() -> None: + response = textgen_interactions_with_txt_stream.generate_content() + assert response + + +def test_textgen_interactions_with_txt() -> None: + response = textgen_interactions_with_txt.generate_content() + assert response + + +def test_textgen_interactions_chat_with_txt() -> None: + response = textgen_interactions_chat_with_txt.generate_content() + assert response + + +def test_textgen_interactions_chat_stream_with_txt() -> None: + response = textgen_interactions_chat_stream_with_txt.generate_content() + assert response + + +def test_textgen_interactions_config_with_txt() -> None: + response = textgen_interactions_config_with_txt.generate_content() + assert response + + +def test_textgen_interactions_sys_instr_with_txt() -> None: + response = textgen_interactions_sys_instr_with_txt.generate_content() + assert response + + +def test_textgen_interactions_with_pdf() -> None: + response = textgen_interactions_with_pdf.generate_content() + assert response + + +def test_textgen_interactions_with_txt_img() -> None: + response = textgen_interactions_with_txt_img.generate_content() + assert response + + +def test_textgen_interactions_with_txt_thinking() -> None: + response = thinking_textgen_interactions_with_txt.generate_content() + assert response + + +def test_textgen_interactions_with_multi_img() -> None: + response = textgen_interactions_with_multi_img.generate_content() + assert response + + +def test_textgen_interactions_with_multi_local_img() -> None: + response = textgen_interactions_with_multi_local_img.generate_content( + "./test_data/latte.jpg", + "./test_data/scones.jpg", + ) + assert response + + +def test_textgen_interactions_with_mute_video() -> None: + response = textgen_interactions_with_mute_video.generate_content() + assert response + + +def test_textgen_interactions_with_gcs_audio() -> None: + response = textgen_interactions_with_gcs_audio.generate_content() + assert response + + +def test_textgen_interactions_transcript_with_gcs_audio() -> None: + response = textgen_interactions_transcript_with_gcs_audio.generate_content() + assert response + + +def test_textgen_interactions_with_video() -> None: + response = textgen_interactions_with_video.generate_content() + assert response + + +def test_textgen_interactions_async_with_txt() -> None: + response = textgen_interactions_async_with_txt.generate_content() + assert response + + +def test_textgen_interactions_with_local_video() -> None: + response = textgen_interactions_with_local_video.generate_content() + assert response + + +def test_textgen_interactions_with_youtube_video() -> None: + response = textgen_interactions_with_youtube_video.generate_content() + assert response + + +def test_textgen_interactions_code_with_pdf() -> None: + response = textgen_interactions_code_with_pdf.generate_content() + assert response + # Migrated to Model Optimser Folder # def test_model_optimizer_textgen_with_txt() -> None: # os.environ["GOOGLE_CLOUD_LOCATION"] = "us-central1" diff --git a/genai/text_generation/textgen_interactions_async_with_txt.py b/genai/text_generation/textgen_interactions_async_with_txt.py new file mode 100644 index 00000000000..b768d32377f --- /dev/null +++ b/genai/text_generation/textgen_interactions_async_with_txt.py @@ -0,0 +1,42 @@ +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# https://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import asyncio + + +async def generate_content() -> str: + # [START googlegenaisdk_interactions_textgen_async_with_txt] + from google import genai + + client = genai.Client() + model_id = "gemini-3.8-flash" + + interaction = await client.aio.interactions.create( + model=model_id, + input="Compose a song about the adventures of a time-traveling squirrel.", + response_modalities=["TEXT"], + ) + + print(interaction.output_text) + # Example response: + # (Verse 1) + # Sammy the squirrel, a furry little friend + # Had a knack for adventure, beyond all comprehend + + # [END googlegenaisdk_interactions_textgen_async_with_txt] + return interaction.output_text + + +if __name__ == "__main__": + asyncio.run(generate_content()) diff --git a/genai/text_generation/textgen_interactions_chat_stream_with_txt.py b/genai/text_generation/textgen_interactions_chat_stream_with_txt.py new file mode 100644 index 00000000000..9f0bf597781 --- /dev/null +++ b/genai/text_generation/textgen_interactions_chat_stream_with_txt.py @@ -0,0 +1,50 @@ +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# https://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + + +def generate_content() -> bool: + # [START googlegenaisdk_interactions_textgen_chat_stream_with_txt] + from google import genai + + client = genai.Client() + + interaction1 = client.interactions.create( + model="gemini-3.8-flash", + input="Hello", + ) + + stream = client.interactions.create( + model="gemini-3.8-flash", + previous_interaction_id=interaction1.id, + input="Why is the sky blue?", + stream=True, + ) + + for event in stream: + if event.event_type == "step.delta" and event.delta: + if getattr(event.delta, "type", None) == "text" and getattr( + event.delta, "text", None + ): + print(event.delta.text, end="", flush=True) + # Example response: + # The + # sky appears blue due to a phenomenon called **Rayleigh scattering**. Here's + # a breakdown of why: + # ... + # [END googlegenaisdk_interactions_textgen_chat_stream_with_txt] + return True + + +if __name__ == "__main__": + generate_content() diff --git a/genai/text_generation/textgen_interactions_chat_with_txt.py b/genai/text_generation/textgen_interactions_chat_with_txt.py new file mode 100644 index 00000000000..acc3ee4e976 --- /dev/null +++ b/genai/text_generation/textgen_interactions_chat_with_txt.py @@ -0,0 +1,40 @@ +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# https://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + + +def generate_content() -> str: + # [START googlegenaisdk_interactions_textgen_chat_with_txt] + from google import genai + + client = genai.Client() + interaction1 = client.interactions.create( + model="gemini-3.8-flash", + input="Hello", + ) + + interaction2 = client.interactions.create( + model="gemini-3.8-flash", + previous_interaction_id=interaction1.id, + input="Tell me a story.", + ) + print(interaction2.output_text) + # Example response: + # Okay, here's a story for you: + # ... + # [END googlegenaisdk_interactions_textgen_chat_with_txt] + return interaction2.output_text + + +if __name__ == "__main__": + generate_content() diff --git a/genai/text_generation/textgen_interactions_code_with_pdf.py b/genai/text_generation/textgen_interactions_code_with_pdf.py new file mode 100644 index 00000000000..aec4390945c --- /dev/null +++ b/genai/text_generation/textgen_interactions_code_with_pdf.py @@ -0,0 +1,54 @@ +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# https://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + + +def generate_content() -> str: + # [START googlegenaisdk_interactions_textgen_code_with_pdf] + from google import genai + from google.genai.interactions import DocumentContent, TextContent + + client = genai.Client() + model_id = "gemini-3.8-flash" + prompt = "Convert this python code to use Google Python Style Guide." + print("> ", prompt, "\n") + pdf_uri = "https://storage.googleapis.com/cloud-samples-data/generative-ai/text/inefficient_fibonacci_series_python_code.pdf" + + interaction = client.interactions.create( + model=model_id, + input=[ + DocumentContent( + uri=pdf_uri, + mime_type="application/pdf", + ), + TextContent(text=prompt), + ], + ) + + print(interaction.output_text) + # Example response: + # > Convert this python code to use Google Python Style Guide. + # + # def generate_fibonacci_sequence(num_terms: int) -> list[int]: + # """Generates the Fibonacci sequence up to a specified number of terms. + # + # This function calculates the Fibonacci sequence starting with 0 and 1. + # It handles base cases for 0, 1, and 2 terms efficiently. + # + # # ... + # [END googlegenaisdk_interactions_textgen_code_with_pdf] + return interaction.output_text + + +if __name__ == "__main__": + generate_content() diff --git a/genai/text_generation/textgen_interactions_config_with_txt.py b/genai/text_generation/textgen_interactions_config_with_txt.py new file mode 100644 index 00000000000..bdff812794f --- /dev/null +++ b/genai/text_generation/textgen_interactions_config_with_txt.py @@ -0,0 +1,44 @@ +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# https://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + + +def generate_content() -> str: + # [START googlegenaisdk_interactions_textgen_config_with_txt] + from google import genai + from google.genai.interactions import GenerationConfig + + client = genai.Client() + interaction = client.interactions.create( + model="gemini-3.8-flash", + input="Why is the sky blue?", + generation_config=GenerationConfig( + temperature=0, + top_p=0.95, + seed=5, + max_output_tokens=500, + stop_sequences=["STOP!"], + ), + response_mime_type="application/json", + ) + print(interaction.output_text) + # Example response: + # { + # "explanation": "The sky appears blue due to a phenomenon called Rayleigh scattering. When ... + # } + # [END googlegenaisdk_interactions_textgen_config_with_txt] + return interaction.output_text + + +if __name__ == "__main__": + generate_content() diff --git a/genai/text_generation/textgen_interactions_sys_instr_with_txt.py b/genai/text_generation/textgen_interactions_sys_instr_with_txt.py new file mode 100644 index 00000000000..fd07a250533 --- /dev/null +++ b/genai/text_generation/textgen_interactions_sys_instr_with_txt.py @@ -0,0 +1,34 @@ +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# https://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + + +def generate_content() -> str: + # [START googlegenaisdk_interactions_textgen_sys_instr_with_txt] + from google import genai + + client = genai.Client() + interaction = client.interactions.create( + model="gemini-3.8-flash", + input="Why is the sky blue?", + system_instruction="You're a language translator. Your mission is to translate text in English to French.", + ) + print(interaction.output_text) + # Example response: + # Pourquoi le ciel est-il bleu ? + # [END googlegenaisdk_interactions_textgen_sys_instr_with_txt] + return interaction.output_text + + +if __name__ == "__main__": + generate_content() diff --git a/genai/text_generation/textgen_interactions_transcript_with_gcs_audio.py b/genai/text_generation/textgen_interactions_transcript_with_gcs_audio.py new file mode 100644 index 00000000000..b9ae58f9f68 --- /dev/null +++ b/genai/text_generation/textgen_interactions_transcript_with_gcs_audio.py @@ -0,0 +1,48 @@ +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# https://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + + +def generate_content() -> str: + # [START googlegenaisdk_interactions_textgen_transcript_with_gcs_audio] + from google import genai + from google.genai.interactions import AudioContent, TextContent + + client = genai.Client() + prompt = """ + Transcribe the interview, in the format of timecode, speaker, caption. + Use speaker A, speaker B, etc. to identify speakers. + """ + interaction = client.interactions.create( + model="gemini-3.8-flash", + input=[ + AudioContent( + uri="gs://cloud-samples-data/generative-ai/audio/pixel.mp3", + mime_type="audio/mpeg", + ), + TextContent(text=prompt), + ], + ) + print(interaction.output_text) + # Example response: + # [00:00:00] **Speaker A:** your devices are getting better over time. And so ... + # [00:00:14] **Speaker B:** Welcome to the Made by Google podcast where we meet ... + # [00:00:20] **Speaker B:** Here's your host, Rasheed Finch. + # [00:00:23] **Speaker C:** Today we're talking to Aisha Sharif and DeCarlos Love. ... + # ... + # [END googlegenaisdk_interactions_textgen_transcript_with_gcs_audio] + return interaction.output_text + + +if __name__ == "__main__": + generate_content() diff --git a/genai/text_generation/textgen_interactions_with_gcs_audio.py b/genai/text_generation/textgen_interactions_with_gcs_audio.py new file mode 100644 index 00000000000..694eaf3de2b --- /dev/null +++ b/genai/text_generation/textgen_interactions_with_gcs_audio.py @@ -0,0 +1,45 @@ +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# https://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + + +def generate_content() -> str: + # [START googlegenaisdk_interactions_textgen_with_gcs_audio] + from google import genai + from google.genai.interactions import AudioContent, TextContent + + client = genai.Client() + prompt = """ + Provide a concise summary of the main points in the audio file. + """ + interaction = client.interactions.create( + model="gemini-3.8-flash", + input=[ + AudioContent( + uri="gs://cloud-samples-data/generative-ai/audio/pixel.mp3", + mime_type="audio/mpeg", + ), + TextContent(text=prompt), + ], + ) + print(interaction.output_text) + # Example response: + # Here's a summary of the main points from the audio file: + + # The Made by Google podcast discusses the Pixel feature drops with product managers Aisha Sheriff and De Carlos Love. The key idea is that devices should improve over time, with a connected experience across phones, watches, earbuds, and tablets. + # [END googlegenaisdk_interactions_textgen_with_gcs_audio] + return interaction.output_text + + +if __name__ == "__main__": + generate_content() diff --git a/genai/text_generation/textgen_interactions_with_local_video.py b/genai/text_generation/textgen_interactions_with_local_video.py new file mode 100644 index 00000000000..c20452c3259 --- /dev/null +++ b/genai/text_generation/textgen_interactions_with_local_video.py @@ -0,0 +1,53 @@ +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# https://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + + +def generate_content() -> str: + # [START googlegenaisdk_interactions_textgen_with_local_video] + import base64 + from google import genai + from google.genai.interactions import TextContent, VideoContent + + client = genai.Client() + model_id = "gemini-3.8-flash" + + # Read local video file content + with open("test_data/describe_video_content.mp4", "rb") as fp: + # Video source: https://storage.googleapis.com/cloud-samples-data/generative-ai/video/describe_video_content.mp4 + video_content = fp.read() + video_b64 = base64.b64encode(video_content).decode("utf-8") + + interaction = client.interactions.create( + model=model_id, + input=[ + TextContent(text="hello-world"), + VideoContent( + data=video_b64, + mime_type="video/mp4", + ), + TextContent(text="Write a short and engaging blog post based on this video."), + ], + ) + + print(interaction.output_text) + # Example response: + # Okay, here's a short and engaging blog post based on the climbing video: + # **Title: Conquering the Wall: A Glimpse into the World of Indoor Climbing** + # ... + # [END googlegenaisdk_interactions_textgen_with_local_video] + return interaction.output_text + + +if __name__ == "__main__": + generate_content() diff --git a/genai/text_generation/textgen_interactions_with_multi_img.py b/genai/text_generation/textgen_interactions_with_multi_img.py new file mode 100644 index 00000000000..04fb39ecc66 --- /dev/null +++ b/genai/text_generation/textgen_interactions_with_multi_img.py @@ -0,0 +1,55 @@ +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# https://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + + +def generate_content() -> str: + # [START googlegenaisdk_interactions_textgen_with_multi_img] + import base64 + from google import genai + from google.genai.interactions import ImageContent, TextContent + + client = genai.Client() + + # Read content from GCS + gcs_file_img_path = "gs://cloud-samples-data/generative-ai/image/scones.jpg" + + # Read content from a local file + with open("test_data/latte.jpg", "rb") as f: + local_file_img_bytes = f.read() + local_file_img_b64 = base64.b64encode(local_file_img_bytes).decode("utf-8") + + interaction = client.interactions.create( + model="gemini-3.8-flash", + input=[ + TextContent(text="Generate a list of all the objects contained in both images."), + ImageContent( + uri=gcs_file_img_path, + mime_type="image/jpeg", + ), + ImageContent( + data=local_file_img_b64, + mime_type="image/jpeg", + ), + ], + ) + print(interaction.output_text) + # Example response: + # Okay, here's the list of objects present in both images: + # ... + # [END googlegenaisdk_interactions_textgen_with_multi_img] + return interaction.output_text + + +if __name__ == "__main__": + generate_content() diff --git a/genai/text_generation/textgen_interactions_with_multi_local_img.py b/genai/text_generation/textgen_interactions_with_multi_local_img.py new file mode 100644 index 00000000000..2862e4852e5 --- /dev/null +++ b/genai/text_generation/textgen_interactions_with_multi_local_img.py @@ -0,0 +1,60 @@ +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# https://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + + +def generate_content(image_path_1: str, image_path_2: str) -> str: + # [START googlegenaisdk_interactions_textgen_with_multi_local_img] + import base64 + from google import genai + from google.genai.interactions import ImageContent, TextContent + + client = genai.Client() + # TODO(Developer): Update the below file paths to your images + # image_path_1 = "path/to/your/image1.jpg" + # image_path_2 = "path/to/your/image2.jpg" + with open(image_path_1, "rb") as f: + image_1_bytes = f.read() + with open(image_path_2, "rb") as f: + image_2_bytes = f.read() + + image_1_b64 = base64.b64encode(image_1_bytes).decode("utf-8") + image_2_b64 = base64.b64encode(image_2_bytes).decode("utf-8") + + interaction = client.interactions.create( + model="gemini-3.8-flash", + input=[ + TextContent(text="Generate a list of all the objects contained in both images."), + ImageContent( + data=image_1_b64, + mime_type="image/jpeg", + ), + ImageContent( + data=image_2_b64, + mime_type="image/jpeg", + ), + ], + ) + print(interaction.output_text) + # Example response: + # Okay, here's a jingle combining the elements of both sets of images, focusing on ... + # ... + # [END googlegenaisdk_interactions_textgen_with_multi_local_img] + return interaction.output_text + + +if __name__ == "__main__": + generate_content( + "./test_data/latte.jpg", + "./test_data/scones.jpg", + ) diff --git a/genai/text_generation/textgen_interactions_with_mute_video.py b/genai/text_generation/textgen_interactions_with_mute_video.py new file mode 100644 index 00000000000..edb8ccaa811 --- /dev/null +++ b/genai/text_generation/textgen_interactions_with_mute_video.py @@ -0,0 +1,40 @@ +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# https://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + + +def generate_content() -> str: + # [START googlegenaisdk_interactions_textgen_with_mute_video] + from google import genai + from google.genai.interactions import TextContent, VideoContent + + client = genai.Client() + interaction = client.interactions.create( + model="gemini-3.8-flash", + input=[ + VideoContent( + uri="gs://cloud-samples-data/generative-ai/video/ad_copy_from_video.mp4", + mime_type="video/mp4", + ), + TextContent(text="What is in the video?"), + ], + ) + print(interaction.output_text) + # Example response: + # The video shows several people surfing in an ocean with a coastline in the background. The camera ... + # [END googlegenaisdk_interactions_textgen_with_mute_video] + return interaction.output_text + + +if __name__ == "__main__": + generate_content() diff --git a/genai/text_generation/textgen_interactions_with_pdf.py b/genai/text_generation/textgen_interactions_with_pdf.py new file mode 100644 index 00000000000..386c53a50a3 --- /dev/null +++ b/genai/text_generation/textgen_interactions_with_pdf.py @@ -0,0 +1,54 @@ +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# https://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + + +def generate_content() -> str: + # [START googlegenaisdk_interactions_textgen_with_pdf] + from google import genai + from google.genai.interactions import DocumentContent, TextContent + + client = genai.Client() + model_id = "gemini-3.8-flash" + + prompt = """ + You are a highly skilled document summarization specialist. + Your task is to provide a concise executive summary of no more than 300 words. + Please summarize the given document for a general audience. + """ + + interaction = client.interactions.create( + model=model_id, + input=[ + DocumentContent( + uri="gs://cloud-samples-data/generative-ai/pdf/1706.03762v7.pdf", + mime_type="application/pdf", + ), + TextContent(text=prompt), + ], + ) + + print(interaction.output_text) + # Example response: + # Here is a summary of the document in 300 words. + # + # The paper introduces the Transformer, a novel neural network architecture for + # sequence transduction tasks like machine translation. Unlike existing models that rely on recurrent or + # convolutional layers, the Transformer is based entirely on attention mechanisms. + # ... + # [END googlegenaisdk_interactions_textgen_with_pdf] + return interaction.output_text + + +if __name__ == "__main__": + generate_content() diff --git a/genai/text_generation/textgen_interactions_with_txt.py b/genai/text_generation/textgen_interactions_with_txt.py new file mode 100644 index 00000000000..43bba55aff4 --- /dev/null +++ b/genai/text_generation/textgen_interactions_with_txt.py @@ -0,0 +1,36 @@ +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# https://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + + +def generate_content() -> str: + # [START googlegenaisdk_interactions_textgen_with_txt] + from google import genai + + client = genai.Client() + interaction = client.interactions.create( + model="gemini-3.8-flash", + input="How does AI work?", + ) + print(interaction.output_text) + # Example response: + # Okay, let's break down how AI works. It's a broad field, so I'll focus on the ... + # + # Here's a simplified overview: + # ... + # [END googlegenaisdk_interactions_textgen_with_txt] + return interaction.output_text + + +if __name__ == "__main__": + generate_content() diff --git a/genai/text_generation/textgen_interactions_with_txt_img.py b/genai/text_generation/textgen_interactions_with_txt_img.py new file mode 100644 index 00000000000..33c64013c4d --- /dev/null +++ b/genai/text_generation/textgen_interactions_with_txt_img.py @@ -0,0 +1,40 @@ +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# https://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + + +def generate_content() -> str: + # [START googlegenaisdk_interactions_textgen_with_txt_img] + from google import genai + from google.genai.interactions import ImageContent, TextContent + + client = genai.Client() + interaction = client.interactions.create( + model="gemini-3.8-flash", + input=[ + TextContent(text="What is shown in this image?"), + ImageContent( + uri="gs://cloud-samples-data/generative-ai/image/scones.jpg", + mime_type="image/jpeg", + ), + ], + ) + print(interaction.output_text) + # Example response: + # The image shows a flat lay of blueberry scones arranged on parchment paper. There are ... + # [END googlegenaisdk_interactions_textgen_with_txt_img] + return interaction.output_text + + +if __name__ == "__main__": + generate_content() diff --git a/genai/text_generation/textgen_interactions_with_txt_stream.py b/genai/text_generation/textgen_interactions_with_txt_stream.py new file mode 100644 index 00000000000..099cb9c2f56 --- /dev/null +++ b/genai/text_generation/textgen_interactions_with_txt_stream.py @@ -0,0 +1,44 @@ +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# https://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + + +def generate_content() -> bool: + # [START googlegenaisdk_interactions_textgen_with_txt_stream] + from google import genai + + client = genai.Client() + + stream = client.interactions.create( + model="gemini-3.8-flash", + input="Why is the sky blue?", + stream=True, + ) + + for event in stream: + if event.event_type == "step.delta" and event.delta: + if getattr(event.delta, "type", None) == "text" and getattr( + event.delta, "text", None + ): + print(event.delta.text, end="", flush=True) + # Example response: + # The + # sky appears blue due to a phenomenon called **Rayleigh scattering**. Here's + # a breakdown of why: + # ... + # [END googlegenaisdk_interactions_textgen_with_txt_stream] + return True + + +if __name__ == "__main__": + generate_content() diff --git a/genai/text_generation/textgen_interactions_with_video.py b/genai/text_generation/textgen_interactions_with_video.py new file mode 100644 index 00000000000..7a69e6d2edd --- /dev/null +++ b/genai/text_generation/textgen_interactions_with_video.py @@ -0,0 +1,55 @@ +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# https://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + + +def generate_content() -> str: + # [START googlegenaisdk_interactions_textgen_with_video] + from google import genai + from google.genai.interactions import TextContent, VideoContent + + client = genai.Client() + prompt = """ + Analyze the provided video file, including its audio. + Summarize the main points of the video concisely. + Create a chapter breakdown with timestamps for key sections or topics discussed. + """ + interaction = client.interactions.create( + model="gemini-3.8-flash", + input=[ + VideoContent( + uri="gs://cloud-samples-data/generative-ai/video/pixel8.mp4", + mime_type="video/mp4", + ), + TextContent(text=prompt), + ], + ) + + print(interaction.output_text) + # Example response: + # Here's a breakdown of the video: + # + # **Summary:** + # + # Saeka Shimada, a photographer in Tokyo, uses the Google Pixel 8 Pro's "Video Boost" feature to ... + # + # **Chapter Breakdown with Timestamps:** + # + # * **[00:00-00:12] Introduction & Tokyo at Night:** Saeka Shimada introduces herself ... + # ... + # [END googlegenaisdk_interactions_textgen_with_video] + return interaction.output_text + + +if __name__ == "__main__": + generate_content() diff --git a/genai/text_generation/textgen_interactions_with_youtube_video.py b/genai/text_generation/textgen_interactions_with_youtube_video.py new file mode 100644 index 00000000000..2c761948f76 --- /dev/null +++ b/genai/text_generation/textgen_interactions_with_youtube_video.py @@ -0,0 +1,47 @@ +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# https://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + + +def generate_content() -> str: + # [START googlegenaisdk_interactions_textgen_with_youtube_video] + from google import genai + from google.genai.interactions import TextContent, VideoContent + + client = genai.Client() + model_id = "gemini-3.8-flash" + + interaction = client.interactions.create( + model=model_id, + input=[ + VideoContent( + uri="https://www.youtube.com/watch?v=3KtWfp0UopM", + mime_type="video/mp4", + ), + TextContent(text="Write a short and engaging blog post based on this video."), + ], + ) + + print(interaction.output_text) + # Example response: + # Here's a short blog post based on the video provided: + # + # **Google Turns 25: A Quarter Century of Search!** + # ... + + # [END googlegenaisdk_interactions_textgen_with_youtube_video] + return interaction.output_text + + +if __name__ == "__main__": + generate_content() diff --git a/genai/text_generation/thinking_textgen_interactions_with_txt.py b/genai/text_generation/thinking_textgen_interactions_with_txt.py new file mode 100644 index 00000000000..e1b7aafaa91 --- /dev/null +++ b/genai/text_generation/thinking_textgen_interactions_with_txt.py @@ -0,0 +1,77 @@ +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# https://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + + +def generate_content() -> str: + # [START googlegenaisdk_interactions_thinking_textgen_with_txt] + from google import genai + + client = genai.Client() + interaction = client.interactions.create( + model="gemini-3.1-pro-preview", + input="solve x^2 + 4x + 4 = 0", + ) + print(interaction.output_text) + # Example Response: + # Okay, let's solve the quadratic equation x² + 4x + 4 = 0. + # + # We can solve this equation by factoring, using the quadratic formula, or by recognizing it as a perfect square trinomial. + # + # **Method 1: Factoring** + # + # 1. We need two numbers that multiply to the constant term (4) and add up to the coefficient of the x term (4). + # 2. The numbers 2 and 2 satisfy these conditions: 2 * 2 = 4 and 2 + 2 = 4. + # 3. So, we can factor the quadratic as: + # (x + 2)(x + 2) = 0 + # or + # (x + 2)² = 0 + # 4. For the product to be zero, the factor must be zero: + # x + 2 = 0 + # 5. Solve for x: + # x = -2 + # + # **Method 2: Quadratic Formula** + # + # The quadratic formula for an equation ax² + bx + c = 0 is: + # x = [-b ± sqrt(b² - 4ac)] / (2a) + # + # 1. In our equation x² + 4x + 4 = 0, we have a=1, b=4, and c=4. + # 2. Substitute these values into the formula: + # x = [-4 ± sqrt(4² - 4 * 1 * 4)] / (2 * 1) + # x = [-4 ± sqrt(16 - 16)] / 2 + # x = [-4 ± sqrt(0)] / 2 + # x = [-4 ± 0] / 2 + # x = -4 / 2 + # x = -2 + # + # **Method 3: Perfect Square Trinomial** + # + # 1. Notice that the expression x² + 4x + 4 fits the pattern of a perfect square trinomial: a² + 2ab + b², where a=x and b=2. + # 2. We can rewrite the equation as: + # (x + 2)² = 0 + # 3. Take the square root of both sides: + # x + 2 = 0 + # 4. Solve for x: + # x = -2 + # + # All methods lead to the same solution. + # + # **Answer:** + # The solution to the equation x² + 4x + 4 = 0 is x = -2. This is a repeated root (or a root with multiplicity 2). + # [END googlegenaisdk_interactions_thinking_textgen_with_txt] + return interaction.output_text + + +if __name__ == "__main__": + generate_content() diff --git a/genai/thinking/requirements.txt b/genai/thinking/requirements.txt index 1efe7b29dbc..ad433f48578 100644 --- a/genai/thinking/requirements.txt +++ b/genai/thinking/requirements.txt @@ -1 +1 @@ -google-genai==1.42.0 +google-genai==2.29.0 diff --git a/genai/thinking/test_thinking_examples.py b/genai/thinking/test_thinking_examples.py index 047141ace4e..623c8e27398 100644 --- a/genai/thinking/test_thinking_examples.py +++ b/genai/thinking/test_thinking_examples.py @@ -15,6 +15,9 @@ import thinking_budget_with_txt import thinking_includethoughts_with_txt +import thinking_interactions_budget_with_txt +import thinking_interactions_includethoughts_with_txt +import thinking_interactions_with_txt import thinking_with_txt os.environ["GOOGLE_GENAI_USE_ENTERPRISE"] = "True" @@ -33,3 +36,16 @@ def test_thinking_includethoughts_with_txt() -> None: def test_thinking_with_txt() -> None: assert thinking_with_txt.generate_content() + + +def test_thinking_interactions_budget_with_txt() -> None: + assert thinking_interactions_budget_with_txt.generate_content() + + +def test_thinking_interactions_includethoughts_with_txt() -> None: + assert thinking_interactions_includethoughts_with_txt.generate_content() + + +def test_thinking_interactions_with_txt() -> None: + assert thinking_interactions_with_txt.generate_content() + diff --git a/genai/thinking/thinking_interactions_budget_with_txt.py b/genai/thinking/thinking_interactions_budget_with_txt.py new file mode 100644 index 00000000000..0044b2cd258 --- /dev/null +++ b/genai/thinking/thinking_interactions_budget_with_txt.py @@ -0,0 +1,48 @@ +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# https://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + + +def generate_content() -> str: + # [START googlegenaisdk_interactions_thinking_budget_with_txt] + from google import genai + from google.genai.interactions import GenerationConfig + + client = genai.Client() + + # The Interactions API controls thinking depth via thinking_level ("minimal", "low", "medium", "high") + interaction = client.interactions.create( + model="gemini-3.8-flash", + input="solve x^2 + 4x + 4 = 0", + generation_config=GenerationConfig( + thinking_level="medium", + ), + ) + + print(interaction.output_text) + + # Thinking thoughts token count from usage + if interaction.usage and interaction.usage.modality_tokens: + for item in interaction.usage.modality_tokens: + if item.modality == "thought": + print(f"Thoughts tokens: {item.token_count}") + + if interaction.usage: + print(f"Total tokens: {interaction.usage.total_tokens}") + + # [END googlegenaisdk_interactions_thinking_budget_with_txt] + return interaction.output_text + + +if __name__ == "__main__": + generate_content() diff --git a/genai/thinking/thinking_interactions_includethoughts_with_txt.py b/genai/thinking/thinking_interactions_includethoughts_with_txt.py new file mode 100644 index 00000000000..be411a13d8a --- /dev/null +++ b/genai/thinking/thinking_interactions_includethoughts_with_txt.py @@ -0,0 +1,43 @@ +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# https://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + + +def generate_content() -> str: + # [START googlegenaisdk_interactions_thinking_includethoughts_with_txt] + from google import genai + from google.genai.interactions import GenerationConfig + + client = genai.Client() + interaction = client.interactions.create( + model="gemini-3.1-pro-preview", + input="solve x^2 + 4x + 4 = 0", + generation_config=GenerationConfig( + thinking_summaries="auto", + ), + ) + + print(interaction.output_text) + + # Inspect thoughts step in interaction + for step in interaction.steps: + if step.type == "thought": + print("Thought:") + print(step.summary) + + # [END googlegenaisdk_interactions_thinking_includethoughts_with_txt] + return interaction.output_text + + +if __name__ == "__main__": + generate_content() diff --git a/genai/thinking/thinking_interactions_with_txt.py b/genai/thinking/thinking_interactions_with_txt.py new file mode 100644 index 00000000000..1f33868ab03 --- /dev/null +++ b/genai/thinking/thinking_interactions_with_txt.py @@ -0,0 +1,31 @@ +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# https://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + + +def generate_content() -> str: + # [START googlegenaisdk_interactions_thinking_with_txt] + from google import genai + + client = genai.Client() + interaction = client.interactions.create( + model="gemini-3.1-pro-preview", + input="solve x^2 + 4x + 4 = 0", + ) + print(interaction.output_text) + # [END googlegenaisdk_interactions_thinking_with_txt] + return interaction.output_text + + +if __name__ == "__main__": + generate_content() diff --git a/genai/tools/test_tools_examples.py b/genai/tools/test_tools_examples.py index 95611393b00..94ad3beb1d9 100644 --- a/genai/tools/test_tools_examples.py +++ b/genai/tools/test_tools_examples.py @@ -28,6 +28,17 @@ import tools_google_maps_with_txt import tools_google_search_and_urlcontext_with_txt import tools_google_search_with_txt +import tools_interactions_code_exec_with_txt +import tools_interactions_code_exec_with_txt_local_img +import tools_interactions_enterprise_web_search_with_txt +import tools_interactions_func_def_with_txt +import tools_interactions_func_desc_with_txt +import tools_interactions_google_maps_coordinates_with_txt +import tools_interactions_google_maps_with_txt +import tools_interactions_google_search_and_urlcontext_with_txt +import tools_interactions_google_search_with_txt +import tools_interactions_urlcontext_with_txt +import tools_interactions_vais_with_txt import tools_urlcontext_with_txt import tools_vais_with_txt @@ -84,3 +95,53 @@ def test_tools_urlcontext_with_txt() -> None: def test_tools_google_search_and_urlcontext_with_txt() -> None: assert tools_google_search_and_urlcontext_with_txt.generate_content() + + +def test_tools_interactions_code_exec_with_txt() -> None: + assert tools_interactions_code_exec_with_txt.generate_content() + + +def test_tools_interactions_code_exec_with_txt_local_img() -> None: + assert tools_interactions_code_exec_with_txt_local_img.generate_content() + + +def test_tools_interactions_enterprise_web_search_with_txt() -> None: + assert tools_interactions_enterprise_web_search_with_txt.generate_content() + + +def test_tools_interactions_func_def_with_txt() -> None: + assert tools_interactions_func_def_with_txt.generate_content() + + +def test_tools_interactions_func_desc_with_txt() -> None: + assert tools_interactions_func_desc_with_txt.generate_content() + + +@pytest.mark.skip( + reason="Google Maps Grounding allowlisting is not set up for the test project." +) +def test_tools_interactions_google_maps_with_txt() -> None: + assert tools_interactions_google_maps_with_txt.generate_content() + + +def test_tools_interactions_google_search_with_txt() -> None: + assert tools_interactions_google_search_with_txt.generate_content() + + +def test_tools_interactions_vais_with_txt() -> None: + PROJECT_ID = os.environ.get("GOOGLE_CLOUD_PROJECT") + datastore = f"projects/{PROJECT_ID}/locations/global/collections/default_collection/dataStores/grounding-test-datastore" + assert tools_interactions_vais_with_txt.generate_content(datastore) + + +def test_tools_interactions_google_maps_coordinates_with_txt() -> None: + assert tools_interactions_google_maps_coordinates_with_txt.generate_content() + + +def test_tools_interactions_urlcontext_with_txt() -> None: + assert tools_interactions_urlcontext_with_txt.generate_content() + + +def test_tools_interactions_google_search_and_urlcontext_with_txt() -> None: + assert tools_interactions_google_search_and_urlcontext_with_txt.generate_content() + diff --git a/genai/tools/tools_interactions_code_exec_with_txt.py b/genai/tools/tools_interactions_code_exec_with_txt.py new file mode 100644 index 00000000000..7b2ff70851f --- /dev/null +++ b/genai/tools/tools_interactions_code_exec_with_txt.py @@ -0,0 +1,48 @@ +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# https://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + + +def generate_content() -> str: + # [START googlegenaisdk_interactions_tools_code_exec_with_txt] + from google import genai + from google.genai.interactions import CodeExecution + + client = genai.Client() + model_id = "gemini-3.8-flash" + + interaction = client.interactions.create( + model=model_id, + input="Calculate 20th fibonacci number. Then find the nearest palindrome to it.", + tools=[CodeExecution()], + ) + + executable_code = None + execution_result = None + for step in interaction.steps: + if step.type == "code_execution_call": + executable_code = step.arguments.code + print("# Code:") + print(executable_code) + elif step.type == "code_execution_result": + execution_result = step.result + print("# Outcome:") + print(execution_result) + + print(interaction.output_text) + # [END googlegenaisdk_interactions_tools_code_exec_with_txt] + return executable_code + + +if __name__ == "__main__": + generate_content() diff --git a/genai/tools/tools_interactions_code_exec_with_txt_local_img.py b/genai/tools/tools_interactions_code_exec_with_txt_local_img.py new file mode 100644 index 00000000000..b093e6d2661 --- /dev/null +++ b/genai/tools/tools_interactions_code_exec_with_txt_local_img.py @@ -0,0 +1,64 @@ +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# https://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +from typing import Any + + +def generate_content() -> Any: + # [START googlegenaisdk_interactions_tools_code_exec_with_txt_local_img] + import base64 + from google import genai + from google.genai.interactions import CodeExecution, ImageContent, TextContent + + client = genai.Client() + + prompt = """ + Run a simulation of the Monty Hall Problem with 1,000 trials. + Here's how this works as a reminder. In the Monty Hall Problem, you're on a game + show with three doors. Behind one is a car, and behind the others are goats. You + pick a door. The host, who knows what's behind the doors, opens a different door + to reveal a goat. Should you switch to the remaining unopened door? + The answer has always been a little difficult for me to understand when people + solve it with math - so please run a simulation with Python to show me what the + best strategy is. + Thank you! + """ + + with open("test_data/640px-Monty_open_door.svg.png", "rb") as image_file: + b64_image = base64.b64encode(image_file.read()).decode("utf-8") + + interaction = client.interactions.create( + model="gemini-3.8-flash", + input=[ + ImageContent(data=b64_image, mime_type="image/png"), + TextContent(text=prompt), + ], + tools=[CodeExecution()], + ) + + for step in interaction.steps: + if step.type == "code_execution_call": + print("# Code:") + print(step.arguments.code) + elif step.type == "code_execution_result": + print("# Outcome:") + print(step.result) + + print(interaction.output_text) + # [END googlegenaisdk_interactions_tools_code_exec_with_txt_local_img] + return interaction + + +if __name__ == "__main__": + generate_content() diff --git a/genai/tools/tools_interactions_enterprise_web_search_with_txt.py b/genai/tools/tools_interactions_enterprise_web_search_with_txt.py new file mode 100644 index 00000000000..e8d2e8da6bf --- /dev/null +++ b/genai/tools/tools_interactions_enterprise_web_search_with_txt.py @@ -0,0 +1,35 @@ +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# https://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + + +def generate_content() -> str: + # [START googlegenaisdk_interactions_tools_enterprise_web_search_with_txt] + from google import genai + from google.genai.interactions import GoogleSearch + + client = genai.Client() + + interaction = client.interactions.create( + model="gemini-3.8-flash", + input="When is the next total solar eclipse in the United States?", + tools=[GoogleSearch(search_types=["enterprise_web_search"])], + ) + + print(interaction.output_text) + # [END googlegenaisdk_interactions_tools_enterprise_web_search_with_txt] + return interaction.output_text + + +if __name__ == "__main__": + generate_content() diff --git a/genai/tools/tools_interactions_func_def_with_txt.py b/genai/tools/tools_interactions_func_def_with_txt.py new file mode 100644 index 00000000000..740e35c998e --- /dev/null +++ b/genai/tools/tools_interactions_func_def_with_txt.py @@ -0,0 +1,88 @@ +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# https://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + + +def generate_content() -> str: + # [START googlegenaisdk_interactions_tools_func_def_with_txt] + from google import genai + from google.genai.interactions import Function + + def get_current_weather(location: str) -> str: + """Example method. Returns the current weather. + + Args: + location: The city and state, e.g. San Francisco, CA + """ + weather_map: dict[str, str] = { + "Boston, MA": "snowing", + "San Francisco, CA": "foggy", + "Seattle, WA": "raining", + "Austin, TX": "hot", + "Chicago, IL": "windy", + } + return weather_map.get(location, "unknown") + + client = genai.Client() + model_id = "gemini-3.8-flash" + + # Define function tool declaration for the Interactions API + weather_tool = Function( + name="get_current_weather", + description="Returns the current weather for a given city and state.", + parameters={ + "type": "object", + "properties": { + "location": { + "type": "string", + "description": "The city and state, e.g. San Francisco, CA", + } + }, + "required": ["location"], + }, + ) + + interaction = client.interactions.create( + model=model_id, + input="What is the weather like in Boston?", + tools=[weather_tool], + ) + + # Check for function call step and execute it if requested + for step in interaction.steps: + if step.type == "function_call" and step.name == "get_current_weather": + args = step.arguments or {} + result = get_current_weather(**args) + + # Return function execution result back in a follow-up interaction + interaction = client.interactions.create( + model=model_id, + previous_interaction_id=interaction.id, + input=[ + { + "type": "function_result", + "call_id": step.id, + "name": step.name, + "result": [{"type": "text", "text": result}], + } + ], + ) + break + + print(interaction.output_text) + # [END googlegenaisdk_interactions_tools_func_def_with_txt] + return interaction.output_text + + +if __name__ == "__main__": + generate_content() diff --git a/genai/tools/tools_interactions_func_desc_with_txt.py b/genai/tools/tools_interactions_func_desc_with_txt.py new file mode 100644 index 00000000000..7dcd9ce2a80 --- /dev/null +++ b/genai/tools/tools_interactions_func_desc_with_txt.py @@ -0,0 +1,77 @@ +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# https://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + + +def generate_content() -> str: + # [START googlegenaisdk_interactions_tools_func_desc_with_txt] + from google import genai + from google.genai.interactions import Function + + client = genai.Client() + model_id = "gemini-3.8-flash" + + get_album_sales_tool = Function( + name="get_album_sales", + description="Gets the number of albums sold", + parameters={ + "type": "object", + "properties": { + "albums": { + "type": "array", + "description": "List of albums", + "items": { + "description": "Album and its sales", + "type": "object", + "properties": { + "album_name": { + "type": "string", + "description": "Name of the music album", + }, + "copies_sold": { + "type": "integer", + "description": "Number of copies sold", + }, + }, + }, + }, + }, + }, + ) + + interaction = client.interactions.create( + model=model_id, + input=( + 'At Stellar Sounds, a music label, 2024 was a rollercoaster. "Echoes of the Night," a debut synth-pop album, ' + 'surprisingly sold 350,000 copies, while veteran rock band "Crimson Tide\'s" latest, "Reckless Hearts," ' + 'lagged at 120,000. Their up-and-coming indie artist, "Luna Bloom\'s" EP, "Whispers of Dawn," ' + 'secured 75,000 sales. The biggest disappointment was the highly-anticipated rap album "Street Symphony" ' + "only reaching 100,000 units. Overall, Stellar Sounds moved over 645,000 units this year, revealing unexpected " + "trends in music consumption." + ), + tools=[get_album_sales_tool], + ) + + function_calls = [ + {"name": step.name, "arguments": step.arguments} + for step in interaction.steps + if step.type == "function_call" + ] + + print(function_calls) + # [END googlegenaisdk_interactions_tools_func_desc_with_txt] + return str(function_calls) + + +if __name__ == "__main__": + generate_content() diff --git a/genai/tools/tools_interactions_google_maps_coordinates_with_txt.py b/genai/tools/tools_interactions_google_maps_coordinates_with_txt.py new file mode 100644 index 00000000000..4853c951e9d --- /dev/null +++ b/genai/tools/tools_interactions_google_maps_coordinates_with_txt.py @@ -0,0 +1,35 @@ +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# https://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + + +def generate_content() -> str: + # [START googlegenaisdk_interactions_tools_google_maps_coordinates_with_txt] + from google import genai + from google.genai.interactions import GoogleMaps + + client = genai.Client() + + interaction = client.interactions.create( + model="gemini-3.8-flash", + input="Where can I get the best espresso near me?", + tools=[GoogleMaps(latitude=40.7128, longitude=-74.006)], + ) + + print(interaction.output_text) + # [END googlegenaisdk_interactions_tools_google_maps_coordinates_with_txt] + return interaction.output_text + + +if __name__ == "__main__": + generate_content() diff --git a/genai/tools/tools_interactions_google_maps_with_txt.py b/genai/tools/tools_interactions_google_maps_with_txt.py new file mode 100644 index 00000000000..885565ebdbd --- /dev/null +++ b/genai/tools/tools_interactions_google_maps_with_txt.py @@ -0,0 +1,35 @@ +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# https://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + + +def generate_content() -> str: + # [START googlegenaisdk_interactions_tools_google_maps_with_txt] + from google import genai + from google.genai.interactions import GoogleMaps + + client = genai.Client() + + interaction = client.interactions.create( + model="gemini-3.8-flash", + input="Recommend a good restaurant in San Francisco.", + tools=[GoogleMaps()], + ) + + print(interaction.output_text) + # [END googlegenaisdk_interactions_tools_google_maps_with_txt] + return interaction.output_text + + +if __name__ == "__main__": + generate_content() diff --git a/genai/tools/tools_interactions_google_search_and_urlcontext_with_txt.py b/genai/tools/tools_interactions_google_search_and_urlcontext_with_txt.py new file mode 100644 index 00000000000..3938c7c98e8 --- /dev/null +++ b/genai/tools/tools_interactions_google_search_and_urlcontext_with_txt.py @@ -0,0 +1,50 @@ +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# https://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + + +def generate_content() -> str: + # [START googlegenaisdk_interactions_tools_google_search_and_urlcontext_with_txt] + from google import genai + from google.genai.interactions import GoogleSearch, URLContext + + client = genai.Client() + model_id = "gemini-3.8-flash" + + tools = [ + URLContext(), + GoogleSearch(), + ] + + # TODO(developer): Here put your URLs! + url = "https://www.google.com/search?q=events+in+New+York" + + interaction = client.interactions.create( + model=model_id, + input=f"Give me three day events schedule based on {url}. Also let me know what needs to taken care of considering weather and commute.", + tools=tools, + ) + + print(interaction.output_text) + + # Inspect URL context results from interaction steps + for step in interaction.steps: + if step.type == "url_context_result": + print(step.result) + + # [END googlegenaisdk_interactions_tools_google_search_and_urlcontext_with_txt] + return interaction.output_text + + +if __name__ == "__main__": + generate_content() diff --git a/genai/tools/tools_interactions_google_search_with_txt.py b/genai/tools/tools_interactions_google_search_with_txt.py new file mode 100644 index 00000000000..ae4e37e0ac4 --- /dev/null +++ b/genai/tools/tools_interactions_google_search_with_txt.py @@ -0,0 +1,35 @@ +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# https://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + + +def generate_content() -> str: + # [START googlegenaisdk_interactions_tools_google_search_with_txt] + from google import genai + from google.genai.interactions import GoogleSearch + + client = genai.Client() + + interaction = client.interactions.create( + model="gemini-3.8-flash", + input="When is the next total solar eclipse in the United States?", + tools=[GoogleSearch()], + ) + + print(interaction.output_text) + # [END googlegenaisdk_interactions_tools_google_search_with_txt] + return interaction.output_text + + +if __name__ == "__main__": + generate_content() diff --git a/genai/tools/tools_interactions_urlcontext_with_txt.py b/genai/tools/tools_interactions_urlcontext_with_txt.py new file mode 100644 index 00000000000..ed22befd022 --- /dev/null +++ b/genai/tools/tools_interactions_urlcontext_with_txt.py @@ -0,0 +1,46 @@ +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# https://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + + +def generate_content() -> str: + # [START googlegenaisdk_interactions_tools_urlcontext_with_txt] + from google import genai + from google.genai.interactions import URLContext + + client = genai.Client() + model_id = "gemini-3.8-flash" + + # TODO(developer): Here put your URLs + url1 = "https://cloud.google.com/vertex-ai/docs/generative-ai/start" + url2 = "https://cloud.google.com/docs/overview" + + interaction = client.interactions.create( + model=model_id, + input=f"Compare the content, purpose, and audiences of {url1} and {url2}.", + tools=[URLContext()], + ) + + print(interaction.output_text) + + # Inspect URL context metadata from interaction steps + for step in interaction.steps: + if step.type == "url_context_result": + print(step.result) + + # [END googlegenaisdk_interactions_tools_urlcontext_with_txt] + return interaction.output_text + + +if __name__ == "__main__": + generate_content() diff --git a/genai/tools/tools_interactions_vais_with_txt.py b/genai/tools/tools_interactions_vais_with_txt.py new file mode 100644 index 00000000000..2b3e3fdb180 --- /dev/null +++ b/genai/tools/tools_interactions_vais_with_txt.py @@ -0,0 +1,45 @@ +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# https://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + + +def generate_content(datastore: str) -> bool: + # [START googlegenaisdk_interactions_tools_vais_with_txt] + from google import genai + from google.genai.interactions import Retrieval, VertexAISearchConfig + + client = genai.Client() + + # Load Data Store ID from Vertex AI Search + # datastore = "projects/111111111111/locations/global/collections/default_collection/dataStores/data-store-id" + + interaction = client.interactions.create( + model="gemini-3.8-flash", + input="How do I make an appointment to renew my driver's license?", + tools=[ + Retrieval( + vertex_ai_search_config=VertexAISearchConfig( + datastores=[datastore], + ) + ) + ], + ) + + print(interaction.output_text) + # [END googlegenaisdk_interactions_tools_vais_with_txt] + return True + + +if __name__ == "__main__": + datastore = input("Data Store ID: ") + generate_content(datastore)