From 362e0010dd2ebc67de4fee2278301e6d19702912 Mon Sep 17 00:00:00 2001 From: Surya Date: Tue, 21 Jan 2025 20:54:17 +0530 Subject: [PATCH 01/17] Refactor embedding model name in call (#645) --- google/generativeai/types/model_types.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/google/generativeai/types/model_types.py b/google/generativeai/types/model_types.py index ff66d6339..631e44d33 100644 --- a/google/generativeai/types/model_types.py +++ b/google/generativeai/types/model_types.py @@ -355,7 +355,10 @@ def make_model_name(name: AnyModelNameOptions): if isinstance(name, (Model, protos.Model, TunedModel, protos.TunedModel)): name = name.name # pytype: disable=attribute-error elif isinstance(name, str): - name = name + if "/" not in name: + name = "models/" + name + else: + name = name else: raise TypeError( "Invalid input type. Expected one of the following types: `str`, `Model`, or `TunedModel`." From d415d1a8093aa0cb1e8326303928d55f17e48b67 Mon Sep 17 00:00:00 2001 From: Mark Daoust Date: Thu, 6 Feb 2025 10:54:04 -0800 Subject: [PATCH 02/17] Add the migration guide. (#672) * Add migration guide to the readme. Change-Id: I6834a1ac98f208ffad9fdedba392c25109a3d023 * add links Change-Id: I992b94277878190aed5270adbb2b65d0f73423e6 * Fixing the colab button which was displayed on the same line as the next title --------- Co-authored-by: Guillaume Vernade --- README.md | 928 +++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 913 insertions(+), 15 deletions(-) diff --git a/README.md b/README.md index f05edb77b..46b3afc4a 100644 --- a/README.md +++ b/README.md @@ -14,38 +14,936 @@ The Google AI Python SDK is the easiest way for Python developers to build with 5. For detailed instructions, try the [Python SDK tutorial](https://ai.google.dev/tutorials/python_quickstart) on [ai.google.dev](https://ai.google.dev). -## Usage example -See the [Gemini API Cookbook](https://github.com/google-gemini/gemini-api-cookbook/) or [ai.google.dev](https://ai.google.dev) for complete code. +## Upgrade to the new Google Gen AI SDK for Python -1. Install from [PyPI](https://pypi.org/project/google-generativeai). +Until now, the `google-generativeai` SDK package has been the recommended tool +for accessing the Gemini API from Python. While this package gets the job done, +the long incremental development process (starting from the PaLM API in 2023) +made it impossible to implement some important high level features without +significant breakages. -`pip install -U google-generativeai` +The new SDK package, `google-genai` ([github](https://github.com/googleapis/python-genai), +[pypi](https://pypi.org/project/google-genai/)), is a from-scratch rewrite designed to +resolve these problems. Among other things, the new package: -2. Import the SDK and configure your API key. +* Is clear about when clients are created, configured, and used (clear + separation between data objects, and the API client). +* Lets you swap between API versions, or use Vertex AI's implementation of + the Gemini API. +* Follows consistent patterns across methods and language implementations. +* Follows the API layout closely; paths and data structures mostly match + between the SDK and the REST interface. + +From Gemini 2.0 onwards the old SDK, `google-generativeai`, will no longer be +developing new features. The old SDK can run a subset of Gemini-2.0 model +features. Any new new code should be written using the new SDK, `google-genai`. + + + +
+ + + Try the new SDK in Google Colab + +
+

+ +### Install the SDK + +**Before** + +``` +pip install -U -q "google-generativeai" +``` + +**After** + +``` +pip install -U -q "google-genai" +``` + +### Authenticate + +Authenticate with API key. You can +[create](https://aistudio.google.com/app/apikey) +your API key using Google AI studio. + + +The old SDK implicitly handled the API client object behind the scenes. In the +new SDK you create the API client and use it to call the API. + +Remember, in either case the SDK will pick +up your API key from the `GOOGLE_API_KEY` environment variable if you don't pass +one to `configure`/`Client`. + +
export GOOGLE_API_KEY=...
+ +**Before** + +```python +import google.generativeai as genai + +genai.configure(api_key=...) +``` + +**After** + +```python +from google import genai + +client = genai.Client(api_key=...) +``` + +### Generate content + +The new SDK provides access to all the API methods through the `Client` object. +Except for a few stateful special cases (`chat`, live-api `session`s) these are all +stateless functions. For utility and uniformity objects returned are `pydantic` +classes. + +**Before** ```python import google.generativeai as genai -import os -genai.configure(api_key=os.environ["GEMINI_API_KEY"]) +model = genai.GenerativeModel('gemini-1.5-flash') +response = model.generate_content( + 'Tell me a story in 300 words' +) +print(response.text) +``` + +**After** + +```python +from google import genai +client = genai.Client() + +response = client.models.generate_content( + model='gemini-1.5-flash', + contents='Tell me a story in 300 words.' +) +print(response.text) + +print(response.model_dump_json( + exclude_none=True, indent=4)) ``` -3. Create a model and run a prompt. + +Many of the same convenience features exist in the new SDK. For example +`PIL.Image` objects are automatically converted: + +**Before** ```python +import google.generativeai as genai + model = genai.GenerativeModel('gemini-1.5-flash') -response = model.generate_content("The opposite of hot is") +response = model.generate_content([ + 'Tell me a story based on this image', + Image.open(image_path) +]) print(response.text) ``` -## Documentation +**After** + +```python +from google import genai +from PIL import Image + +client = genai.Client() + +response = client.models.generate_content( + model='gemini-1.5-flash', + contents=[ + 'Tell me a story based on this image', + Image.open(image_path) + ] +) +print(response.text) +``` + + +#### Streaming + +Streaming methods are each separate functions named with a `_stream` suffix. + +**Before** + +```python +import google.generativeai as genai + +response = model.generate_content( + "Write a cute story about cats.", + stream=True) +for chunk in response: + print(chunk.text) +``` + +**After** + +```python +from google import genai +client = genai.Client() + +for chunk in client.models.generate_content_stream( + model='gemini-1.5-flash', + contents='Tell me a story in 300 words.' +): + print(chunk.text) +``` + + +### Optional arguments + +For all methods in the new SDK the required arguments are provided as keyword +arguments. All optional inputs are provided in the `config` argument. + +The `config` can always be passed as a dictionary or, for better autocomplete and +stricter typing, each method has a `Config` class in the `google.genai.types` +module. For utility and uniformity, everything in the `types` module is defined +as a `pydantic` class. + +**Before** + +```python +import google.generativeai as genai + +model = genai.GenerativeModel( + 'gemini-1.5-flash', + system_instruction='you are a story teller for kids under 5 years old', + generation_config=genai.GenerationConfig( + max_output_tokens=400, + top_k=2, + top_p=0.5, + temperature=0.5, + response_mime_type='application/json', + stop_sequences=['\n'], + ) +) +response = model.generate_content('tell me a story in 100 words') + +``` + +**After** + +```python +from google import genai +from google.genai import types +client = genai.Client() + +response = client.models.generate_content( + model='gemini-1.5-flash', + contents='Tell me a story in 100 words.', + config=types.GenerateContentConfig( + system_instruction='you are a story teller for kids under 5 years old', + max_output_tokens= 400, + top_k= 2, + top_p= 0.5, + temperature= 0.5, + response_mime_type= 'application/json', + stop_sequences= ['\n'], + seed=42, + ), +) +``` + + +#### Example: Safety settings + +Generate response with safety settings: + +**Before** + +```python +import google.generativeai as genai + +model = genai.GenerativeModel('gemini-1.5-pro-002') +response = model.generate_content( + 'say something bad', + safety_settings={ + 'HATE': 'BLOCK_ONLY_HIGH', + 'HARASSMENT': 'BLOCK_ONLY_HIGH', + } +) +``` + +**After** + +```python +from google import genai +from google.genai import types +client = genai.Client() + +response = client.models.generate_content( + model='gemini-1.5-pro-002', + contents='say something bad', + config=types.GenerateContentConfig( + safety_settings= [ + types.SafetySetting( + category='HARM_CATEGORY_HATE_SPEECH', + threshold='BLOCK_ONLY_HIGH' + ), + ] + ), +) +``` + + +### Async + +To use the new SDK with `asyncio`, there is a separate `async` implementation of +every method under `client.aio`. + +**Before** + +```python +import google.generativeai as genai + +model = genai.GenerativeModel('gemini-1.5-flash') +response = model.generate_content_async( + 'tell me a story in 100 words' +) +``` + +**After** + +```python +from google import genai +client = genai.Client() + +response = await client.aio.models.generate_content( + model='gemini-1.5-flash', + contents='Tell me a story in 300 words.' +) +``` + +### Chat + +Starts a chat and sends a message to the model: + +**Before** + +```python +import google.generativeai as genai + +model = genai.GenerativeModel('gemini-1.5-flash') +chat = model.start_chat() + +response = chat.send_message( + "Tell me a story in 100 words") +response = chat.send_message( + "What happened after that?") +``` + +**After** + +```python +from google import genai +client = genai.Client() + +chat = client.chats.create(model='gemini-1.5-flash') + +response = chat.send_message( + message='Tell me a story in 100 words') +response = chat.send_message( + message='What happened after that?') +``` + -See the [Gemini API Cookbook](https://github.com/google-gemini/gemini-api-cookbook/) or [ai.google.dev](https://ai.google.dev) for complete documentation. +### Function calling -## Contributing +In the New SDK, automatic function calling is the default. Here we disable it. -See [Contributing](https://github.com/google/generative-ai-python/blob/main/CONTRIBUTING.md) for more information on contributing to the Google AI Python SDK. +**Before** -## License +```python +import google.generativeai as genai +from enum import Enum + +def get_current_weather(location: str) -> str: + """Get the current whether in a given location. + + Args: + location: required, The city and state, e.g. San Franciso, CA + unit: celsius or fahrenheit + """ + print(f'Called with: {location=}') + return "23C" + +model = genai.GenerativeModel( + model_name="gemini-1.5-pro-002", + tools=[get_current_weather] +) + +response = model.generate_content("What is the weather in San Francisco?") +function_call = response.candidates[0].parts[0].function_call +``` + +**After** + +```python +from google import genai +from google.genai import types +client = genai.Client() + +def get_current_weather(location: str) -> str: + """Get the current whether in a given location. + + Args: + location: required, The city and state, e.g. San Franciso, CA + unit: celsius or fahrenheit + """ + print(f'Called with: {location=}') + return "23C" + +response = client.models.generate_content( + model='gemini-1.5-pro-002', + contents="What is the weather like in Boston?", + config=types.GenerateContentConfig( + tools=[get_current_weather], + automatic_function_calling={'disable': True}, + ), +) + +function_call = response.candidates[0].content.parts[0].function_call +``` + +#### Automatic function calling + +The old SDK only supports automatic function calling in chat. In the new SDK +this is the default behavior in `generate_content`. + +**Before** + +```python +import google.generativeai as genai -The contents of this repository are licensed under the [Apache License, version 2.0](http://www.apache.org/licenses/LICENSE-2.0). +def get_current_weather(city: str) -> str: + return "23C" + +model = genai.GenerativeModel( + model_name="gemini-1.5-pro-002", + tools=[get_current_weather] +) + +chat = model.start_chat( + enable_automatic_function_calling=True) +result = chat.send_message("What is the weather in San Francisco?") +``` + +**After** + +```python +from google import genai +from google.genai import types +client = genai.Client() + +def get_current_weather(city: str) -> str: + return "23C" + +response = client.models.generate_content( + model='gemini-1.5-pro-002', + contents="What is the weather like in Boston?", + config=types.GenerateContentConfig( + tools=[get_current_weather] + ), +) +``` + +### Code execution + +Code execution is a tool that allows the model to generate Python code, run it, +and return the result. + +**Before** + +```python +import google.generativeai as genai + +model = genai.GenerativeModel( + model_name="gemini-1.5-flash", + tools="code_execution" +) + +result = model.generate_content( + "What is the sum of the first 50 prime numbers? Generate and run code for " + "the calculation, and make sure you get all 50.") +``` + +**After** + +```python +from google import genai +from google.genai import types +client = genai.Client() + +response = client.models.generate_content( + model='gemini-1.5-flash', + contents='What is the sum of the first 50 prime numbers? Generate and run ' + 'code for the calculation, and make sure you get all 50.', + config=types.GenerateContentConfig( + tools=[types.Tool(code_execution=types.CodeExecution())], + ), +) +``` + +### Search grounding + +`GoogleSearch` (Gemini>=2.0) and `GoogleSearchRetrieval` (Gemini < 2.0) are tools +that allow the model to retrieve public web data for grounding, powered by Google. + +**Before** + +```python +import google.generativeai as genai + +model = genai.GenerativeModel('gemini-1.5-flash') +response = model.generate_content( + contents="what is the Google stock price?", + tools='google_search_retrieval' +) +``` + +**After** + +```python +from google import genai +from google.genai import types +client = genai.Client() + +response = client.models.generate_content( + model='gemini-2.0-flash-exp', + contents='What is the Google stock price?', + config=types.GenerateContentConfig( + tools=[ + types.Tool( + google_search=types.GoogleSearch() + ) + ] + ) +) +``` + +### JSON response + +Generate answers in JSON format. + +By specifying a `response_schema` and setting +`response_mime_type="application/json"` users can constrain the model to produce a +`JSON` response following a given structure. The new SDK uses `pydantic` classes +to provide the schema (although you can pass a `genai.types.Schema`, or equivalent +`dict`). When possible, the SDK will parse the returned JSON, and return the +result in `response.parsed`. If you provided a `pydantic` class as the schema the +SDK will convert that `JSON` to an instance of the class. + +**Before** + +```python +import google.generativeai as genai +import typing_extensions as typing + +class CountryInfo(typing.TypedDict): + name: str + population: int + capital: str + continent: str + major_cities: list[str] + gdp: int + official_language: str + total_area_sq_mi: int + +model = genai.GenerativeModel(model_name="gemini-1.5-flash") +result = model.generate_content( + "Give me information of the United States", + generation_config=genai.GenerationConfig( + response_mime_type="application/json", + response_schema = CountryInfo + ), +) + +``` + +**After** + +```python +from google import genai +from pydantic import BaseModel +client = genai.Client() + +class CountryInfo(BaseModel): + name: str + population: int + capital: str + continent: str + major_cities: list[str] + gdp: int + official_language: str + total_area_sq_mi: int + +response = client.models.generate_content( + model='gemini-1.5-flash', + contents='Give me information of the United States.', + config={ + 'response_mime_type': 'application/json', + 'response_schema': CountryInfo, + }, + ) + +response.parsed +``` + +### Files + +#### Upload + +Upload a file: + +**Before** + +```python +import requests +import pathlib +import google.generativeai as genai + +# Download file +response = requests.get( + 'https://storage.googleapis.com/generativeai-downloads/data/a11.txt') +pathlib.Path('a11.txt').write_text(response.text) + +file = genai.upload_file(path='a11.txt') + +model = genai.GenerativeModel('gemini-1.5-flash') +response = model.generate_content([ + 'Can you summarize this file:', + my_file +]) +print(response.text) +``` + +**After** + +```python +import requests +import pathlib +from google import genai +client = genai.Client() + +# Download file +response = requests.get( + 'https://storage.googleapis.com/generativeai-downloads/data/a11.txt') +pathlib.Path('a11.txt').write_text(response.text) + +my_file = client.files.upload(file='a11.txt') + +response = client.models.generate_content( + model='gemini-1.5-flash', + contents=[ + 'Can you summarize this file:', + my_file + ] +) +print(response.text) +``` + +#### List and get + +List uploaded files and get an uploaded file with a file name: + +**Before** + +```python +import google.generativeai as genai + +for file in genai.list_files(): + print(file.name) + +file = genai.get_file(name=file.name) +``` + +**After** + +```python +from google import genai +client = genai.Client() + +for file in client.files.list(): + print(file.name) + +file = client.files.get(name=file.name) +``` + + +#### Delete + +Delete a file: + +**Before** + +```python +import pathlib +import google.generativeai as genai + +pathlib.Path('dummy.txt').write_text(dummy) +dummy_file = genai.upload_file(path='dummy.txt') + +file = genai.delete_file(name=dummy_file.name) +``` + +**After** + +```python +import pathlib +from google import genai +client = genai.Client() + +pathlib.Path('dummy.txt').write_text(dummy) +dummy_file = client.files.upload(file='dummy.txt') + +response = client.files.delete(name=dummy_file.name) +``` + + +### Context caching + +Context caching allows the user to pass the content to the model once, cache the +input tokens, and then refer to the cached tokens in subsequent calls to lower the +cost. + +**Before** + +```python +import requests +import pathlib +import google.generativeai as genai +from google.generativeai import caching + +# Download file +response = requests.get( + 'https://storage.googleapis.com/generativeai-downloads/data/a11.txt') +pathlib.Path('a11.txt').write_text(response.text) + + +# Upload file +document = genai.upload_file(path="a11.txt") + +# Create cache +apollo_cache = caching.CachedContent.create( + model="gemini-1.5-flash-001", + system_instruction="You are an expert at analyzing transcripts.", + contents=[document], +) + +# Generate response +apollo_model = genai.GenerativeModel.from_cached_content( + cached_content=apollo_cache +) +response = apollo_model.generate_content("Find a lighthearted moment from this transcript") +``` + +**After** + +```python +import requests +import pathlib +from google import genai +from google.genai import types +client = genai.Client() + +# Download file +response = requests.get( + 'https://storage.googleapis.com/generativeai-downloads/data/a11.txt') +pathlib.Path('a11.txt').write_text(response.text) + + +# Upload file +document = client.files.upload(file='a11.txt') + +# Create cache +model='gemini-1.5-flash-001' +apollo_cache = client.caches.create( + model=model, + config={ + 'contents': [document], + 'system_instruction': 'You are an expert at analyzing transcripts.', + }, + ) + +# Generate response +response = client.models.generate_content( + model=model, + contents='Find a lighthearted moment from this transcript', + config=types.GenerateContentConfig( + cached_content=apollo_cache.name, + ) +) +``` + +### Count tokens + +Count the number of tokens in a request. + +**Before** + +```python +import google.generativeai as genai + +model = genai.GenerativeModel('gemini-1.5-flash') +response = model.count_tokens( + 'The quick brown fox jumps over the lazy dog.') + +``` + +**After** + +```python +from google import genai +client = genai.Client() + +response = client.models.count_tokens( + model='gemini-1.5-flash', + contents='The quick brown fox jumps over the lazy dog.', +) +``` + +### Generate images + +Generate images: + +**Before** + +```python +#pip install https://github.com/google-gemini/generative-ai-python@imagen +import google.generativeai as genai + +imagen = genai.ImageGenerationModel( + "imagen-3.0-generate-001") +gen_images = imagen.generate_images( + prompt="Robot holding a red skateboard", + number_of_images=1, + safety_filter_level="block_only_high", + person_generation="allow_adult", + aspect_ratio="3:4", + negative_prompt="Outside", +) +``` + +**After** + +```python +from google import genai +client = genai.Client() + +gen_images = client.models.generate_image( + model='imagen-3.0-generate-001', + prompt='Robot holding a red skateboard', + config=types.GenerateImageConfig( + number_of_images= 1, + safety_filter_level= "BLOCK_ONLY_HIGH", + person_generation= "ALLOW_ADULT", + aspect_ratio= "3:4", + negative_prompt= "Outside", + ) +) + +for n, image in enumerate(gen_images.generated_images): + pathlib.Path(f'{n}.png').write_bytes( + image.image.image_bytes) +``` + + +### Embed content + +Generate content embeddings. + +**Before** + +```python +import google.generativeai as genai + +response = genai.embed_content( + model='models/text-embedding-004', + content='Hello world' +) +``` + +**After** + +```python +from google import genai +client = genai.Client() + +response = client.models.embed_content( + model='text-embedding-004', + contents='Hello world', +) +``` + +### Tune a Model + +Create and use a tuned model. + +The new SDK simplifies tuning with `client.tunings.tune`, which launches the +tuning job and polls until the job is complete. + +**Before** + +```python +import google.generativeai as genai +import random + +# create tuning model +train_data = {} +for i in range(1, 6): + key = f'input {i}' + value = f'output {i}' + train_data[key] = value + +name = f'generate-num-{random.randint(0,10000)}' +operation = genai.create_tuned_model( + source_model='gemini-1.0-pro-001', + training_data=train_data, + id = name, + epoch_count = 5, + batch_size=4, + learning_rate=0.001, +) +# wait for tuning complete +tuningProgress = operation.result() + +# generate content with the tuned model +model = genai.GenerativeModel(model_name=f'tunedModels/{name}') +response = model.generate_content('55') +``` + +**After** + +```python +# create tuning model +training_dataset=types.TuningDataset( + examples=[ + types.TuningExample( + text_input=f'input {i}', + output=f'output {i}', + ) + for i in range(5) + ], + ) +tuning_job = client.tunings.tune( + base_model='models/gemini-1.0-pro-001', + training_dataset=training_dataset, + config=types.CreateTuningJobConfig( + epoch_count= 5, + batch_size=4, + learning_rate=0.001, + tuned_model_display_name="test tuned model" + ) +) + +# generate content with the tuned model +response = client.models.generate_content( + model=tuning_job.tuned_model.model, + contents='55', +) +``` From 85b368049c5801170e1b588e3d7d6d99d73309b3 Mon Sep 17 00:00:00 2001 From: Mark Daoust Date: Fri, 7 Feb 2025 08:49:32 -0800 Subject: [PATCH 03/17] Update README.md (#675) * Update README.md * Update README.md --- README.md | 222 ++++++++++++++++++++++++++++-------------------------- 1 file changed, 115 insertions(+), 107 deletions(-) diff --git a/README.md b/README.md index 46b3afc4a..9d5033fbf 100644 --- a/README.md +++ b/README.md @@ -4,39 +4,28 @@ ![Python support](https://img.shields.io/pypi/pyversions/google-generativeai) ![PyPI - Downloads](https://img.shields.io/pypi/dd/google-generativeai) -The Google AI Python SDK is the easiest way for Python developers to build with the Gemini API. The Gemini API gives you access to Gemini [models](https://ai.google.dev/models/gemini) created by [Google DeepMind](https://deepmind.google/technologies/gemini/#introduction). Gemini models are built from the ground up to be multimodal, so you can reason seamlessly across text, images, and code. - -## Get started with the Gemini API -1. Go to [Google AI Studio](https://aistudio.google.com/). -2. Login with your Google account. -3. [Create](https://aistudio.google.com/app/apikey) an API key. -4. Try a Python SDK [quickstart](https://github.com/google-gemini/gemini-api-cookbook/blob/main/quickstarts/Prompting.ipynb) in the [Gemini API Cookbook](https://github.com/google-gemini/gemini-api-cookbook/). -5. For detailed instructions, try the -[Python SDK tutorial](https://ai.google.dev/tutorials/python_quickstart) on [ai.google.dev](https://ai.google.dev). - -## Upgrade to the new Google Gen AI SDK for Python - -Until now, the `google-generativeai` SDK package has been the recommended tool -for accessing the Gemini API from Python. While this package gets the job done, -the long incremental development process (starting from the PaLM API in 2023) -made it impossible to implement some important high level features without -significant breakages. - -The new SDK package, `google-genai` ([github](https://github.com/googleapis/python-genai), -[pypi](https://pypi.org/project/google-genai/)), is a from-scratch rewrite designed to -resolve these problems. Among other things, the new package: - -* Is clear about when clients are created, configured, and used (clear - separation between data objects, and the API client). -* Lets you swap between API versions, or use Vertex AI's implementation of - the Gemini API. -* Follows consistent patterns across methods and language implementations. -* Follows the API layout closely; paths and data structures mostly match - between the SDK and the REST interface. - -From Gemini 2.0 onwards the old SDK, `google-generativeai`, will no longer be -developing new features. The old SDK can run a subset of Gemini-2.0 model -features. Any new new code should be written using the new SDK, `google-genai`. +# Upgrade the Google GenAI SDK for Python + +With Gemini 2 we are offering a [new SDK](https://github.com/googleapis/python-genai) +([google-genai](https://pypi.org/project/google-genai/), +v1.0). The updated SDK is fully compatible with all Gemini API +models and features, including recent additions like the +[live API](https://aistudio.google.com/live) (audio + video streaming), +improved tool usage ( +[code execution](https://ai.google.dev/gemini-api/docs/code-execution?lang=python), +[function calling](https://ai.google.dev/gemini-api/docs/function-calling/tutorial?lang=python) and integrated +[Google search grounding](https://ai.google.dev/gemini-api/docs/grounding?lang=python)), +and media generation ([Imagen](https://ai.google.dev/gemini-api/docs/imagen)). +This SDK allows you to connect to the Gemini API through either +[Google AI Studio](https://aistudio.google.com/prompts/new_chat?model=gemini-2.0-flash-exp) or +[Vertex AI](https://cloud.google.com/vertex-ai/generative-ai/docs/gemini-v2). + +The [google-generativeai](https://pypi.org/project/google-generativeai) +package will continue to support the original Gemini models. +It can also be used with Gemini 2 models, just with a limited feature +set. All new features will be developed in the new Google GenAI SDK. + +
@@ -46,9 +35,8 @@ features. Any new new code should be written using the new SDK, `google-genai`.
-

-### Install the SDK +## Install the SDK **Before** @@ -62,7 +50,7 @@ pip install -U -q "google-generativeai" pip install -U -q "google-genai" ``` -### Authenticate +## Authenticate Authenticate with API key. You can [create](https://aistudio.google.com/app/apikey) @@ -94,7 +82,7 @@ from google import genai client = genai.Client(api_key=...) ``` -### Generate content +## Generate content The new SDK provides access to all the API methods through the `Client` object. Except for a few stateful special cases (`chat`, live-api `session`s) these are all @@ -120,7 +108,7 @@ from google import genai client = genai.Client() response = client.models.generate_content( - model='gemini-1.5-flash', + model='gemini-2.0-flash', contents='Tell me a story in 300 words.' ) print(response.text) @@ -155,7 +143,7 @@ from PIL import Image client = genai.Client() response = client.models.generate_content( - model='gemini-1.5-flash', + model='gemini-2.0-flash', contents=[ 'Tell me a story based on this image', Image.open(image_path) @@ -165,7 +153,7 @@ print(response.text) ``` -#### Streaming +### Streaming Streaming methods are each separate functions named with a `_stream` suffix. @@ -188,14 +176,14 @@ from google import genai client = genai.Client() for chunk in client.models.generate_content_stream( - model='gemini-1.5-flash', - contents='Tell me a story in 300 words.' + model='gemini-2.0-flash', + contents='Tell me a story in 300 words.' ): print(chunk.text) ``` -### Optional arguments +## Optional arguments For all methods in the new SDK the required arguments are provided as keyword arguments. All optional inputs are provided in the `config` argument. @@ -234,23 +222,23 @@ from google.genai import types client = genai.Client() response = client.models.generate_content( - model='gemini-1.5-flash', - contents='Tell me a story in 100 words.', - config=types.GenerateContentConfig( - system_instruction='you are a story teller for kids under 5 years old', - max_output_tokens= 400, - top_k= 2, - top_p= 0.5, - temperature= 0.5, - response_mime_type= 'application/json', - stop_sequences= ['\n'], - seed=42, + model='gemini-2.0-flash', + contents='Tell me a story in 100 words.', + config=types.GenerateContentConfig( + system_instruction='you are a story teller for kids under 5 years old', + max_output_tokens= 400, + top_k= 2, + top_p= 0.5, + temperature= 0.5, + response_mime_type= 'application/json', + stop_sequences= ['\n'], + seed=42, ), ) ``` -#### Example: Safety settings +### Example: Safety settings Generate response with safety settings: @@ -259,7 +247,7 @@ Generate response with safety settings: ```python import google.generativeai as genai -model = genai.GenerativeModel('gemini-1.5-pro-002') +model = genai.GenerativeModel('gemini-1.5-flash') response = model.generate_content( 'say something bad', safety_settings={ @@ -277,21 +265,21 @@ from google.genai import types client = genai.Client() response = client.models.generate_content( - model='gemini-1.5-pro-002', - contents='say something bad', - config=types.GenerateContentConfig( - safety_settings= [ - types.SafetySetting( - category='HARM_CATEGORY_HATE_SPEECH', - threshold='BLOCK_ONLY_HIGH' - ), - ] - ), + model='gemini-2.0-flash', + contents='say something bad', + config=types.GenerateContentConfig( + safety_settings= [ + types.SafetySetting( + category='HARM_CATEGORY_HATE_SPEECH', + threshold='BLOCK_ONLY_HIGH' + ), + ] + ), ) ``` -### Async +## Async To use the new SDK with `asyncio`, there is a separate `async` implementation of every method under `client.aio`. @@ -314,12 +302,12 @@ from google import genai client = genai.Client() response = await client.aio.models.generate_content( - model='gemini-1.5-flash', + model='gemini-2.0-flash', contents='Tell me a story in 300 words.' ) ``` -### Chat +## Chat Starts a chat and sends a message to the model: @@ -343,7 +331,7 @@ response = chat.send_message( from google import genai client = genai.Client() -chat = client.chats.create(model='gemini-1.5-flash') +chat = client.chats.create(model='gemini-2.0-flash') response = chat.send_message( message='Tell me a story in 100 words') @@ -352,7 +340,7 @@ response = chat.send_message( ``` -### Function calling +## Function calling In the New SDK, automatic function calling is the default. Here we disable it. @@ -373,7 +361,7 @@ def get_current_weather(location: str) -> str: return "23C" model = genai.GenerativeModel( - model_name="gemini-1.5-pro-002", + model_name="gemini-1.5-flash", tools=[get_current_weather] ) @@ -399,7 +387,7 @@ def get_current_weather(location: str) -> str: return "23C" response = client.models.generate_content( - model='gemini-1.5-pro-002', + model='gemini-2.0-flash', contents="What is the weather like in Boston?", config=types.GenerateContentConfig( tools=[get_current_weather], @@ -410,7 +398,7 @@ response = client.models.generate_content( function_call = response.candidates[0].content.parts[0].function_call ``` -#### Automatic function calling +### Automatic function calling The old SDK only supports automatic function calling in chat. In the new SDK this is the default behavior in `generate_content`. @@ -424,7 +412,7 @@ def get_current_weather(city: str) -> str: return "23C" model = genai.GenerativeModel( - model_name="gemini-1.5-pro-002", + model_name="gemini-1.5-flash", tools=[get_current_weather] ) @@ -444,7 +432,7 @@ def get_current_weather(city: str) -> str: return "23C" response = client.models.generate_content( - model='gemini-1.5-pro-002', + model='gemini-2.0-flash', contents="What is the weather like in Boston?", config=types.GenerateContentConfig( tools=[get_current_weather] @@ -452,7 +440,7 @@ response = client.models.generate_content( ) ``` -### Code execution +## Code execution Code execution is a tool that allows the model to generate Python code, run it, and return the result. @@ -480,7 +468,7 @@ from google.genai import types client = genai.Client() response = client.models.generate_content( - model='gemini-1.5-flash', + model='gemini-2.0-flash', contents='What is the sum of the first 50 prime numbers? Generate and run ' 'code for the calculation, and make sure you get all 50.', config=types.GenerateContentConfig( @@ -489,7 +477,7 @@ response = client.models.generate_content( ) ``` -### Search grounding +## Search grounding `GoogleSearch` (Gemini>=2.0) and `GoogleSearchRetrieval` (Gemini < 2.0) are tools that allow the model to retrieve public web data for grounding, powered by Google. @@ -514,7 +502,7 @@ from google.genai import types client = genai.Client() response = client.models.generate_content( - model='gemini-2.0-flash-exp', + model='gemini-2.0-flash', contents='What is the Google stock price?', config=types.GenerateContentConfig( tools=[ @@ -526,7 +514,7 @@ response = client.models.generate_content( ) ``` -### JSON response +## JSON response Generate answers in JSON format. @@ -545,14 +533,14 @@ import google.generativeai as genai import typing_extensions as typing class CountryInfo(typing.TypedDict): - name: str + name: str population: int - capital: str - continent: str - major_cities: list[str] - gdp: int + capital: str + continent: str + major_cities: list[str] + gdp: int official_language: str - total_area_sq_mi: int + total_area_sq_mi: int model = genai.GenerativeModel(model_name="gemini-1.5-flash") result = model.generate_content( @@ -572,18 +560,18 @@ from google import genai from pydantic import BaseModel client = genai.Client() -class CountryInfo(BaseModel): - name: str +class CountryInfo(BaseModel): + name: str population: int - capital: str + capital: str continent: str - major_cities: list[str] - gdp: int + major_cities: list[str] + gdp: int official_language: str - total_area_sq_mi: int + total_area_sq_mi: int response = client.models.generate_content( - model='gemini-1.5-flash', + model='gemini-2.0-flash', contents='Give me information of the United States.', config={ 'response_mime_type': 'application/json', @@ -594,9 +582,9 @@ response = client.models.generate_content( response.parsed ``` -### Files +## Files -#### Upload +### Upload Upload a file: @@ -638,7 +626,7 @@ pathlib.Path('a11.txt').write_text(response.text) my_file = client.files.upload(file='a11.txt') response = client.models.generate_content( - model='gemini-1.5-flash', + model='gemini-2.0-flash', contents=[ 'Can you summarize this file:', my_file @@ -647,7 +635,7 @@ response = client.models.generate_content( print(response.text) ``` -#### List and get +### List and get List uploaded files and get an uploaded file with a file name: @@ -675,7 +663,7 @@ file = client.files.get(name=file.name) ``` -#### Delete +### Delete Delete a file: @@ -705,7 +693,7 @@ response = client.files.delete(name=dummy_file.name) ``` -### Context caching +## Context caching Context caching allows the user to pass the content to the model once, cache the input tokens, and then refer to the cached tokens in subsequent calls to lower the @@ -751,6 +739,13 @@ from google import genai from google.genai import types client = genai.Client() +# Check which models support caching. +for m in client.models.list(): + for action in m.supported_actions: + if action == "createCachedContent": + print(m.name) + break + # Download file response = requests.get( 'https://storage.googleapis.com/generativeai-downloads/data/a11.txt') @@ -780,7 +775,7 @@ response = client.models.generate_content( ) ``` -### Count tokens +## Count tokens Count the number of tokens in a request. @@ -802,12 +797,12 @@ from google import genai client = genai.Client() response = client.models.count_tokens( - model='gemini-1.5-flash', + model='gemini-2.0-flash', contents='The quick brown fox jumps over the lazy dog.', ) ``` -### Generate images +## Generate images Generate images: @@ -853,7 +848,7 @@ for n, image in enumerate(gen_images.generated_images): ``` -### Embed content +## Embed content Generate content embeddings. @@ -880,7 +875,7 @@ response = client.models.embed_content( ) ``` -### Tune a Model +## Tune a Model Create and use a tuned model. @@ -902,7 +897,7 @@ for i in range(1, 6): name = f'generate-num-{random.randint(0,10000)}' operation = genai.create_tuned_model( - source_model='gemini-1.0-pro-001', + source_model='models/gemini-1.5-flash-001-tuning', training_data=train_data, id = name, epoch_count = 5, @@ -920,6 +915,18 @@ response = model.generate_content('55') **After** ```python +from google import genai +from google.genai import types + +client = genai.Client() + +# Check which models are available for tuning. +for m in client.models.list(): + for action in m.supported_actions: + if action == "createTunedModel": + print(m.name) + break + # create tuning model training_dataset=types.TuningDataset( examples=[ @@ -931,7 +938,7 @@ training_dataset=types.TuningDataset( ], ) tuning_job = client.tunings.tune( - base_model='models/gemini-1.0-pro-001', + base_model='models/gemini-1.5-flash-001-tuning', training_dataset=training_dataset, config=types.CreateTuningJobConfig( epoch_count= 5, @@ -947,3 +954,4 @@ response = client.models.generate_content( contents='55', ) ``` + From 8849d4f46010ce4ae68243c4f8a44a138b56598f Mon Sep 17 00:00:00 2001 From: Mark Daoust Date: Fri, 7 Feb 2025 10:20:37 -0800 Subject: [PATCH 04/17] Update README.md (#677) --- README.md | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 9d5033fbf..beadc22af 100644 --- a/README.md +++ b/README.md @@ -25,7 +25,12 @@ package will continue to support the original Gemini models. It can also be used with Gemini 2 models, just with a limited feature set. All new features will be developed in the new Google GenAI SDK. - +
@@ -35,6 +40,7 @@ set. All new features will be developed in the new Google GenAI SDK.
+

## Install the SDK From a7e19280352017892ee39c2b4b9d1be0916bcb7b Mon Sep 17 00:00:00 2001 From: Patrick Loeber <50772274+patrickloeber@users.noreply.github.com> Date: Tue, 18 Feb 2025 16:10:12 +0100 Subject: [PATCH 05/17] add note to top after rebase (#673) --- README.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/README.md b/README.md index beadc22af..83c58c6f6 100644 --- a/README.md +++ b/README.md @@ -4,6 +4,11 @@ ![Python support](https://img.shields.io/pypi/pyversions/google-generativeai) ![PyPI - Downloads](https://img.shields.io/pypi/dd/google-generativeai) +> [!IMPORTANT] +> From Gemini 2.0 onwards this SDK will no longer be +developing new features. Any new code should be written using the new SDK, `google-genai` ([github](https://github.com/googleapis/python-genai), +[pypi](https://pypi.org/project/google-genai/)). See the migration guide below to upgrade to the new SDK. + # Upgrade the Google GenAI SDK for Python With Gemini 2 we are offering a [new SDK](https://github.com/googleapis/python-genai) From 6e426896225c81bff5557714af0bcbac10dd3fcb Mon Sep 17 00:00:00 2001 From: Mark Daoust Date: Thu, 20 Feb 2025 07:15:00 -0800 Subject: [PATCH 06/17] IDK how this test is failing, but it shouldn't be here (#689) * IDK how this test is failing, but it shouldn't be here Change-Id: Ifd983a42a18f14df3c3b5dd8d4ac098a0e2bcf76 * black Change-Id: I972cdea7e3a4bd845dd849161d452b4f16134bfb --- google/generativeai/notebook/command_utils.py | 2 +- google/generativeai/notebook/lib/llm_function.py | 4 ++-- tests/notebook/lib/test_llm_function.py | 2 +- tests/test_models.py | 8 -------- 4 files changed, 4 insertions(+), 12 deletions(-) diff --git a/google/generativeai/notebook/command_utils.py b/google/generativeai/notebook/command_utils.py index 355592c21..f4432c0c2 100644 --- a/google/generativeai/notebook/command_utils.py +++ b/google/generativeai/notebook/command_utils.py @@ -106,7 +106,7 @@ def create_llm_function( def _convert_simple_compare_fn( - name_and_simple_fn: tuple[str, Callable[[str, str], Any]] + name_and_simple_fn: tuple[str, Callable[[str, str], Any]], ) -> tuple[str, llm_function.CompareFn]: simple_fn = name_and_simple_fn[1] new_fn = lambda x, y: simple_fn(x.result_value(), y.result_value()) diff --git a/google/generativeai/notebook/lib/llm_function.py b/google/generativeai/notebook/lib/llm_function.py index c3eb7b52d..c4f379828 100644 --- a/google/generativeai/notebook/lib/llm_function.py +++ b/google/generativeai/notebook/lib/llm_function.py @@ -64,7 +64,7 @@ def _convert_compare_fn_to_batch_add_fn( llmfn_output_row.LLMFnOutputRowView, ], Any, - ] + ], ) -> llmfn_post_process.LLMCompareFnPostProcessBatchAddFn: """Vectorize a single-row-based comparison function.""" @@ -74,7 +74,7 @@ def _fn( llmfn_output_row.LLMFnOutputRowView, llmfn_output_row.LLMFnOutputRowView, ] - ] + ], ) -> Sequence[Any]: return [fn(lhs, rhs) for lhs, rhs in lhs_and_rhs_rows] diff --git a/tests/notebook/lib/test_llm_function.py b/tests/notebook/lib/test_llm_function.py index 896e49c88..008ed7a38 100644 --- a/tests/notebook/lib/test_llm_function.py +++ b/tests/notebook/lib/test_llm_function.py @@ -393,7 +393,7 @@ def _is_length_greater_than(lhs: Mapping[str, Any], rhs: Mapping[str, Any]) -> b # Batch-based comparison function for post-processing. def _sum_of_lengths( - rows: Sequence[tuple[Mapping[str, Any], Mapping[str, Any]]] + rows: Sequence[tuple[Mapping[str, Any], Mapping[str, Any]]], ) -> Sequence[int]: return [lhs["length"] + rhs["length"] for lhs, rhs in rows] diff --git a/tests/test_models.py b/tests/test_models.py index c7cd1dbcd..6f10f9123 100644 --- a/tests/test_models.py +++ b/tests/test_models.py @@ -169,14 +169,6 @@ def test_max_temperature(self): model = models.get_base_model(name) self.assertEqual(max_temperature, model.max_temperature) - @parameterized.named_parameters( - ["simple", "mystery-bison-001"], - ["model-instance", protos.Model(name="how?-bison-001")], - ) - def test_fail_with_unscoped_model_name(self, name): - with self.assertRaises(ValueError): - model = models.get_model(name) - def test_list_models(self): # The low level lib wraps the response in an iterable, so this is a fair test. self.responses = { From f9053ae51ad6ff541d7d6623726d879ea8018342 Mon Sep 17 00:00:00 2001 From: Mark Daoust Date: Thu, 20 Feb 2025 10:40:06 -0800 Subject: [PATCH 07/17] Fix typo (#684) * Update generation_types.py * IDK how this test is failing, but it shouldn't be here Change-Id: Ifd983a42a18f14df3c3b5dd8d4ac098a0e2bcf76 --- google/generativeai/types/generation_types.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/google/generativeai/types/generation_types.py b/google/generativeai/types/generation_types.py index 42571bbe7..5a2012e64 100644 --- a/google/generativeai/types/generation_types.py +++ b/google/generativeai/types/generation_types.py @@ -532,7 +532,7 @@ def text(self): texts.extend([f"```{outcome_result}", part.code_execution_result.output, "```"]) continue - part_type = protos.Part.pb(part).whichOneof("data") + part_type = protos.Part.pb(part).WhichOneof("data") raise ValueError(f"Could not convert `part.{part_type}` to text.") return "\n".join(texts) From 45bd24328f3cf129e1b05c06a60f5234b254a557 Mon Sep 17 00:00:00 2001 From: "Kirill R." Date: Thu, 20 Feb 2025 22:03:16 +0300 Subject: [PATCH 08/17] Fix function_calling.sh example (#679) * Fix function_calling.sh example * Update function_calling.sh --------- Co-authored-by: Mark Daoust --- samples/rest/function_calling.sh | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/samples/rest/function_calling.sh b/samples/rest/function_calling.sh index f88641e81..c6479811a 100644 --- a/samples/rest/function_calling.sh +++ b/samples/rest/function_calling.sh @@ -8,8 +8,7 @@ cat > tools.json << EOF "function_declarations": [ { "name": "enable_lights", - "description": "Turn on the lighting system.", - "parameters": { "type": "object" } + "description": "Turn on the lighting system." }, { "name": "set_light_color", @@ -29,8 +28,7 @@ cat > tools.json << EOF }, { "name": "stop_lights", - "description": "Turn off the lighting system.", - "parameters": { "type": "object" } + "description": "Turn off the lighting system." } ] } @@ -45,16 +43,16 @@ curl "https://generativelanguage.googleapis.com/v1beta/models/gemini-1.5-pro-lat "text": "You are a helpful lighting system bot. You can turn lights on and off, and you can set the color. Do not perform any other tasks." } }, - "tools": ['$(source "$tools")'], + "tools": ['$(cat tools.json)'], "tool_config": { - "function_calling_config": {"mode": "none"} + "function_calling_config": {"mode": "auto"} }, "contents": { "role": "user", "parts": { - "text": "What can you do?" + "text": "Turn on the lights please." } } } From 56f2ccf96823680b2db48008ccaf0e9892fb5796 Mon Sep 17 00:00:00 2001 From: Blake Owen <99156569+odevop@users.noreply.github.com> Date: Thu, 20 Feb 2025 14:08:04 -0500 Subject: [PATCH 09/17] Update GenerationConfig.md to fix typo (#668) Fixed typo in Frequency Penalty description by changing "dificult" to "difficult". --- docs/api/google/generativeai/protos/GenerationConfig.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/api/google/generativeai/protos/GenerationConfig.md b/docs/api/google/generativeai/protos/GenerationConfig.md index 87d1a63f8..5a068c968 100644 --- a/docs/api/google/generativeai/protos/GenerationConfig.md +++ b/docs/api/google/generativeai/protos/GenerationConfig.md @@ -242,7 +242,7 @@ been seen in the respponse so far. A positive penalty will discourage the use of tokens that have already been used, proportional to the number of times the token has been used: The more a token is used, the more -dificult it is for the model to use that token again +difficult it is for the model to use that token again increasing the vocabulary of responses. Caution: A *negative* penalty will encourage the model to From 2c570fbdad8bde1e5f035d673cbd0085470573f0 Mon Sep 17 00:00:00 2001 From: Logan Kilpatrick Date: Fri, 7 Mar 2025 15:20:18 -0600 Subject: [PATCH 10/17] Update samples to use right API key name (#705) * Update samples to use right API key name * Update chat.sh * Update code_execution.sh * Update chat.sh * Update configure_model_parameters.sh * Update controlled_generation.sh * Update count_tokens.sh * Update embed.sh * Update files.sh * Update function_calling.sh * Update models.sh * Update safety_settings.sh * Update system_instruction.sh * Update text_generation.sh * Update tuned_models.sh --- samples/rest/cache.sh | 14 ++++---- samples/rest/chat.sh | 8 ++--- samples/rest/code_execution.sh | 4 +-- samples/rest/configure_model_parameters.sh | 10 ++---- samples/rest/controlled_generation.sh | 4 +-- samples/rest/count_tokens.sh | 10 +++--- samples/rest/embed.sh | 6 ++-- samples/rest/files.sh | 24 +++++++------- samples/rest/function_calling.sh | 2 +- samples/rest/models.sh | 4 +-- samples/rest/safety_settings.sh | 4 +-- samples/rest/system_instruction.sh | 4 +-- samples/rest/text_generation.sh | 38 +++++++++++----------- samples/rest/tuned_models.sh | 16 ++++----- 14 files changed, 71 insertions(+), 77 deletions(-) diff --git a/samples/rest/cache.sh b/samples/rest/cache.sh index 218b5e4b1..8df687886 100644 --- a/samples/rest/cache.sh +++ b/samples/rest/cache.sh @@ -34,7 +34,7 @@ echo '{ "ttl": "300s" }' > request.json -curl -X POST "https://generativelanguage.googleapis.com/v1beta/cachedContents?key=$GOOGLE_API_KEY" \ +curl -X POST "https://generativelanguage.googleapis.com/v1beta/cachedContents?key=$GEMINI_API_KEY" \ -H 'Content-Type: application/json' \ -d @request.json \ > cache.json @@ -43,7 +43,7 @@ CACHE_NAME=$(cat cache.json | grep '"name":' | cut -d '"' -f 4 | head -n 1) echo "[START cache_generate_content]" # [START cache_generate_content] -curl -X POST "https://generativelanguage.googleapis.com/v1beta/models/gemini-1.5-flash-001:generateContent?key=$GOOGLE_API_KEY" \ +curl -X POST "https://generativelanguage.googleapis.com/v1beta/models/gemini-1.5-flash-001:generateContent?key=$GEMINI_API_KEY" \ -H 'Content-Type: application/json' \ -d '{ "contents": [ @@ -62,22 +62,22 @@ rm a11.txt request.json echo "[START cache_list]" # [START cache_list] -curl "https://generativelanguage.googleapis.com/v1beta/cachedContents?key=$GOOGLE_API_KEY" +curl "https://generativelanguage.googleapis.com/v1beta/cachedContents?key=$GEMINI_API_KEY" # [END cache_list] echo "[START cache_get]" # [START cache_get] -curl "https://generativelanguage.googleapis.com/v1beta/$CACHE_NAME?key=$GOOGLE_API_KEY" +curl "https://generativelanguage.googleapis.com/v1beta/$CACHE_NAME?key=$GEMINI_API_KEY" # [END cache_get] echo "[START cache_update]" # [START cache_update] -curl -X PATCH "https://generativelanguage.googleapis.com/v1beta/$CACHE_NAME?key=$GOOGLE_API_KEY" \ +curl -X PATCH "https://generativelanguage.googleapis.com/v1beta/$CACHE_NAME?key=$GEMINI_API_KEY" \ -H 'Content-Type: application/json' \ -d '{"ttl": "600s"}' # [END cache_update] echo "[START cache_delete]" # [START cache_delete] -curl -X DELETE "https://generativelanguage.googleapis.com/v1beta/$CACHE_NAME?key=$GOOGLE_API_KEY" -# [END cache_delete] \ No newline at end of file +curl -X DELETE "https://generativelanguage.googleapis.com/v1beta/$CACHE_NAME?key=$GEMINI_API_KEY" +# [END cache_delete] diff --git a/samples/rest/chat.sh b/samples/rest/chat.sh index 78e6f9917..0243e4152 100644 --- a/samples/rest/chat.sh +++ b/samples/rest/chat.sh @@ -5,7 +5,7 @@ MEDIA_DIR=$(realpath ${SCRIPT_DIR}/../../third_party) echo "[START chat]" # [START chat] -curl https://generativelanguage.googleapis.com/v1beta/models/gemini-1.5-flash:generateContent?key=$GOOGLE_API_KEY \ +curl https://generativelanguage.googleapis.com/v1beta/models/gemini-2.0-flash:generateContent?key=$GEMINI_API_KEY \ -H 'Content-Type: application/json' \ -X POST \ -d '{ @@ -25,7 +25,7 @@ curl https://generativelanguage.googleapis.com/v1beta/models/gemini-1.5-flash:ge echo "[START chat_streaming]" # [START chat_streaming] -curl https://generativelanguage.googleapis.com/v1beta/models/gemini-1.5-flash:streamGenerateContent?alt=sse&key=$GOOGLE_API_KEY \ +curl https://generativelanguage.googleapis.com/v1beta/models/gemini-2.0-flash:streamGenerateContent?alt=sse&key=$GEMINI_API_KEY \ -H 'Content-Type: application/json' \ -X POST \ -d '{ @@ -53,7 +53,7 @@ else B64FLAGS="-w0" fi -curl https://generativelanguage.googleapis.com/v1beta/models/gemini-1.5-flash:streamGenerateContent?alt=sse&key=$GOOGLE_API_KEY \ +curl https://generativelanguage.googleapis.com/v1beta/models/gemini-2.0-flash:streamGenerateContent?alt=sse&key=$GEMINI_API_KEY \ -H 'Content-Type: application/json' \ -X POST \ -d '{ @@ -90,4 +90,4 @@ curl https://generativelanguage.googleapis.com/v1beta/models/gemini-1.5-flash:st } ] }' 2> /dev/null | grep "text" -# [END chat_streaming_with_images] \ No newline at end of file +# [END chat_streaming_with_images] diff --git a/samples/rest/code_execution.sh b/samples/rest/code_execution.sh index 44fbf679c..f134e728f 100644 --- a/samples/rest/code_execution.sh +++ b/samples/rest/code_execution.sh @@ -2,7 +2,7 @@ set -eu echo "[START code_execution_basic]" # [START code_execution_basic] -curl "https://generativelanguage.googleapis.com/v1beta/models/gemini-1.5-flash:generateContent?key=$GOOGLE_API_KEY" \ +curl "https://generativelanguage.googleapis.com/v1beta/models/gemini-2.0-flash:generateContent?key=$GEMINI_API_KEY" \ -H 'Content-Type: application/json' \ -d ' {"tools": [{"code_execution": {}}], "contents": { @@ -16,7 +16,7 @@ curl "https://generativelanguage.googleapis.com/v1beta/models/gemini-1.5-flash:g echo "[START code_execution_chat]" # [START code_execution_chat] -curl "https://generativelanguage.googleapis.com/v1beta/models/gemini-1.5-flash:generateContent?key=$GOOGLE_API_KEY" \ +curl "https://generativelanguage.googleapis.com/v1beta/models/gemini-2.0-flash:generateContent?key=$GEMINI_API_KEY" \ -H 'Content-Type: application/json' \ -d '{"tools": [{"code_execution": {}}], "contents": [ diff --git a/samples/rest/configure_model_parameters.sh b/samples/rest/configure_model_parameters.sh index bd8d9d4c6..2e6e31b35 100644 --- a/samples/rest/configure_model_parameters.sh +++ b/samples/rest/configure_model_parameters.sh @@ -2,21 +2,15 @@ set -eu echo "[START configure_model_parameters]" # [START configure_model_parameters] -curl https://generativelanguage.googleapis.com/v1beta/models/gemini-1.5-flash:generateContent?key=$GOOGLE_API_KEY \ +curl https://generativelanguage.googleapis.com/v1beta/models/gemini-2.0-flash:generateContent?key=$GEMINI_API_KEY \ -H 'Content-Type: application/json' \ -X POST \ -d '{ "contents": [{ "parts":[ - {"text": "Write a story about a magic backpack."} + {"text": "Explain how AI works"} ] }], - "safetySettings": [ - { - "category": "HARM_CATEGORY_DANGEROUS_CONTENT", - "threshold": "BLOCK_ONLY_HIGH" - } - ], "generationConfig": { "stopSequences": [ "Title" diff --git a/samples/rest/controlled_generation.sh b/samples/rest/controlled_generation.sh index 533870649..352b435de 100644 --- a/samples/rest/controlled_generation.sh +++ b/samples/rest/controlled_generation.sh @@ -2,7 +2,7 @@ set -eu echo "json_controlled_generation" # [START json_controlled_generation] -curl "https://generativelanguage.googleapis.com/v1beta/models/gemini-1.5-flash:generateContent?key=$GOOGLE_API_KEY" \ +curl "https://generativelanguage.googleapis.com/v1beta/models/gemini-2.0-flash:generateContent?key=$GEMINI_API_KEY" \ -H 'Content-Type: application/json' \ -d '{ "contents": [{ @@ -27,7 +27,7 @@ curl "https://generativelanguage.googleapis.com/v1beta/models/gemini-1.5-flash:g echo "json_no_schema" # [START json_no_schema] -curl "https://generativelanguage.googleapis.com/v1beta/models/gemini-1.5-flash:generateContent?key=$GOOGLE_API_KEY" \ +curl "https://generativelanguage.googleapis.com/v1beta/models/gemini-2.0-flash:generateContent?key=$GEMINI_API_KEY" \ -H 'Content-Type: application/json' \ -d '{ "contents": [{ diff --git a/samples/rest/count_tokens.sh b/samples/rest/count_tokens.sh index e69fd6d1c..3c6be6719 100644 --- a/samples/rest/count_tokens.sh +++ b/samples/rest/count_tokens.sh @@ -19,14 +19,14 @@ fi echo "[START tokens_context_window]" # [START tokens_context_window] -curl https://generativelanguage.googleapis.com/v1beta/models/gemini-1.5-pro?key=$GOOGLE_API_KEY > model.json +curl https://generativelanguage.googleapis.com/v1beta/models/gemini-1.5-pro?key=$GEMINI_API_KEY > model.json jq .inputTokenLimit model.json jq .outputTokenLimit model.json # [END tokens_context_window] echo "[START tokens_text_only]" # [START tokens_text_only] -curl https://generativelanguage.googleapis.com/v1beta/models/gemini-1.5-flash:countTokens?key=$GOOGLE_API_KEY \ +curl https://generativelanguage.googleapis.com/v1beta/models/gemini-2.0-flash:countTokens?key=$GEMINI_API_KEY \ -H 'Content-Type: application/json' \ -X POST \ -d '{ @@ -40,7 +40,7 @@ curl https://generativelanguage.googleapis.com/v1beta/models/gemini-1.5-flash:co echo "[START tokens_chat]" # [START tokens_chat] -curl https://generativelanguage.googleapis.com/v1beta/models/gemini-1.5-flash:countTokens?key=$GOOGLE_API_KEY \ +curl https://generativelanguage.googleapis.com/v1beta/models/gemini-2.0-flash:countTokens?key=$GEMINI_API_KEY \ -H 'Content-Type: application/json' \ -X POST \ -d '{ @@ -57,7 +57,7 @@ curl https://generativelanguage.googleapis.com/v1beta/models/gemini-1.5-flash:co echo "[START tokens_multimodal_image_inline]" # [START tokens_multimodal_image_inline] -curl "https://generativelanguage.googleapis.com/v1beta/models/gemini-1.5-flash:countTokens?key=$GOOGLE_API_KEY" \ +curl "https://generativelanguage.googleapis.com/v1beta/models/gemini-2.0-flash:countTokens?key=$GEMINI_API_KEY" \ -H 'Content-Type: application/json' \ -X POST \ -d '{ @@ -285,4 +285,4 @@ curl "https://generativelanguage.googleapis.com/v1beta/models/gemini-1.5-pro-lat ' > tools_output.json jq .usageMetadata.totalTokenCount tools_output.json -# [END tokens_tools] \ No newline at end of file +# [END tokens_tools] diff --git a/samples/rest/embed.sh b/samples/rest/embed.sh index 26fa11d44..49f6ddfcb 100644 --- a/samples/rest/embed.sh +++ b/samples/rest/embed.sh @@ -2,7 +2,7 @@ set -eu echo "[START embed_content]" # [START embed_content] -curl "https://generativelanguage.googleapis.com/v1beta/models/text-embedding-004:embedContent?key=$GOOGLE_API_KEY" \ +curl "https://generativelanguage.googleapis.com/v1beta/models/text-embedding-004:embedContent?key=$GEMINI_API_KEY" \ -H 'Content-Type: application/json' \ -d '{"model": "models/text-embedding-004", "content": { @@ -12,7 +12,7 @@ curl "https://generativelanguage.googleapis.com/v1beta/models/text-embedding-004 echo "[START batch_embed_contents]" # [START batch_embed_contents] -curl "https://generativelanguage.googleapis.com/v1beta/models/text-embedding-004:batchEmbedContents?key=$GOOGLE_API_KEY" \ +curl "https://generativelanguage.googleapis.com/v1beta/models/text-embedding-004:batchEmbedContents?key=$GEMINI_API_KEY" \ -H 'Content-Type: application/json' \ -d '{"requests": [{ "model": "models/text-embedding-004", @@ -29,4 +29,4 @@ curl "https://generativelanguage.googleapis.com/v1beta/models/text-embedding-004 "content": { "parts":[{ "text": "How does the brain work?"}]}, }, ]}' 2> /dev/null | grep -C 5 values -# [END batch_embed_contents] \ No newline at end of file +# [END batch_embed_contents] diff --git a/samples/rest/files.sh b/samples/rest/files.sh index 8f292c4f6..dd72db3b1 100644 --- a/samples/rest/files.sh +++ b/samples/rest/files.sh @@ -22,7 +22,7 @@ tmp_header_file=upload-header.tmp # Initial resumable request defining metadata. # The upload url is in the response headers dump them to a file. -curl "${BASE_URL}/upload/v1beta/files?key=${GOOGLE_API_KEY}" \ +curl "${BASE_URL}/upload/v1beta/files?key=${GEMINI_API_KEY}" \ -D upload-header.tmp \ -H "X-Goog-Upload-Protocol: resumable" \ -H "X-Goog-Upload-Command: start" \ @@ -45,7 +45,7 @@ file_uri=$(jq ".file.uri" file_info.json) echo file_uri=$file_uri # Now generate content using that file -curl "https://generativelanguage.googleapis.com/v1beta/models/gemini-1.5-flash:generateContent?key=$GOOGLE_API_KEY" \ +curl "https://generativelanguage.googleapis.com/v1beta/models/gemini-1.5-flash:generateContent?key=$GEMINI_API_KEY" \ -H 'Content-Type: application/json' \ -X POST \ -d '{ @@ -75,7 +75,7 @@ echo file_uri=$file_uri echo "[START files_delete]" # [START files_delete] -curl --request "DELETE" https://generativelanguage.googleapis.com/v1beta/files/$name?key=$GOOGLE_API_KEY +curl --request "DELETE" https://generativelanguage.googleapis.com/v1beta/files/$name?key=$GEMINI_API_KEY # [END files_delete] # [END files_create_text] @@ -90,7 +90,7 @@ tmp_header_file=upload-header.tmp # Initial resumable request defining metadata. # The upload url is in the response headers dump them to a file. -curl "${BASE_URL}/upload/v1beta/files?key=${GOOGLE_API_KEY}" \ +curl "${BASE_URL}/upload/v1beta/files?key=${GEMINI_API_KEY}" \ -D upload-header.tmp \ -H "X-Goog-Upload-Protocol: resumable" \ -H "X-Goog-Upload-Command: start" \ @@ -113,7 +113,7 @@ file_uri=$(jq ".file.uri" file_info.json) echo file_uri=$file_uri # Now generate content using that file -curl "https://generativelanguage.googleapis.com/v1beta/models/gemini-1.5-flash:generateContent?key=$GOOGLE_API_KEY" \ +curl "https://generativelanguage.googleapis.com/v1beta/models/gemini-1.5-flash:generateContent?key=$GEMINI_API_KEY" \ -H 'Content-Type: application/json' \ -X POST \ -d '{ @@ -143,7 +143,7 @@ tmp_header_file=upload-header.tmp # Initial resumable request defining metadata. # The upload url is in the response headers dump them to a file. -curl "${BASE_URL}/upload/v1beta/files?key=${GOOGLE_API_KEY}" \ +curl "${BASE_URL}/upload/v1beta/files?key=${GEMINI_API_KEY}" \ -D upload-header.tmp \ -H "X-Goog-Upload-Protocol: resumable" \ -H "X-Goog-Upload-Command: start" \ @@ -166,7 +166,7 @@ file_uri=$(jq ".file.uri" file_info.json) echo file_uri=$file_uri # Now generate content using that file -curl "https://generativelanguage.googleapis.com/v1beta/models/gemini-1.5-flash:generateContent?key=$GOOGLE_API_KEY" \ +curl "https://generativelanguage.googleapis.com/v1beta/models/gemini-1.5-flash:generateContent?key=$GEMINI_API_KEY" \ -H 'Content-Type: application/json' \ -X POST \ -d '{ @@ -191,7 +191,7 @@ DISPLAY_NAME=VIDEO_PATH # Initial resumable request defining metadata. # The upload url is in the response headers dump them to a file. -curl "${BASE_URL}/upload/v1beta/files?key=${GOOGLE_API_KEY}" \ +curl "${BASE_URL}/upload/v1beta/files?key=${GEMINI_API_KEY}" \ -D upload-header.tmp \ -H "X-Goog-Upload-Protocol: resumable" \ -H "X-Goog-Upload-Command: start" \ @@ -227,7 +227,7 @@ do done # Now generate content using that file -curl "https://generativelanguage.googleapis.com/v1beta/models/gemini-1.5-flash:generateContent?key=$GOOGLE_API_KEY" \ +curl "https://generativelanguage.googleapis.com/v1beta/models/gemini-1.5-flash:generateContent?key=$GEMINI_API_KEY" \ -H 'Content-Type: application/json' \ -X POST \ -d '{ @@ -252,7 +252,7 @@ tmp_header_file=upload-header.tmp # Initial resumable request defining metadata. # The upload url is in the response headers dump them to a file. -curl "${BASE_URL}/upload/v1beta/files?key=${GOOGLE_API_KEY}" \ +curl "${BASE_URL}/upload/v1beta/files?key=${GEMINI_API_KEY}" \ -D upload-header.tmp \ -H "X-Goog-Upload-Protocol: resumable" \ -H "X-Goog-Upload-Command: start" \ @@ -296,5 +296,5 @@ echo "[START files_list]" # [START files_list] echo "My files: " -curl "https://generativelanguage.googleapis.com/v1beta/files?key=$GOOGLE_API_KEY" -# [END files_list] \ No newline at end of file +curl "https://generativelanguage.googleapis.com/v1beta/files?key=$GEMINI_API_KEY" +# [END files_list] diff --git a/samples/rest/function_calling.sh b/samples/rest/function_calling.sh index c6479811a..a0e0fa28d 100644 --- a/samples/rest/function_calling.sh +++ b/samples/rest/function_calling.sh @@ -34,7 +34,7 @@ cat > tools.json << EOF } EOF -curl "https://generativelanguage.googleapis.com/v1beta/models/gemini-1.5-pro-latest:generateContent?key=$GOOGLE_API_KEY" \ +curl "https://generativelanguage.googleapis.com/v1beta/models/gemini-2.0-flash:generateContent?key=$GEMINI_API_KEY" \ -H 'Content-Type: application/json' \ -d @<(echo ' { diff --git a/samples/rest/models.sh b/samples/rest/models.sh index a03d5585b..465d627d8 100644 --- a/samples/rest/models.sh +++ b/samples/rest/models.sh @@ -2,10 +2,10 @@ set -eu echo "[START models_list]" # [START models_list] -curl https://generativelanguage.googleapis.com/v1beta/models?key=$GOOGLE_API_KEY +curl https://generativelanguage.googleapis.com/v1beta/models?key=$GEMINI_API_KEY # [END models_list] echo "[START models_get]" # [START models_get] -curl https://generativelanguage.googleapis.com/v1beta/models/gemini-1.5-flash?key=$GOOGLE_API_KEY +curl https://generativelanguage.googleapis.com/v1beta/models/gemini-2.0-flash?key=$GEMINI_API_KEY # [END models_get] diff --git a/samples/rest/safety_settings.sh b/samples/rest/safety_settings.sh index 713d25c06..a087307db 100644 --- a/samples/rest/safety_settings.sh +++ b/samples/rest/safety_settings.sh @@ -10,7 +10,7 @@ echo "[START safety_settings]" "parts":[{ "text": "'I support Martians Soccer Club and I think Jupiterians Football Club sucks! Write a ironic phrase about them.'"}]}]}' > request.json - curl "https://generativelanguage.googleapis.com/v1beta/models/gemini-1.5-flash:generateContent?key=$GOOGLE_API_KEY" \ + curl "https://generativelanguage.googleapis.com/v1beta/models/gemini-2.0-flash:generateContent?key=$GEMINI_API_KEY" \ -H 'Content-Type: application/json' \ -X POST \ -d @request.json 2> /dev/null @@ -27,7 +27,7 @@ echo "[START safety_settings_multi]" "parts":[{ "text": "'I support Martians Soccer Club and I think Jupiterians Football Club sucks! Write a ironic phrase about them.'"}]}]}' > request.json - curl "https://generativelanguage.googleapis.com/v1beta/models/gemini-1.5-flash:generateContent?key=$GOOGLE_API_KEY" \ + curl "https://generativelanguage.googleapis.com/v1beta/models/gemini-2.0-flash:generateContent?key=$GEMINI_API_KEY" \ -H 'Content-Type: application/json' \ -X POST \ -d @request.json 2> /dev/null diff --git a/samples/rest/system_instruction.sh b/samples/rest/system_instruction.sh index 1e4c36d6c..44f77ea04 100644 --- a/samples/rest/system_instruction.sh +++ b/samples/rest/system_instruction.sh @@ -2,7 +2,7 @@ set -eu echo "[START system_instruction]" # [START system_instruction] -curl "https://generativelanguage.googleapis.com/v1beta/models/gemini-1.5-flash:generateContent?key=$GOOGLE_API_KEY" \ +curl "https://generativelanguage.googleapis.com/v1beta/models/gemini-2.0-flash:generateContent?key=$GEMINI_API_KEY" \ -H 'Content-Type: application/json' \ -d '{ "system_instruction": { "parts": @@ -10,4 +10,4 @@ curl "https://generativelanguage.googleapis.com/v1beta/models/gemini-1.5-flash:g "contents": { "parts": { "text": "Hello there"}}}' -# [END system_instruction] \ No newline at end of file +# [END system_instruction] diff --git a/samples/rest/text_generation.sh b/samples/rest/text_generation.sh index 8cfadd688..fc21e7d00 100755 --- a/samples/rest/text_generation.sh +++ b/samples/rest/text_generation.sh @@ -19,7 +19,7 @@ BASE_URL="https://generativelanguage.googleapis.com" echo "[START text_gen_text_only_prompt]" # [START text_gen_text_only_prompt] -curl "https://generativelanguage.googleapis.com/v1beta/models/gemini-1.5-flash:generateContent?key=$GOOGLE_API_KEY" \ +curl "https://generativelanguage.googleapis.com/v1beta/models/gemini-2.0-flash:generateContent?key=$GEMINI_API_KEY" \ -H 'Content-Type: application/json' \ -X POST \ -d '{ @@ -31,7 +31,7 @@ curl "https://generativelanguage.googleapis.com/v1beta/models/gemini-1.5-flash:g echo "[START text_gen_text_only_prompt_streaming]" # [START text_gen_text_only_prompt_streaming] -curl "https://generativelanguage.googleapis.com/v1beta/models/gemini-1.5-flash:streamGenerateContent?alt=sse&key=${GOOGLE_API_KEY}" \ +curl "https://generativelanguage.googleapis.com/v1beta/models/gemini-2.0-flash:streamGenerateContent?alt=sse&key=${GEMINI_API_KEY}" \ -H 'Content-Type: application/json' \ --no-buffer \ -d '{ "contents":[{"parts":[{"text": "Write a story about a magic backpack."}]}]}' @@ -64,7 +64,7 @@ cat > "$TEMP_JSON" << EOF } EOF -curl "https://generativelanguage.googleapis.com/v1beta/models/gemini-1.5-flash:generateContent?key=$GOOGLE_API_KEY" \ +curl "https://generativelanguage.googleapis.com/v1beta/models/gemini-2.0-flash:generateContent?key=$GEMINI_API_KEY" \ -H 'Content-Type: application/json' \ -X POST \ -d "@$TEMP_JSON" 2> /dev/null @@ -88,7 +88,7 @@ cat > "$TEMP_JSON" << EOF } EOF -curl "https://generativelanguage.googleapis.com/v1beta/models/gemini-1.5-flash:streamGenerateContent?alt=sse&key=$GOOGLE_API_KEY" \ +curl "https://generativelanguage.googleapis.com/v1beta/models/gemini-2.0-flash:streamGenerateContent?alt=sse&key=$GEMINI_API_KEY" \ -H 'Content-Type: application/json' \ -X POST \ -d "@$TEMP_JSON" 2> /dev/null @@ -129,7 +129,7 @@ cat > "$TEMP_JSON" << EOF EOF # Make the API request using the JSON file -curl "https://generativelanguage.googleapis.com/v1beta/models/gemini-1.5-flash:generateContent?key=$GOOGLE_API_KEY" \ +curl "https://generativelanguage.googleapis.com/v1beta/models/gemini-2.0-flash:generateContent?key=$GEMINI_API_KEY" \ -H 'Content-Type: application/json' \ -X POST \ -d "@$TEMP_JSON" 2> /dev/null > response.json @@ -162,7 +162,7 @@ cat > "$TEMP_JSON" << EOF EOF # Make the API request using the JSON file -curl "https://generativelanguage.googleapis.com/v1beta/models/gemini-1.5-pro:generateContent?key=$GOOGLE_API_KEY" \ +curl "https://generativelanguage.googleapis.com/v1beta/models/gemini-2.0-flash:generateContent?key=$GEMINI_API_KEY" \ -H 'Content-Type: application/json' \ -X POST \ -d "@$TEMP_JSON" 2> /dev/null > response.json @@ -181,7 +181,7 @@ tmp_header_file=upload-header.tmp # Initial resumable request defining metadata. # The upload url is in the response headers dump them to a file. -curl "${BASE_URL}/upload/v1beta/files?key=${GOOGLE_API_KEY}" \ +curl "${BASE_URL}/upload/v1beta/files?key=${GEMINI_API_KEY}" \ -D upload-header.tmp \ -H "X-Goog-Upload-Protocol: resumable" \ -H "X-Goog-Upload-Command: start" \ @@ -203,7 +203,7 @@ curl "${upload_url}" \ file_uri=$(jq ".file.uri" file_info.json) echo file_uri=$file_uri -curl "https://generativelanguage.googleapis.com/v1beta/models/gemini-1.5-flash:generateContent?key=$GOOGLE_API_KEY" \ +curl "https://generativelanguage.googleapis.com/v1beta/models/gemini-2.0-flash:generateContent?key=$GEMINI_API_KEY" \ -H 'Content-Type: application/json' \ -X POST \ -d '{ @@ -231,7 +231,7 @@ tmp_header_file=upload-header.tmp # Initial resumable request defining metadata. # The upload url is in the response headers dump them to a file. -curl "${BASE_URL}/upload/v1beta/files?key=${GOOGLE_API_KEY}" \ +curl "${BASE_URL}/upload/v1beta/files?key=${GEMINI_API_KEY}" \ -D upload-header.tmp \ -H "X-Goog-Upload-Protocol: resumable" \ -H "X-Goog-Upload-Command: start" \ @@ -253,7 +253,7 @@ curl "${upload_url}" \ file_uri=$(jq ".file.uri" file_info.json) echo file_uri=$file_uri -curl "https://generativelanguage.googleapis.com/v1beta/models/gemini-1.5-flash:streamGenerateContent?alt=sse&key=$GOOGLE_API_KEY" \ +curl "https://generativelanguage.googleapis.com/v1beta/models/gemini-2.0-flash:streamGenerateContent?alt=sse&key=$GEMINI_API_KEY" \ -H 'Content-Type: application/json' \ -X POST \ -d '{ @@ -277,7 +277,7 @@ DISPLAY_NAME=VIDEO # Initial resumable request defining metadata. # The upload url is in the response headers dump them to a file. -curl "${BASE_URL}/upload/v1beta/files?key=${GOOGLE_API_KEY}" \ +curl "${BASE_URL}/upload/v1beta/files?key=${GEMINI_API_KEY}" \ -D "${tmp_header_file}" \ -H "X-Goog-Upload-Protocol: resumable" \ -H "X-Goog-Upload-Command: start" \ @@ -314,7 +314,7 @@ do state=$(jq ".file.state" file_info.json) done -curl "https://generativelanguage.googleapis.com/v1beta/models/gemini-1.5-flash:generateContent?key=$GOOGLE_API_KEY" \ +curl "https://generativelanguage.googleapis.com/v1beta/models/gemini-2.0-flash:generateContent?key=$GEMINI_API_KEY" \ -H 'Content-Type: application/json' \ -X POST \ -d '{ @@ -340,7 +340,7 @@ DISPLAY_NAME=VIDEO_PATH # Initial resumable request defining metadata. # The upload url is in the response headers dump them to a file. -curl "${BASE_URL}/upload/v1beta/files?key=${GOOGLE_API_KEY}" \ +curl "${BASE_URL}/upload/v1beta/files?key=${GEMINI_API_KEY}" \ -D upload-header.tmp \ -H "X-Goog-Upload-Protocol: resumable" \ -H "X-Goog-Upload-Command: start" \ @@ -374,7 +374,7 @@ do state=$(jq ".file.state" file_info.json) done -curl "https://generativelanguage.googleapis.com/v1beta/models/gemini-1.5-flash:streamGenerateContent?alt=sse&key=$GOOGLE_API_KEY" \ +curl "https://generativelanguage.googleapis.com/v1beta/models/gemini-2.0-flash:streamGenerateContent?alt=sse&key=$GEMINI_API_KEY" \ -H 'Content-Type: application/json' \ -X POST \ -d '{ @@ -401,7 +401,7 @@ tmp_header_file=upload-header.tmp # Initial resumable request defining metadata. # The upload url is in the response headers dump them to a file. -curl "${BASE_URL}/upload/v1beta/files?key=${GOOGLE_API_KEY}" \ +curl "${BASE_URL}/upload/v1beta/files?key=${GEMINI_API_KEY}" \ -D upload-header.tmp \ -H "X-Goog-Upload-Protocol: resumable" \ -H "X-Goog-Upload-Command: start" \ @@ -424,7 +424,7 @@ file_uri=$(jq ".file.uri" file_info.json) echo file_uri=$file_uri # Now generate content using that file -curl "https://generativelanguage.googleapis.com/v1beta/models/gemini-1.5-flash:generateContent?key=$GOOGLE_API_KEY" \ +curl "https://generativelanguage.googleapis.com/v1beta/models/gemini-2.0-flash:generateContent?key=$GEMINI_API_KEY" \ -H 'Content-Type: application/json' \ -X POST \ -d '{ @@ -453,7 +453,7 @@ tmp_header_file=upload-header.tmp # Initial resumable request defining metadata. # The upload url is in the response headers dump them to a file. -curl "${BASE_URL}/upload/v1beta/files?key=${GOOGLE_API_KEY}" \ +curl "${BASE_URL}/upload/v1beta/files?key=${GEMINI_API_KEY}" \ -D upload-header.tmp \ -H "X-Goog-Upload-Protocol: resumable" \ -H "X-Goog-Upload-Command: start" \ @@ -476,7 +476,7 @@ file_uri=$(jq ".file.uri" file_info.json) echo file_uri=$file_uri # Now generate content using that file -curl "https://generativelanguage.googleapis.com/v1beta/models/gemini-1.5-flash:streamGenerateContent?alt=sse&key=$GOOGLE_API_KEY" \ +curl "https://generativelanguage.googleapis.com/v1beta/models/gemini-2.0-flash:streamGenerateContent?alt=sse&key=$GEMINI_API_KEY" \ -H 'Content-Type: application/json' \ -X POST \ -d '{ @@ -489,4 +489,4 @@ curl "https://generativelanguage.googleapis.com/v1beta/models/gemini-1.5-flash:s cat response.json echo -# [END text_gen_multimodal_pdf_streaming] \ No newline at end of file +# [END text_gen_multimodal_pdf_streaming] diff --git a/samples/rest/tuned_models.sh b/samples/rest/tuned_models.sh index 5594734f6..0e32f97a0 100644 --- a/samples/rest/tuned_models.sh +++ b/samples/rest/tuned_models.sh @@ -2,7 +2,7 @@ set -eu echo "[START tuned_models_create]" # [START tuned_models_create] -curl -X POST "https://generativelanguage.googleapis.com/v1beta/tunedModels?key=$GOOGLE_API_KEY" \ +curl -X POST "https://generativelanguage.googleapis.com/v1beta/tunedModels?key=$GEMINI_API_KEY" \ -H 'Content-Type: application/json' \ -d ' { @@ -77,7 +77,7 @@ tuning_done=false while [[ "$tuning_done" != "true" ]]; do sleep 5 - curl -X GET "https://generativelanguage.googleapis.com/v1/${operation}?key=$GOOGLE_API_KEY" \ + curl -X GET "https://generativelanguage.googleapis.com/v1/${operation}?key=$GEMINI_API_KEY" \ -H 'Content-Type: application/json' \ 2> /dev/null > tuning_operation.json @@ -90,7 +90,7 @@ done # Or get the TunedModel and check it's state. The model is ready to use if the state is active. modelname=$(cat tunemodel.json | jq ".metadata.tunedModel" | tr -d '"') -curl -X GET https://generativelanguage.googleapis.com/v1beta/${modelname}?key=$GOOGLE_API_KEY \ +curl -X GET https://generativelanguage.googleapis.com/v1beta/${modelname}?key=$GEMINI_API_KEY \ -H 'Content-Type: application/json' > tuned_model.json cat tuned_model.json | jq ".state" @@ -99,7 +99,7 @@ cat tuned_model.json | jq ".state" echo "[START tuned_models_generate_content]" # [START tuned_models_generate_content] -curl -X POST https://generativelanguage.googleapis.com/v1beta/$modelname:generateContent?key=$GOOGLE_API_KEY \ +curl -X POST https://generativelanguage.googleapis.com/v1beta/$modelname:generateContent?key=$GEMINI_API_KEY \ -H 'Content-Type: application/json' \ -d '{ "contents": [{ @@ -112,7 +112,7 @@ curl -X POST https://generativelanguage.googleapis.com/v1beta/$modelname:generat echo "[START tuned_models_get]" # [START tuned_models_get] -curl -X GET https://generativelanguage.googleapis.com/v1beta/${modelname}?key=$GOOGLE_API_KEY \ +curl -X GET https://generativelanguage.googleapis.com/v1beta/${modelname}?key=$GEMINI_API_KEY \ -H 'Content-Type: application/json' | grep state # [END tuned_models_get] @@ -130,7 +130,7 @@ jq .tunedModels[].name < tuned_models.json page_token=$(jq .nextPageToken < tuned_models.json | tr -d '"') if [[ "$page_token" != "null"" ]]; then -curl -X GET https://generativelanguage.googleapis.com/v1beta/tunedModels?page_size=5\&page_token=${page_token}?key=$GOOGLE_API_KEY \ +curl -X GET https://generativelanguage.googleapis.com/v1beta/tunedModels?page_size=5\&page_token=${page_token}?key=$GEMINI_API_KEY \ -H "Content-Type: application/json" > tuned_models2.json jq .tunedModels[].name < tuned_models.json fi @@ -138,6 +138,6 @@ fi echo "[START tuned_models_delete]" # [START tuned_models_delete] -curl -X DELETE https://generativelanguage.googleapis.com/v1beta/${modelname}?key=$GOOGLE_API_KEY \ +curl -X DELETE https://generativelanguage.googleapis.com/v1beta/${modelname}?key=$GEMINI_API_KEY \ -H 'Content-Type: application/json' -# [END tuned_models_delete] \ No newline at end of file +# [END tuned_models_delete] From e0fb11798506d865d0fc36e13e2cbf5dba79e1c1 Mon Sep 17 00:00:00 2001 From: Amir Hardon Date: Tue, 18 Mar 2025 19:49:21 -0700 Subject: [PATCH 11/17] Add a GitHub Action to manage status: `awaiting user response` (#720) A new comment on an issue with this label would get the label automatically removed. --- .github/workflows/user-input.yml | 14 ++++++++++++++ 1 file changed, 14 insertions(+) create mode 100644 .github/workflows/user-input.yml diff --git a/.github/workflows/user-input.yml b/.github/workflows/user-input.yml new file mode 100644 index 000000000..632611296 --- /dev/null +++ b/.github/workflows/user-input.yml @@ -0,0 +1,14 @@ +name: Manage awaiting user response + +on: + issue_comment: + types: [created] + +jobs: + remove_label: + runs-on: ubuntu-latest + if: "contains(github.event.issue.labels.*.name, 'status: awaiting user response')" + steps: + - uses: actions-ecosystem/action-remove-labels@v1 + with: + labels: "status: awaiting user response" From 6bf45711adb41ece635954f6ebec66de16d29948 Mon Sep 17 00:00:00 2001 From: Mark McDonald Date: Wed, 19 Mar 2025 11:22:33 +0800 Subject: [PATCH 12/17] Pin actions to specific SHAs (#719) * Pin actions to specific SHAs * Update all the other workflows --- .github/workflows/labeler.yml | 2 +- .github/workflows/remove-issue-labels.yml | 2 +- .github/workflows/remove-pr-labels.yml | 2 +- .github/workflows/samples.yaml | 8 ++++---- .github/workflows/stale.yml | 2 +- .github/workflows/test_pr.yaml | 24 +++++++++++------------ 6 files changed, 20 insertions(+), 20 deletions(-) diff --git a/.github/workflows/labeler.yml b/.github/workflows/labeler.yml index 6dcd9ab15..19574ff0a 100644 --- a/.github/workflows/labeler.yml +++ b/.github/workflows/labeler.yml @@ -11,5 +11,5 @@ jobs: pull-requests: write runs-on: ubuntu-latest steps: - - uses: actions/labeler@v4 + - uses: actions/labeler@ac9175f8a1f3625fd0d4fb234536d26811351594 # v4 if: ${{ github.event.pull_request.draft == false }} diff --git a/.github/workflows/remove-issue-labels.yml b/.github/workflows/remove-issue-labels.yml index 43f43dd13..79783430d 100644 --- a/.github/workflows/remove-issue-labels.yml +++ b/.github/workflows/remove-issue-labels.yml @@ -11,7 +11,7 @@ jobs: issues: write runs-on: ubuntu-latest steps: - - uses: actions-ecosystem/action-remove-labels@v1 + - uses: actions-ecosystem/action-remove-labels@2ce5d41b4b6aa8503e285553f75ed56e0a40bae0 # v1 with: labels: | status:triaged diff --git a/.github/workflows/remove-pr-labels.yml b/.github/workflows/remove-pr-labels.yml index 3aed6ced7..64aeeaa64 100644 --- a/.github/workflows/remove-pr-labels.yml +++ b/.github/workflows/remove-pr-labels.yml @@ -11,7 +11,7 @@ jobs: pull-requests: write runs-on: ubuntu-latest steps: - - uses: actions-ecosystem/action-remove-labels@v1 + - uses: actions-ecosystem/action-remove-labels@2ce5d41b4b6aa8503e285553f75ed56e0a40bae0 # v1 with: labels: | status:awaiting review diff --git a/.github/workflows/samples.yaml b/.github/workflows/samples.yaml index 04f2611aa..6e5d45261 100644 --- a/.github/workflows/samples.yaml +++ b/.github/workflows/samples.yaml @@ -10,11 +10,11 @@ jobs: steps: - name: Checkout Code - uses: actions/checkout@v3 + uses: actions/checkout@f43a0e5ff2bd294095638e18286ca9a3d1956744 # v3 - name: Get Changed Files id: changed_files - uses: tj-actions/changed-files@v44 + uses: tj-actions/changed-files@2d756ea4c53f7f6b397767d8723b3a10a9f35bf2 # v44 with: files: | samples/*.py @@ -49,11 +49,11 @@ jobs: steps: - name: Checkout Code - uses: actions/checkout@v3 + uses: actions/checkout@f43a0e5ff2bd294095638e18286ca9a3d1956744 # v3 - name: Get Changed Files id: changed_files - uses: tj-actions/changed-files@v44 + uses: tj-actions/changed-files@2d756ea4c53f7f6b397767d8723b3a10a9f35bf2 # v44 with: files: | samples/rest/*.sh diff --git a/.github/workflows/stale.yml b/.github/workflows/stale.yml index df7d6c186..1f7710e5a 100644 --- a/.github/workflows/stale.yml +++ b/.github/workflows/stale.yml @@ -19,7 +19,7 @@ jobs: pull-requests: write steps: - - uses: actions/stale@v5 + - uses: actions/stale@f7176fd3007623b69d27091f9b9d4ab7995f0a06 # v5 with: repo-token: ${{ secrets.GITHUB_TOKEN }} days-before-issue-stale: 14 diff --git a/.github/workflows/test_pr.yaml b/.github/workflows/test_pr.yaml index 362a53e49..35f7c8fea 100644 --- a/.github/workflows/test_pr.yaml +++ b/.github/workflows/test_pr.yaml @@ -19,8 +19,8 @@ jobs: name: Test Py3.12 runs-on: ubuntu-latest steps: - - uses: actions/checkout@v3 - - uses: actions/setup-python@v4 + - uses: actions/checkout@f43a0e5ff2bd294095638e18286ca9a3d1956744 # v3 + - uses: actions/setup-python@65d7f2d534ac1bc67fcd62888c5f4f3d2cb2b236 # v4 with: python-version: '3.12' - name: Run tests @@ -32,8 +32,8 @@ jobs: name: Test Py3.11 runs-on: ubuntu-latest steps: - - uses: actions/checkout@v3 - - uses: actions/setup-python@v4 + - uses: actions/checkout@f43a0e5ff2bd294095638e18286ca9a3d1956744 # v3 + - uses: actions/setup-python@65d7f2d534ac1bc67fcd62888c5f4f3d2cb2b236 # v4 with: python-version: '3.11' - name: Run tests @@ -45,8 +45,8 @@ jobs: name: Test Py3.10 runs-on: ubuntu-latest steps: - - uses: actions/checkout@v3 - - uses: actions/setup-python@v4 + - uses: actions/checkout@f43a0e5ff2bd294095638e18286ca9a3d1956744 # v3 + - uses: actions/setup-python@65d7f2d534ac1bc67fcd62888c5f4f3d2cb2b236 # v4 with: python-version: '3.10' - name: Run tests @@ -58,8 +58,8 @@ jobs: name: Test Py3.9 runs-on: ubuntu-latest steps: - - uses: actions/checkout@v3 - - uses: actions/setup-python@v4 + - uses: actions/checkout@f43a0e5ff2bd294095638e18286ca9a3d1956744 # v3 + - uses: actions/setup-python@65d7f2d534ac1bc67fcd62888c5f4f3d2cb2b236 # v4 with: python-version: '3.9' - name: Run tests @@ -71,8 +71,8 @@ jobs: name: pytype 3.11 runs-on: ubuntu-latest steps: - - uses: actions/checkout@v3 - - uses: actions/setup-python@v4 + - uses: actions/checkout@f43a0e5ff2bd294095638e18286ca9a3d1956744 # v3 + - uses: actions/setup-python@65d7f2d534ac1bc67fcd62888c5f4f3d2cb2b236 # v4 with: python-version: '3.11' - name: Run pytype @@ -86,8 +86,8 @@ jobs: name: Check format with black runs-on: ubuntu-latest steps: - - uses: actions/checkout@v3 - - uses: actions/setup-python@v4 + - uses: actions/checkout@f43a0e5ff2bd294095638e18286ca9a3d1956744 # v3 + - uses: actions/setup-python@65d7f2d534ac1bc67fcd62888c5f4f3d2cb2b236 # v4 with: python-version: '3.11' - name: Check format From 29f85b8d4e05503fd52e963bd0b4981c6e4f1a2d Mon Sep 17 00:00:00 2001 From: Logan Kilpatrick Date: Fri, 21 Mar 2025 17:43:45 -0500 Subject: [PATCH 13/17] Update README.md --- README.md | 969 +----------------------------------------------------- 1 file changed, 5 insertions(+), 964 deletions(-) diff --git a/README.md b/README.md index 83c58c6f6..a743b5ebf 100644 --- a/README.md +++ b/README.md @@ -1,968 +1,9 @@ -# Google AI Python SDK for the Gemini API +# [Deprecated] Google AI Python SDK for the Gemini API -[![PyPI version](https://badge.fury.io/py/google-generativeai.svg)](https://badge.fury.io/py/google-generativeai) -![Python support](https://img.shields.io/pypi/pyversions/google-generativeai) -![PyPI - Downloads](https://img.shields.io/pypi/dd/google-generativeai) +With Gemini 2.0, we took the chance to create a single unified SDK for all developers who want to use Google's GenAI models (Gemini, Veo, Imagen, etc). As part of that process, we took all of the feedback from this SDK and what developers like about other SDKs in the ecosystem to create the [Google Gen AI SDK](https://github.com/googleapis/python-genai). -> [!IMPORTANT] -> From Gemini 2.0 onwards this SDK will no longer be -developing new features. Any new code should be written using the new SDK, `google-genai` ([github](https://github.com/googleapis/python-genai), -[pypi](https://pypi.org/project/google-genai/)). See the migration guide below to upgrade to the new SDK. +The full migration guide from the old SDK to new SDK is available in the [Gemini API docs](https://ai.google.dev/gemini-api/docs/migrate). -# Upgrade the Google GenAI SDK for Python - -With Gemini 2 we are offering a [new SDK](https://github.com/googleapis/python-genai) -([google-genai](https://pypi.org/project/google-genai/), -v1.0). The updated SDK is fully compatible with all Gemini API -models and features, including recent additions like the -[live API](https://aistudio.google.com/live) (audio + video streaming), -improved tool usage ( -[code execution](https://ai.google.dev/gemini-api/docs/code-execution?lang=python), -[function calling](https://ai.google.dev/gemini-api/docs/function-calling/tutorial?lang=python) and integrated -[Google search grounding](https://ai.google.dev/gemini-api/docs/grounding?lang=python)), -and media generation ([Imagen](https://ai.google.dev/gemini-api/docs/imagen)). -This SDK allows you to connect to the Gemini API through either -[Google AI Studio](https://aistudio.google.com/prompts/new_chat?model=gemini-2.0-flash-exp) or -[Vertex AI](https://cloud.google.com/vertex-ai/generative-ai/docs/gemini-v2). - -The [google-generativeai](https://pypi.org/project/google-generativeai) -package will continue to support the original Gemini models. -It can also be used with Gemini 2 models, just with a limited feature -set. All new features will be developed in the new Google GenAI SDK. - - - - - -
- - - Try the new SDK in Google Colab - -
-

- -## Install the SDK - -**Before** - -``` -pip install -U -q "google-generativeai" -``` - -**After** - -``` -pip install -U -q "google-genai" -``` - -## Authenticate - -Authenticate with API key. You can -[create](https://aistudio.google.com/app/apikey) -your API key using Google AI studio. - - -The old SDK implicitly handled the API client object behind the scenes. In the -new SDK you create the API client and use it to call the API. - -Remember, in either case the SDK will pick -up your API key from the `GOOGLE_API_KEY` environment variable if you don't pass -one to `configure`/`Client`. - -
export GOOGLE_API_KEY=...
- -**Before** - -```python -import google.generativeai as genai - -genai.configure(api_key=...) -``` - -**After** - -```python -from google import genai - -client = genai.Client(api_key=...) -``` - -## Generate content - -The new SDK provides access to all the API methods through the `Client` object. -Except for a few stateful special cases (`chat`, live-api `session`s) these are all -stateless functions. For utility and uniformity objects returned are `pydantic` -classes. - -**Before** - -```python -import google.generativeai as genai - -model = genai.GenerativeModel('gemini-1.5-flash') -response = model.generate_content( - 'Tell me a story in 300 words' -) -print(response.text) -``` - -**After** - -```python -from google import genai -client = genai.Client() - -response = client.models.generate_content( - model='gemini-2.0-flash', - contents='Tell me a story in 300 words.' -) -print(response.text) - -print(response.model_dump_json( - exclude_none=True, indent=4)) -``` - - -Many of the same convenience features exist in the new SDK. For example -`PIL.Image` objects are automatically converted: - -**Before** - -```python -import google.generativeai as genai - -model = genai.GenerativeModel('gemini-1.5-flash') -response = model.generate_content([ - 'Tell me a story based on this image', - Image.open(image_path) -]) -print(response.text) -``` - -**After** - -```python -from google import genai -from PIL import Image - -client = genai.Client() - -response = client.models.generate_content( - model='gemini-2.0-flash', - contents=[ - 'Tell me a story based on this image', - Image.open(image_path) - ] -) -print(response.text) -``` - - -### Streaming - -Streaming methods are each separate functions named with a `_stream` suffix. - -**Before** - -```python -import google.generativeai as genai - -response = model.generate_content( - "Write a cute story about cats.", - stream=True) -for chunk in response: - print(chunk.text) -``` - -**After** - -```python -from google import genai -client = genai.Client() - -for chunk in client.models.generate_content_stream( - model='gemini-2.0-flash', - contents='Tell me a story in 300 words.' -): - print(chunk.text) -``` - - -## Optional arguments - -For all methods in the new SDK the required arguments are provided as keyword -arguments. All optional inputs are provided in the `config` argument. - -The `config` can always be passed as a dictionary or, for better autocomplete and -stricter typing, each method has a `Config` class in the `google.genai.types` -module. For utility and uniformity, everything in the `types` module is defined -as a `pydantic` class. - -**Before** - -```python -import google.generativeai as genai - -model = genai.GenerativeModel( - 'gemini-1.5-flash', - system_instruction='you are a story teller for kids under 5 years old', - generation_config=genai.GenerationConfig( - max_output_tokens=400, - top_k=2, - top_p=0.5, - temperature=0.5, - response_mime_type='application/json', - stop_sequences=['\n'], - ) -) -response = model.generate_content('tell me a story in 100 words') - -``` - -**After** - -```python -from google import genai -from google.genai import types -client = genai.Client() - -response = client.models.generate_content( - model='gemini-2.0-flash', - contents='Tell me a story in 100 words.', - config=types.GenerateContentConfig( - system_instruction='you are a story teller for kids under 5 years old', - max_output_tokens= 400, - top_k= 2, - top_p= 0.5, - temperature= 0.5, - response_mime_type= 'application/json', - stop_sequences= ['\n'], - seed=42, - ), -) -``` - - -### Example: Safety settings - -Generate response with safety settings: - -**Before** - -```python -import google.generativeai as genai - -model = genai.GenerativeModel('gemini-1.5-flash') -response = model.generate_content( - 'say something bad', - safety_settings={ - 'HATE': 'BLOCK_ONLY_HIGH', - 'HARASSMENT': 'BLOCK_ONLY_HIGH', - } -) -``` - -**After** - -```python -from google import genai -from google.genai import types -client = genai.Client() - -response = client.models.generate_content( - model='gemini-2.0-flash', - contents='say something bad', - config=types.GenerateContentConfig( - safety_settings= [ - types.SafetySetting( - category='HARM_CATEGORY_HATE_SPEECH', - threshold='BLOCK_ONLY_HIGH' - ), - ] - ), -) -``` - - -## Async - -To use the new SDK with `asyncio`, there is a separate `async` implementation of -every method under `client.aio`. - -**Before** - -```python -import google.generativeai as genai - -model = genai.GenerativeModel('gemini-1.5-flash') -response = model.generate_content_async( - 'tell me a story in 100 words' -) -``` - -**After** - -```python -from google import genai -client = genai.Client() - -response = await client.aio.models.generate_content( - model='gemini-2.0-flash', - contents='Tell me a story in 300 words.' -) -``` - -## Chat - -Starts a chat and sends a message to the model: - -**Before** - -```python -import google.generativeai as genai - -model = genai.GenerativeModel('gemini-1.5-flash') -chat = model.start_chat() - -response = chat.send_message( - "Tell me a story in 100 words") -response = chat.send_message( - "What happened after that?") -``` - -**After** - -```python -from google import genai -client = genai.Client() - -chat = client.chats.create(model='gemini-2.0-flash') - -response = chat.send_message( - message='Tell me a story in 100 words') -response = chat.send_message( - message='What happened after that?') -``` - - -## Function calling - -In the New SDK, automatic function calling is the default. Here we disable it. - -**Before** - -```python -import google.generativeai as genai -from enum import Enum - -def get_current_weather(location: str) -> str: - """Get the current whether in a given location. - - Args: - location: required, The city and state, e.g. San Franciso, CA - unit: celsius or fahrenheit - """ - print(f'Called with: {location=}') - return "23C" - -model = genai.GenerativeModel( - model_name="gemini-1.5-flash", - tools=[get_current_weather] -) - -response = model.generate_content("What is the weather in San Francisco?") -function_call = response.candidates[0].parts[0].function_call -``` - -**After** - -```python -from google import genai -from google.genai import types -client = genai.Client() - -def get_current_weather(location: str) -> str: - """Get the current whether in a given location. - - Args: - location: required, The city and state, e.g. San Franciso, CA - unit: celsius or fahrenheit - """ - print(f'Called with: {location=}') - return "23C" - -response = client.models.generate_content( - model='gemini-2.0-flash', - contents="What is the weather like in Boston?", - config=types.GenerateContentConfig( - tools=[get_current_weather], - automatic_function_calling={'disable': True}, - ), -) - -function_call = response.candidates[0].content.parts[0].function_call -``` - -### Automatic function calling - -The old SDK only supports automatic function calling in chat. In the new SDK -this is the default behavior in `generate_content`. - -**Before** - -```python -import google.generativeai as genai - -def get_current_weather(city: str) -> str: - return "23C" - -model = genai.GenerativeModel( - model_name="gemini-1.5-flash", - tools=[get_current_weather] -) - -chat = model.start_chat( - enable_automatic_function_calling=True) -result = chat.send_message("What is the weather in San Francisco?") -``` - -**After** - -```python -from google import genai -from google.genai import types -client = genai.Client() - -def get_current_weather(city: str) -> str: - return "23C" - -response = client.models.generate_content( - model='gemini-2.0-flash', - contents="What is the weather like in Boston?", - config=types.GenerateContentConfig( - tools=[get_current_weather] - ), -) -``` - -## Code execution - -Code execution is a tool that allows the model to generate Python code, run it, -and return the result. - -**Before** - -```python -import google.generativeai as genai - -model = genai.GenerativeModel( - model_name="gemini-1.5-flash", - tools="code_execution" -) - -result = model.generate_content( - "What is the sum of the first 50 prime numbers? Generate and run code for " - "the calculation, and make sure you get all 50.") -``` - -**After** - -```python -from google import genai -from google.genai import types -client = genai.Client() - -response = client.models.generate_content( - model='gemini-2.0-flash', - contents='What is the sum of the first 50 prime numbers? Generate and run ' - 'code for the calculation, and make sure you get all 50.', - config=types.GenerateContentConfig( - tools=[types.Tool(code_execution=types.CodeExecution())], - ), -) -``` - -## Search grounding - -`GoogleSearch` (Gemini>=2.0) and `GoogleSearchRetrieval` (Gemini < 2.0) are tools -that allow the model to retrieve public web data for grounding, powered by Google. - -**Before** - -```python -import google.generativeai as genai - -model = genai.GenerativeModel('gemini-1.5-flash') -response = model.generate_content( - contents="what is the Google stock price?", - tools='google_search_retrieval' -) -``` - -**After** - -```python -from google import genai -from google.genai import types -client = genai.Client() - -response = client.models.generate_content( - model='gemini-2.0-flash', - contents='What is the Google stock price?', - config=types.GenerateContentConfig( - tools=[ - types.Tool( - google_search=types.GoogleSearch() - ) - ] - ) -) -``` - -## JSON response - -Generate answers in JSON format. - -By specifying a `response_schema` and setting -`response_mime_type="application/json"` users can constrain the model to produce a -`JSON` response following a given structure. The new SDK uses `pydantic` classes -to provide the schema (although you can pass a `genai.types.Schema`, or equivalent -`dict`). When possible, the SDK will parse the returned JSON, and return the -result in `response.parsed`. If you provided a `pydantic` class as the schema the -SDK will convert that `JSON` to an instance of the class. - -**Before** - -```python -import google.generativeai as genai -import typing_extensions as typing - -class CountryInfo(typing.TypedDict): - name: str - population: int - capital: str - continent: str - major_cities: list[str] - gdp: int - official_language: str - total_area_sq_mi: int - -model = genai.GenerativeModel(model_name="gemini-1.5-flash") -result = model.generate_content( - "Give me information of the United States", - generation_config=genai.GenerationConfig( - response_mime_type="application/json", - response_schema = CountryInfo - ), -) - -``` - -**After** - -```python -from google import genai -from pydantic import BaseModel -client = genai.Client() - -class CountryInfo(BaseModel): - name: str - population: int - capital: str - continent: str - major_cities: list[str] - gdp: int - official_language: str - total_area_sq_mi: int - -response = client.models.generate_content( - model='gemini-2.0-flash', - contents='Give me information of the United States.', - config={ - 'response_mime_type': 'application/json', - 'response_schema': CountryInfo, - }, - ) - -response.parsed -``` - -## Files - -### Upload - -Upload a file: - -**Before** - -```python -import requests -import pathlib -import google.generativeai as genai - -# Download file -response = requests.get( - 'https://storage.googleapis.com/generativeai-downloads/data/a11.txt') -pathlib.Path('a11.txt').write_text(response.text) - -file = genai.upload_file(path='a11.txt') - -model = genai.GenerativeModel('gemini-1.5-flash') -response = model.generate_content([ - 'Can you summarize this file:', - my_file -]) -print(response.text) -``` - -**After** - -```python -import requests -import pathlib -from google import genai -client = genai.Client() - -# Download file -response = requests.get( - 'https://storage.googleapis.com/generativeai-downloads/data/a11.txt') -pathlib.Path('a11.txt').write_text(response.text) - -my_file = client.files.upload(file='a11.txt') - -response = client.models.generate_content( - model='gemini-2.0-flash', - contents=[ - 'Can you summarize this file:', - my_file - ] -) -print(response.text) -``` - -### List and get - -List uploaded files and get an uploaded file with a file name: - -**Before** - -```python -import google.generativeai as genai - -for file in genai.list_files(): - print(file.name) - -file = genai.get_file(name=file.name) -``` - -**After** - -```python -from google import genai -client = genai.Client() - -for file in client.files.list(): - print(file.name) - -file = client.files.get(name=file.name) -``` - - -### Delete - -Delete a file: - -**Before** - -```python -import pathlib -import google.generativeai as genai - -pathlib.Path('dummy.txt').write_text(dummy) -dummy_file = genai.upload_file(path='dummy.txt') - -file = genai.delete_file(name=dummy_file.name) -``` - -**After** - -```python -import pathlib -from google import genai -client = genai.Client() - -pathlib.Path('dummy.txt').write_text(dummy) -dummy_file = client.files.upload(file='dummy.txt') - -response = client.files.delete(name=dummy_file.name) -``` - - -## Context caching - -Context caching allows the user to pass the content to the model once, cache the -input tokens, and then refer to the cached tokens in subsequent calls to lower the -cost. - -**Before** - -```python -import requests -import pathlib -import google.generativeai as genai -from google.generativeai import caching - -# Download file -response = requests.get( - 'https://storage.googleapis.com/generativeai-downloads/data/a11.txt') -pathlib.Path('a11.txt').write_text(response.text) - - -# Upload file -document = genai.upload_file(path="a11.txt") - -# Create cache -apollo_cache = caching.CachedContent.create( - model="gemini-1.5-flash-001", - system_instruction="You are an expert at analyzing transcripts.", - contents=[document], -) - -# Generate response -apollo_model = genai.GenerativeModel.from_cached_content( - cached_content=apollo_cache -) -response = apollo_model.generate_content("Find a lighthearted moment from this transcript") -``` - -**After** - -```python -import requests -import pathlib -from google import genai -from google.genai import types -client = genai.Client() - -# Check which models support caching. -for m in client.models.list(): - for action in m.supported_actions: - if action == "createCachedContent": - print(m.name) - break - -# Download file -response = requests.get( - 'https://storage.googleapis.com/generativeai-downloads/data/a11.txt') -pathlib.Path('a11.txt').write_text(response.text) - - -# Upload file -document = client.files.upload(file='a11.txt') - -# Create cache -model='gemini-1.5-flash-001' -apollo_cache = client.caches.create( - model=model, - config={ - 'contents': [document], - 'system_instruction': 'You are an expert at analyzing transcripts.', - }, - ) - -# Generate response -response = client.models.generate_content( - model=model, - contents='Find a lighthearted moment from this transcript', - config=types.GenerateContentConfig( - cached_content=apollo_cache.name, - ) -) -``` - -## Count tokens - -Count the number of tokens in a request. - -**Before** - -```python -import google.generativeai as genai - -model = genai.GenerativeModel('gemini-1.5-flash') -response = model.count_tokens( - 'The quick brown fox jumps over the lazy dog.') - -``` - -**After** - -```python -from google import genai -client = genai.Client() - -response = client.models.count_tokens( - model='gemini-2.0-flash', - contents='The quick brown fox jumps over the lazy dog.', -) -``` - -## Generate images - -Generate images: - -**Before** - -```python -#pip install https://github.com/google-gemini/generative-ai-python@imagen -import google.generativeai as genai - -imagen = genai.ImageGenerationModel( - "imagen-3.0-generate-001") -gen_images = imagen.generate_images( - prompt="Robot holding a red skateboard", - number_of_images=1, - safety_filter_level="block_only_high", - person_generation="allow_adult", - aspect_ratio="3:4", - negative_prompt="Outside", -) -``` - -**After** - -```python -from google import genai -client = genai.Client() - -gen_images = client.models.generate_image( - model='imagen-3.0-generate-001', - prompt='Robot holding a red skateboard', - config=types.GenerateImageConfig( - number_of_images= 1, - safety_filter_level= "BLOCK_ONLY_HIGH", - person_generation= "ALLOW_ADULT", - aspect_ratio= "3:4", - negative_prompt= "Outside", - ) -) - -for n, image in enumerate(gen_images.generated_images): - pathlib.Path(f'{n}.png').write_bytes( - image.image.image_bytes) -``` - - -## Embed content - -Generate content embeddings. - -**Before** - -```python -import google.generativeai as genai - -response = genai.embed_content( - model='models/text-embedding-004', - content='Hello world' -) -``` - -**After** - -```python -from google import genai -client = genai.Client() - -response = client.models.embed_content( - model='text-embedding-004', - contents='Hello world', -) -``` - -## Tune a Model - -Create and use a tuned model. - -The new SDK simplifies tuning with `client.tunings.tune`, which launches the -tuning job and polls until the job is complete. - -**Before** - -```python -import google.generativeai as genai -import random - -# create tuning model -train_data = {} -for i in range(1, 6): - key = f'input {i}' - value = f'output {i}' - train_data[key] = value - -name = f'generate-num-{random.randint(0,10000)}' -operation = genai.create_tuned_model( - source_model='models/gemini-1.5-flash-001-tuning', - training_data=train_data, - id = name, - epoch_count = 5, - batch_size=4, - learning_rate=0.001, -) -# wait for tuning complete -tuningProgress = operation.result() - -# generate content with the tuned model -model = genai.GenerativeModel(model_name=f'tunedModels/{name}') -response = model.generate_content('55') -``` - -**After** - -```python -from google import genai -from google.genai import types - -client = genai.Client() - -# Check which models are available for tuning. -for m in client.models.list(): - for action in m.supported_actions: - if action == "createTunedModel": - print(m.name) - break - -# create tuning model -training_dataset=types.TuningDataset( - examples=[ - types.TuningExample( - text_input=f'input {i}', - output=f'output {i}', - ) - for i in range(5) - ], - ) -tuning_job = client.tunings.tune( - base_model='models/gemini-1.5-flash-001-tuning', - training_dataset=training_dataset, - config=types.CreateTuningJobConfig( - epoch_count= 5, - batch_size=4, - learning_rate=0.001, - tuned_model_display_name="test tuned model" - ) -) - -# generate content with the tuned model -response = client.models.generate_content( - model=tuning_job.tuned_model.model, - contents='55', -) -``` +We won't be adding anything to this SDK or making any further changes. The Gemini API docs are fully updated to show examples of the new Google Gen AI SDK. We know how disruptive an SDK change can be and don't take this change lightly, but our goal is to create an extremely simple and clear path for developers to build with our models so it felt necessary to make this change. +Thank you for building with Gemini and [let us know](https://discuss.ai.google.dev/c/gemini-api/4) if you need any help! From d66e975be1793f085ebd313bab0f9ad0a2a88cfa Mon Sep 17 00:00:00 2001 From: David Huntsperger <5672572+pcoet@users.noreply.github.com> Date: Mon, 24 Mar 2025 19:07:18 -0700 Subject: [PATCH 14/17] Update README.md (#722) Add comment back to README, to unbreak API ref build. --- README.md | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/README.md b/README.md index a743b5ebf..23f2308f6 100644 --- a/README.md +++ b/README.md @@ -7,3 +7,10 @@ The full migration guide from the old SDK to new SDK is available in the [Gemini We won't be adding anything to this SDK or making any further changes. The Gemini API docs are fully updated to show examples of the new Google Gen AI SDK. We know how disruptive an SDK change can be and don't take this change lightly, but our goal is to create an extremely simple and clear path for developers to build with our models so it felt necessary to make this change. Thank you for building with Gemini and [let us know](https://discuss.ai.google.dev/c/gemini-api/4) if you need any help! + + From 61867f68149a63fd0cf3c37bd46177a75ec5d8ed Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 27 Mar 2025 10:44:54 -0700 Subject: [PATCH 15/17] Bump tj-actions/changed-files from 44 to 46 in /.github/workflows (#721) Bumps [tj-actions/changed-files](https://github.com/tj-actions/changed-files) from 44 to 46. - [Release notes](https://github.com/tj-actions/changed-files/releases) - [Changelog](https://github.com/tj-actions/changed-files/blob/main/HISTORY.md) - [Commits](https://github.com/tj-actions/changed-files/compare/v44...v46) --- updated-dependencies: - dependency-name: tj-actions/changed-files dependency-type: direct:production ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/samples.yaml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/samples.yaml b/.github/workflows/samples.yaml index 6e5d45261..8a3dc6462 100644 --- a/.github/workflows/samples.yaml +++ b/.github/workflows/samples.yaml @@ -14,7 +14,7 @@ jobs: - name: Get Changed Files id: changed_files - uses: tj-actions/changed-files@2d756ea4c53f7f6b397767d8723b3a10a9f35bf2 # v44 + uses: tj-actions/changed-files@2f7c5bfce28377bc069a65ba478de0a74aa0ca32 # v44 with: files: | samples/*.py @@ -53,7 +53,7 @@ jobs: - name: Get Changed Files id: changed_files - uses: tj-actions/changed-files@2d756ea4c53f7f6b397767d8723b3a10a9f35bf2 # v44 + uses: tj-actions/changed-files@2f7c5bfce28377bc069a65ba478de0a74aa0ca32 # v44 with: files: | samples/rest/*.sh From e179614c3144360e3fa2b34fba6eb13398ea98a7 Mon Sep 17 00:00:00 2001 From: Annie Luc Date: Sun, 13 Apr 2025 21:32:06 -0700 Subject: [PATCH 16/17] chore: Update user-input.yml GitHub workflow to trigger on PR comments (#723) --- .github/workflows/user-input.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.github/workflows/user-input.yml b/.github/workflows/user-input.yml index 632611296..0aa0d6512 100644 --- a/.github/workflows/user-input.yml +++ b/.github/workflows/user-input.yml @@ -3,6 +3,8 @@ name: Manage awaiting user response on: issue_comment: types: [created] + pull_request_review_comment: + types: [created] jobs: remove_label: From f5ac4edfb8ba67384e767b257079fb3038ac1ab2 Mon Sep 17 00:00:00 2001 From: Mark Daoust Date: Wed, 16 Apr 2025 11:30:39 -0700 Subject: [PATCH 17/17] Update version and fix samples for 0.8.5 release (#731) * Update version and fix samples for 0.8.5 release Change-Id: Ie0b0f883cbe5c8e5427c1d59c1b96bea0dd62fde * Fix samples for 0.8.5 release Change-Id: I48f3389565d68bc10f1608980298e6f1e384fc37 * format Change-Id: Ibfe397dc19d055867bb8c0e87f9ba107867e4289 * Fix shawoding caused by an empty GEMINI_API_KEY Change-Id: I1df220253baf1b2171891ba380a0a3dde8e09a8b * fix failing tests Change-Id: I0fdfc084e8c5e88bab8257eef22065ec5a6189ea * fix tests broken by pydantic 2.11 Change-Id: Ie697e2f43b2608cadebfd14d806f3898b064cc3b * format Change-Id: I51110cf338bd61d8cf40b3e73ece12b34c951d0c * sync readme with https://github.com/google-gemini/deprecated-generative-ai-js/pull/462 Change-Id: I6bc43a471b5558f373f6c514a9dc56a49dd9e677 * JS -> Python Change-Id: Ib7aee25dfa0d94fc3c4abd55c28a36211126e883 * patch responder instead of deleting. Change-Id: I8f010a0ff5e45009ce9114d6bfc025e5774c2004 --- README.md | 12 +- google/generativeai/client.py | 4 +- google/generativeai/responder.py | 195 ++++++++++++---- google/generativeai/types/content_types.py | 14 ++ google/generativeai/version.py | 2 +- samples/tuned_models.py | 31 +-- setup.py | 6 +- tests/test_client.py | 36 +++ tests/test_responder.py | 255 --------------------- 9 files changed, 238 insertions(+), 317 deletions(-) delete mode 100644 tests/test_responder.py diff --git a/README.md b/README.md index 23f2308f6..e31c5ffbb 100644 --- a/README.md +++ b/README.md @@ -4,10 +4,20 @@ With Gemini 2.0, we took the chance to create a single unified SDK for all devel The full migration guide from the old SDK to new SDK is available in the [Gemini API docs](https://ai.google.dev/gemini-api/docs/migrate). -We won't be adding anything to this SDK or making any further changes. The Gemini API docs are fully updated to show examples of the new Google Gen AI SDK. We know how disruptive an SDK change can be and don't take this change lightly, but our goal is to create an extremely simple and clear path for developers to build with our models so it felt necessary to make this change. +The Gemini API docs are fully updated to show examples of the new Google Gen AI SDK. We know how disruptive an SDK change can be and don't take this change lightly, but our goal is to create an extremely simple and clear path for developers to build with our models so it felt necessary to make this change. Thank you for building with Gemini and [let us know](https://discuss.ai.google.dev/c/gemini-api/4) if you need any help! +**Please be advised that this repository is now considered legacy.** For the latest features, performance improvements, and active development, we strongly recommend migrating to the official **[Google Generative AI SDK for Python](https://github.com/googleapis/python-genai)**. + +**Support Plan for this Repository:** + +* **Limited Maintenance:** Development is now restricted to **critical bug fixes only**. No new features will be added. +* **Purpose:** This limited support aims to provide stability for users while they transition to the new SDK. +* **End-of-Life Date:** All support for this repository (including bug fixes) will permanently end on **August 31st, 2025**. + +We encourage all users to begin planning their migration to the [Google Generative AI SDK](https://github.com/googleapis/python-genai) to ensure continued access to the latest capabilities and support. +