diff --git a/.github/workflows/docs.yml b/.github/workflows/docs.yml new file mode 100644 index 000000000..902632b35 --- /dev/null +++ b/.github/workflows/docs.yml @@ -0,0 +1,78 @@ +# Builds the API reference (https://googleapis.github.io/python-genai/) with the +# pinned Sphinx in docs/requirements.txt and publishes it to GitHub Pages. +# +# Run by hand from the Actions tab for now, from main: the github-pages +# environment only accepts deployments from main. Publishing also needs the +# repository's Pages source set to "GitHub Actions"; until then, leave "deploy" +# unchecked to build the site and download it as an artifact. +name: Docs + +on: + workflow_dispatch: + inputs: + ref: + description: Tag or branch to build. Tags from before this workflow have no docs/source. + required: true + default: main + deploy: + description: Publish to GitHub Pages + type: boolean + default: false + +permissions: + contents: read + +jobs: + build: + runs-on: ubuntu-latest + steps: + - name: Checkout code + uses: actions/checkout@v4 + with: + ref: ${{ inputs.ref }} + + - name: Set up Python + uses: actions/setup-python@v5 + with: + python-version: '3.12' + + - name: Install dependencies + run: | + python -m pip install --upgrade pip + pip install -r requirements.txt -r docs/requirements.txt + + - name: Build + # The docs import `genai` from the checkout, as build_and_copy_docs.sh + # does from its copy in docs/google. custom.css is copied in first, as + # that script does. The doctree cache goes outside the site, so it is + # not published. + env: + PYTHONPATH: ${{ github.workspace }}/google + run: | + mkdir -p _site/_static/css + cp docs/source/custom.css _site/_static/css/custom.css + sphinx-build -b html -d "$RUNNER_TEMP/doctrees" docs/source _site + + - name: Upload the site + uses: actions/upload-pages-artifact@v3 + with: + path: _site + + deploy: + if: inputs.deploy + needs: build + runs-on: ubuntu-latest + # One deployment at a time; builds can run side by side. + concurrency: + group: pages + cancel-in-progress: false + permissions: + pages: write + id-token: write + environment: + name: github-pages + url: ${{ steps.deployment.outputs.page_url }} + steps: + - name: Publish to GitHub Pages + id: deployment + uses: actions/deploy-pages@v4 diff --git a/docs/requirements.txt b/docs/requirements.txt new file mode 100644 index 000000000..82a50c1b6 --- /dev/null +++ b/docs/requirements.txt @@ -0,0 +1,6 @@ +absl-py==2.1.0 +autodoc_pydantic==2.2.0 +furo==2025.09.25 +myst-parser==4.0.1 +sphinx==8.2.3 +sphinx-autodoc-typehints==3.2.0 diff --git a/docs/source/conf.py b/docs/source/conf.py new file mode 100644 index 000000000..0c48bfdff --- /dev/null +++ b/docs/source/conf.py @@ -0,0 +1,69 @@ +# Configuration file for the Sphinx documentation builder. +# +# For the full list of built-in configuration values, see the documentation: +# https://www.sphinx-doc.org/en/master/usage/configuration.html + +# -- Project information ----------------------------------------------------- +# https://www.sphinx-doc.org/en/master/usage/configuration.html#project-information + +project = 'Google Gen AI SDK' +copyright = '2024, Google' +author = 'Google' + +# -- General configuration --------------------------------------------------- +# https://www.sphinx-doc.org/en/master/usage/configuration.html#general-configuration + +extensions = [] + +templates_path = ['_templates'] +exclude_patterns = ['_build', 'Thumbs.db', '.DS_Store'] + +autoclass_content = 'both' + +# -- Options for HTML output ------------------------------------------------- +# https://www.sphinx-doc.org/en/master/usage/configuration.html#options-for-html-output + +html_static_path = ['_static'] + +import html +import os +import sys +sys.path.insert(0, os.path.abspath('.')) # Add current directory to path +sys.path.insert(0, os.path.abspath('../google')) + +extensions = ['sphinxcontrib.autodoc_pydantic', 'myst_parser', 'sphinx.ext.autodoc', 'sphinx_autodoc_typehints', 'sphinx.ext.napoleon'] +html_theme = 'furo' + +TEXT_FONTS = '"Google Sans Text", Roboto, "Helvetica Neue", Helvetica, Arial, sans-serif' +CODE_FONTS = 'Roboto Mono, "Helvetica Neue Mono", monospace' +FONT_COLOR_FOR_LIGHT_THEME = 'black' +FONT_COLOR_FOR_DARK_THEME = 'white' + +html_theme_options = { + "light_css_variables": { + "font-stack": TEXT_FONTS, + "font-stack--monospace": CODE_FONTS, + "font-stack--headings": TEXT_FONTS, + "color-brand-primary": FONT_COLOR_FOR_LIGHT_THEME, + "color-brand-content": FONT_COLOR_FOR_LIGHT_THEME, + }, + "dark_css_variables": { + "font-stack": TEXT_FONTS, + "font-stack--monospace": CODE_FONTS, + "font-stack--headings": TEXT_FONTS, + "color-brand-primary": FONT_COLOR_FOR_DARK_THEME, + "color-brand-content": FONT_COLOR_FOR_DARK_THEME, + }, +} + +# These folders are copied to the documentation's HTML output +html_static_path = ['_static'] + +# These paths are either relative to html_static_path +# or fully qualified paths (eg. https://...) +html_css_files = [ + 'css/custom.css', +] + +autodoc_pydantic_model_show_json = True +autodoc_pydantic_model_show_config_summary = False diff --git a/docs/source/custom.css b/docs/source/custom.css new file mode 100644 index 000000000..90b794f25 --- /dev/null +++ b/docs/source/custom.css @@ -0,0 +1,33 @@ +@import url('https://fonts.googleapis.com/css?family=Google+Sans:400,500|Roboto:400,400italic,500,500italic,700,700italic|Roboto+Mono:400,500,700&display=swap'); + +body { + font-weight: 400; +} + +h1 { + font-size: 32px; + font-weight: 400; +} + +h2 { + font-size: 24px; + font-weight: 400; +} + +h3 { + font-size: 20px; + font-weight: 400; +} + +h4 { + font-size: 16px; + font-weight: 400; +} + +.sidebar-brand-text { + font-size: 14px; +} + +.highlight { + box-shadow: 0 2px 2px 0 rgba(0,0,0,0.14), 0 3px 1px -2px rgba(0,0,0,0.12), 0 1px 5px 0 rgba(0,0,0,0.2); +} \ No newline at end of file diff --git a/docs/source/genai.rst b/docs/source/genai.rst new file mode 100644 index 000000000..41fa05a20 --- /dev/null +++ b/docs/source/genai.rst @@ -0,0 +1,108 @@ +Submodules +---------- + +genai.client module +------------------- + +.. automodule:: genai.client + :members: + :undoc-members: + :show-inheritance: + + +GAOS Client Resources +^^^^^^^^^^^^^^^^^^^^^ + +The following resource classes are returned by the client properties +``client.interactions``, ``client.agents``, ``client.webhooks``, +``client.triggers``, and ``client.environments``. + +.. autoclass:: genai._gaos.google_genai.GeminiNextGenInteractions + :members: + :undoc-members: + :show-inheritance: + +.. autoclass:: genai._gaos.google_genai.AsyncGeminiNextGenInteractions + :members: + :undoc-members: + :show-inheritance: + +.. autoclass:: genai._gaos.google_genai.GeminiNextGenAgents + :members: + :undoc-members: + :show-inheritance: + +.. autoclass:: genai._gaos.google_genai.AsyncGeminiNextGenAgents + :members: + :undoc-members: + :show-inheritance: + +.. autoclass:: genai._gaos.google_genai.GeminiNextGenWebhooks + :members: + :undoc-members: + :show-inheritance: + +.. autoclass:: genai._gaos.google_genai.AsyncGeminiNextGenWebhooks + :members: + :undoc-members: + :show-inheritance: + +.. autoclass:: genai._gaos.google_genai.GeminiNextGenTriggers + :members: + :undoc-members: + :show-inheritance: + +.. autoclass:: genai._gaos.google_genai.AsyncGeminiNextGenTriggers + :members: + :undoc-members: + :show-inheritance: + +.. autoclass:: genai._gaos.google_genai.GeminiNextGenEnvironments + :members: + :undoc-members: + :show-inheritance: + +.. autoclass:: genai._gaos.google_genai.AsyncGeminiNextGenEnvironments + :members: + :undoc-members: + :show-inheritance: + +genai.live module +----------------- + +.. automodule:: genai.live + :members: + :undoc-members: + :show-inheritance: + +genai.models module +------------------- + +.. automodule:: genai.models + :members: + :undoc-members: + :show-inheritance: + +genai.tokens module +------------------- + +.. automodule:: genai.tokens + :members: + :undoc-members: + :show-inheritance: + +genai.tunings module +-------------------- + +.. automodule:: genai.tunings + :members: + :undoc-members: + :show-inheritance: + +genai.types module +------------------ + +.. automodule:: genai.types + :members: + :undoc-members: + :show-inheritance: diff --git a/docs/source/index.rst b/docs/source/index.rst new file mode 100644 index 000000000..a285fcf80 --- /dev/null +++ b/docs/source/index.rst @@ -0,0 +1,2126 @@ +Google Gen AI SDK +================= + +|pypi| |pyversions| |pydownloads| + +**Documentation:** ``_ + +``_ + +.. |pypi| image:: https://img.shields.io/pypi/v/google-genai.svg + :target: https://pypi.org/project/google-genai/ +.. |pyversions| image:: https://img.shields.io/pypi/pyversions/google-genai + :target: https://pypi.org/project/google-genai/ +.. |pydownloads| image:: https://img.shields.io/pypi/dw/google-genai + :target: https://pypistats.org/packages/google-genai + +Google Gen AI Python SDK provides an interface for developers to integrate +Google's generative models into their Python applications. It supports the +`Gemini Developer API `_ and +`Gemini Enterprise Agent Platform API `_ +APIs. + +Installation +------------ + +.. code:: shell + + pip install google-genai + +With `uv`: + +.. code:: shell + + uv pip install google-genai + + +Imports +------- + +.. code:: python + + from google import genai + from google.genai import types + +Create a client +--------------- + +Please run one of the following code blocks to create a client for +different services (`Gemini Developer API `_ or `Gemini Enterprise Agent Platform API `_). + +.. code:: python + + from google import genai + + # Only run this block for Gemini Developer API + client = genai.Client(api_key='GEMINI_API_KEY') + +.. code:: python + + from google import genai + + # Only run this block for Gemini Enterprise Agent Platform API + client = genai.Client( + enterprise=True, project='your-project-id', location='us-central1' + ) + + +**(Optional) Using environment variables:** + +You can create a client by configuring the necessary environment variables. +Configuration setup instructions depends on whether you're using the Gemini +Developer API or the Gemini API in Gemini Enterprise Agent Platform. + +**Gemini Developer API:** Set the `GEMINI_API_KEY` or `GOOGLE_API_KEY`. +It will automatically be picked up by the client. It's recommended that you +set only one of those variables, but if both are set, `GOOGLE_API_KEY` takes +precedence. + +.. code:: bash + + export GEMINI_API_KEY='your-api-key' + + +**Gemini API on Gemini Enterprise Agent Platform:** Set `GOOGLE_GENAI_USE_ENTERPRISE`, +`GOOGLE_CLOUD_PROJECT` and `GOOGLE_CLOUD_LOCATION`, as shown below: + +.. code:: bash + + export GOOGLE_GENAI_USE_ENTERPRISE=true + export GOOGLE_CLOUD_PROJECT='your-project-id' + export GOOGLE_CLOUD_LOCATION='us-central1' + + +.. code:: python + + from google import genai + + client = genai.Client() + + +Close a client +^^^^^^^^^^^^^^ + +Explicitly close the sync client to ensure that resources, such as the +underlying HTTP connections, are properly cleaned up and closed. + +.. code:: python + + from google.genai import Client + + client = Client() + response_1 = client.models.generate_content( + model=MODEL_ID, + contents='Hello', + ) + response_2 = client.models.generate_content( + model=MODEL_ID, + contents='Ask a question', + ) + # Close the sync client to release resources. + client.close() + + +To explicitly close the async client: + +.. code:: python + + from google.genai import Client + + aclient = Client( + enterprise=True, project='my-project-id', location='us-central1' + ).aio + response_1 = await aclient.models.generate_content( + model=MODEL_ID, + contents='Hello', + ) + response_2 = await aclient.models.generate_content( + model=MODEL_ID, + contents='Ask a question', + ) + # Close the async client to release resources. + await aclient.aclose() + + +Client context managers +^^^^^^^^^^^^^^^^^^^^^^^ + +By using the sync client context manager, it will close the underlying +sync client when exiting the with block. + +.. code:: python + + from google.genai import Client + + with Client() as client: + response_1 = client.models.generate_content( + model=MODEL_ID, + contents='Hello', + ) + response_2 = client.models.generate_content( + model=MODEL_ID, + contents='Ask a question', + ) + + +By using the async client context manager, it will close the underlying +async client when exiting the with block. + + +.. code:: python + + from google.genai import Client + + async with Client().aio as aclient: + response_1 = await aclient.models.generate_content( + model=MODEL_ID, + contents='Hello', + ) + response_2 = await aclient.models.generate_content( + model=MODEL_ID, + contents='Ask a question', + ) + + +API Selection +^^^^^^^^^^^^^ + +By default, the SDK uses the beta API endpoints provided by Google to support preview features in the APIs. The stable API endpoints can be selected by setting the API version to `v1`. + +To set the API version use ``http_options``. For example, to set the API version to ``v1`` for Gemini Enterprise Agent Platform API: + +.. code:: python + + from google import genai + from google.genai import types + + client = genai.Client( + enterprise=True, + project='your-project-id', + location='us-central1', + http_options=types.HttpOptions(api_version='v1') + ) + +To set the API version to `v1alpha` for the Gemini Developer API: + +.. code:: python + + from google import genai + from google.genai import types + + # Only run this block for Gemini Developer API + client = genai.Client( + api_key='GEMINI_API_KEY', + http_options=types.HttpOptions(api_version='v1alpha') + ) + + +Faster async client option: Aiohttp +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +By default we use httpx for both sync and async client implementations. In order +to have faster performance, you may install `google-genai[aiohttp]`. In Gen AI +SDK we configure `trust_env=True` to match with the default behavior of httpx. +Additional args of `aiohttp.ClientSession.request()` +(`see _RequestOptions args `_) +can be passed through the following way: + +.. code:: python + + http_options = types.HttpOptions( + async_client_args={'cookies': ..., 'ssl': ...}, + ) + + client=Client(..., http_options=http_options) + + +Proxy +^^^^^^^ + +Both httpx and aiohttp libraries use `urllib.request.getproxies` from +environment variables. Before client initialization, you may set proxy (and +optional SSL_CERT_FILE) by setting the environment variables: + + +.. code:: bash + + export HTTPS_PROXY='http://username:password@proxy_uri:port' + export SSL_CERT_FILE='client.pem' + + +If you need `socks5` proxy, httpx `supports `_ +`socks5` proxy if you pass it via args to httpx.Client(). You may install +`httpx[socks]` to use it. Then you can pass it through the following way: + +.. code:: python + + http_options = types.HttpOptions( + client_args={'proxy': 'socks5://user:pass@host:port'}, + async_client_args={'proxy': 'socks5://user:pass@host:port'}, + ) + + client=Client(..., http_options=http_options) + + +Custom base url +^^^^^^^^^^^^^^^ + +In some cases you might need a custom base url (for example, API gateway proxy +server) and bypass some authentication checks for project, location, or API key. +You may pass the custom base url like this: + +.. code:: python + + base_url = 'https://test-api-gateway-proxy.com' + client = Client( + enterprise=True, # Currently only enterprise=True is supported. + http_options={ + 'base_url': base_url, + 'headers': {'Authorization': 'Bearer test_token'}, + }, + ) + + +Types +----- + +Parameter types can be specified as either dictionaries(``TypedDict``) or `Pydantic Models `_. +Pydantic model types are available in the ``types`` module. + +Models +====== + +The ``client.models`` modules exposes model inferencing and model +getters. See the 'Create a client' section above to initialize a client. + +Generate Content +---------------- + +with text content input (text output) +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +.. code:: python + + response = client.models.generate_content( + model='gemini-flash-latest', contents='Why is the sky blue?' + ) + print(response.text) + + +with text content input (image output) +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +.. code:: python + + from google.genai import types + + response = client.models.generate_content( + model='gemini-3.1-flash-lite-image', + contents='A cartoon infographic for flying sneakers', + config=types.GenerateContentConfig( + response_modalities=["IMAGE"], + image_config=types.ImageConfig( + aspect_ratio="9:16", + ), + ), + ) + + for part in response.parts: + if part.inline_data: + generated_image = part.as_image() + generated_image.show() + + +with text content input (audio / speech output) +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +.. code:: python + + from google.genai import types + + response = client.models.generate_content( + model='gemini-3.8-flash-tts', + contents='Give me a cheerful greeting.', + config=types.GenerateContentConfig( + response_modalities=['AUDIO'], + speech_config=types.SpeechConfig( + voice_config=types.VoiceConfig( + prebuilt_voice_config=types.PrebuiltVoiceConfig( + voice_name='Aoede' + ) + ) + ), + ), + ) + + for part in response.parts: + if part.inline_data: + with open('greeting.wav', 'wb') as f: + f.write(part.inline_data.data) + + +with uploaded file (Gemini Developer API only) +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +download the file in console. + +.. code:: console + + !wget -q https://storage.googleapis.com/generativeai-downloads/data/a11.txt + +python code. + +.. code:: python + + file = client.files.upload(file='a11.txt') + response = client.models.generate_content( + model='gemini-flash-latest', + contents=['Could you summarize this file?', file] + ) + print(response.text) + + +How to structure `contents` argument for `generate_content` +^^^^^^^^^^^^^^^^^^^^^^^^^^^ +The SDK always converts the inputs to the `contents` argument into +`list[types.Content]`. +The following shows some common ways to provide your inputs. + +Provide a `list[types.Content]` +"""""""""""""""""""""""""""""" +This is the canonical way to provide contents, SDK will not do any conversion. + +Provide a `types.Content` instance +"""""""""""""""""""""""""""""" + +.. code:: python + + from google.genai import types + + contents = types.Content( + role='user', + parts=[types.Part.from_text(text='Why is the sky blue?')] + ) + +SDK converts this to + +.. code:: python + + [ + types.Content( + role='user', + parts=[types.Part.from_text(text='Why is the sky blue?')] + ) + ] + +Provide a string +"""""""""""""""""" + +.. code:: python + + contents='Why is the sky blue?' + +The SDK will assume this is a text part, and it converts this into the following: + +.. code:: python + + [ + types.UserContent( + parts=[ + types.Part.from_text(text='Why is the sky blue?') + ] + ) + ] + +Where a `types.UserContent` is a subclass of `types.Content`, it sets the +`role` field to be `user`. + +Provide a list of string +"""""""""""""""""""""""" + +.. code:: python + + contents=['Why is the sky blue?', 'Why is the cloud white?'] + +The SDK assumes these are 2 text parts, it converts this into a single content, +like the following: + +.. code:: python + + [ + types.UserContent( + parts=[ + types.Part.from_text(text='Why is the sky blue?'), + types.Part.from_text(text='Why is the cloud white?'), + ] + ) + ] + +Where a `types.UserContent` is a subclass of `types.Content`, the +`role` field in `types.UserContent` is fixed to be `user`. + +Provide a function call part +"""""""""""""""""""""""""" + +.. code:: python + + from google.genai import types + + contents = types.Part.from_function_call( + name='get_weather_by_location', + args={'location': 'Boston'} + ) + +The SDK converts a function call part to a content with a `model` role: + +.. code:: python + + [ + types.ModelContent( + parts=[ + types.Part.from_function_call( + name='get_weather_by_location', + args={'location': 'Boston'} + ) + ] + ) + ] + +Where a `types.ModelContent` is a subclass of `types.Content`, the +`role` field in `types.ModelContent` is fixed to be `model`. + +Provide a list of function call parts +"""""""""""""""""""""""""""""" + +.. code:: python + + from google.genai import types + + contents = [ + types.Part.from_function_call( + name='get_weather_by_location', + args={'location': 'Boston'} + ), + types.Part.from_function_call( + name='get_weather_by_location', + args={'location': 'New York'} + ), + ] + +The SDK converts a list of function call parts to the a content with a `model` role: + +.. code:: python + + [ + types.ModelContent( + parts=[ + types.Part.from_function_call( + name='get_weather_by_location', + args={'location': 'Boston'} + ), + types.Part.from_function_call( + name='get_weather_by_location', + args={'location': 'New York'} + ) + ] + ) + ] + +Where a `types.ModelContent` is a subclass of `types.Content`, the +`role` field in `types.ModelContent` is fixed to be `model`. + +Provide a non function call part +"""""""""""""""""""""""" + +.. code:: python + + from google.genai import types + + contents = types.Part.from_uri( + file_uri: 'gs://generativeai-downloads/images/scones.jpg', + mime_type: 'image/jpeg', + ) + +The SDK converts all non function call parts into a content with a `user` role. + +.. code:: python + + [ + types.UserContent(parts=[ + types.Part.from_uri( + file_uri: 'gs://generativeai-downloads/images/scones.jpg', + mime_type: 'image/jpeg', + ) + ]) + ] + +Provide a list of non function call parts +"""""""""""""""""""" + +.. code:: python + + from google.genai import types + + contents = [ + types.Part.from_text('What is this image about?'), + types.Part.from_uri( + file_uri: 'gs://generativeai-downloads/images/scones.jpg', + mime_type: 'image/jpeg', + ) + ] + +The SDK will convert the list of parts into a content with a `user` role + +.. code:: python + + [ + types.UserContent( + parts=[ + types.Part.from_text('What is this image about?'), + types.Part.from_uri( + file_uri: 'gs://generativeai-downloads/images/scones.jpg', + mime_type: 'image/jpeg', + ) + ] + ) + ] + +Mix types in contents +"""""""""""""""""""""""""" +You can also provide a list of `types.ContentUnion`. The SDK leaves items of +`types.Content` as is, it groups consecutive non function call parts into a +single `types.UserContent`, and it groups consecutive function call parts into +a single `types.ModelContent`. + +If you put a list within a list, the inner list can only contain +`types.PartUnion` items. The SDK will convert the inner list into a single +`types.UserContent`. + + +System Instructions and Other Configs +------------------------------------- + +The output of the model can be influenced by several optional settings +available in generate_content's config parameter. For example, increasing +`max_output_tokens` is essential for longer model responses. To make a model more +deterministic, lowering the `temperature` parameter reduces randomness, with +values near 0 minimizing variability. Capabilities and parameter defaults for +each model is shown in the +`Gemini Enterprise Agent Platform docs `_ +and `Gemini API docs `_ respectively. + +.. code:: python + + from google.genai import types + + response = client.models.generate_content( + model='gemini-flash-latest', + contents='high', + config=types.GenerateContentConfig( + system_instruction='I say high, you say low', + max_output_tokens=3, + temperature=0.3, + ), + ) + print(response.text) + +Typed Config +------------ + +All API methods support Pydantic types for parameters as well as +dictionaries. You can get the type from ``google.genai.types``. + +.. code:: python + + from google.genai import types + + response = client.models.generate_content( + model='gemini-flash-latest', + contents=types.Part.from_text(text='Why is the sky blue?'), + config=types.GenerateContentConfig( + temperature=0, + top_p=0.95, + top_k=20, + candidate_count=1, + seed=5, + max_output_tokens=100, + stop_sequences=['STOP!'], + presence_penalty=0.0, + frequency_penalty=0.0, + ), + ) + + print(response.text) + +List Base Models +---------------- + +To retrieve tuned models, see: :ref:`List Tuned Models` + +.. code:: python + + for model in client.models.list(): + print(model) + +.. code:: python + + pager = client.models.list(config={'page_size': 10}) + print(pager.page_size) + print(pager[0]) + pager.next_page() + print(pager[0]) + +List Base Models (Asynchronous) +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +.. code:: python + + async for job in await client.aio.models.list(): + print(job) + +.. code:: python + + async_pager = await client.aio.models.list(config={'page_size': 10}) + print(async_pager.page_size) + print(async_pager[0]) + await async_pager.next_page() + print(async_pager[0]) + +Safety Settings +--------------- + +.. code:: python + + from google.genai import types + + response = client.models.generate_content( + model='gemini-flash-latest', + contents='Say something bad.', + config=types.GenerateContentConfig( + safety_settings=[ + types.SafetySetting( + category='HARM_CATEGORY_HATE_SPEECH', + threshold='BLOCK_ONLY_HIGH', + ) + ] + ), + ) + print(response.text) + +Function Calling +---------------- + +Automatic Python function Support: +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +You can pass a Python function directly and it will be automatically +called and responded by default. + +.. code:: python + + from google.genai import types + + def get_current_weather(location: str) -> str: + """Returns the current weather. + + Args: + location: The city and state, e.g. San Francisco, CA + """ + return 'sunny' + + + response = client.models.generate_content( + model='gemini-flash-latest', + contents='What is the weather like in Boston?', + config=types.GenerateContentConfig( + tools=[get_current_weather], + ), + ) + + print(response.text) + +Disabling automatic function calling +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +If you pass in a python function as a tool directly, and do not want +automatic function calling, you can disable automatic function calling +as follows: + +.. code:: python + + from google.genai import types + + response = client.models.generate_content( + model='gemini-flash-latest', + contents='What is the weather like in Boston?', + config=types.GenerateContentConfig( + tools=[get_current_weather], + automatic_function_calling=types.AutomaticFunctionCallingConfig( + disable=True + ), + ), + ) + +With automatic function calling disabled, you will get a list of function call +parts in the response: + +.. code:: python + + function_calls: Optional[List[types.FunctionCall]] = response.function_calls + + +Manually declare and invoke a function for function calling +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +If you don't want to use the automatic function support, you can manually +declare the function and invoke it. + +The following example shows how to declare a function and pass it as a tool. +Then you will receive a function call part in the response. + +.. code:: python + + from google.genai import types + + function = types.FunctionDeclaration( + name='get_current_weather', + description='Get the current weather in a given location', + parameters_json_schema={ + 'type': 'object', + 'properties': { + 'location': { + 'type': 'string', + 'description': 'The city and state, e.g. San Francisco, CA', + } + }, + 'required': ['location'], + }, + ) + + tool = types.Tool(function_declarations=[function]) + + response = client.models.generate_content( + model='gemini-flash-latest', + contents='What is the weather like in Boston?', + config=types.GenerateContentConfig( + tools=[tool], + ), + ) + print(response.function_calls[0]) + +After you receive the function call part from the model, you can invoke the function +and get the function response. And then you can pass the function response to +the model. +The following example shows how to do it for a simple function invocation. + +.. code:: python + + from google.genai import types + + user_prompt_content = types.Content( + role='user', + parts=[types.Part.from_text(text='What is the weather like in Boston?')], + ) + function_call_part = response.function_calls[0] + function_call_content = response.candidates[0].content + + + try: + function_result = get_current_weather( + **function_call_part.function_call.args + ) + function_response = {'result': function_result} + except ( + Exception + ) as e: # instead of raising the exception, you can let the model handle it + function_response = {'error': str(e)} + + + function_response_part = types.Part.from_function_response( + name=function_call_part.name, + response=function_response, + ) + function_response_content = types.Content( + role='tool', parts=[function_response_part] + ) + + response = client.models.generate_content( + model='gemini-flash-latest', + contents=[ + user_prompt_content, + function_call_content, + function_response_content, + ], + config=types.GenerateContentConfig( + tools=[tool], + ), + ) + + print(response.text) + + +Function calling with ``ANY`` tools config mode +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +If you configure function calling mode to be `ANY`, then the model will always +return function call parts. If you also pass a python function as a tool, by +default the SDK will perform automatic function calling until the remote calls +exceed the maximum remote call for automatic function calling (default to 10 times). + +If you'd like to disable automatic function calling in `ANY` mode: + +.. code-block:: python + + from google.genai import types + + def get_current_weather(location: str) -> str: + """Returns the current weather. + + Args: + location: The city and state, e.g. San Francisco, CA + """ + return "sunny" + + response = client.models.generate_content( + model="gemini-flash-latest", + contents="What is the weather like in Boston?", + config=types.GenerateContentConfig( + tools=[get_current_weather], + automatic_function_calling=types.AutomaticFunctionCallingConfig( + disable=True + ), + tool_config=types.ToolConfig( + function_calling_config=types.FunctionCallingConfig(mode='ANY') + ), + ), + ) + +If you'd like to set ``x`` number of automatic function call turns, you can +configure the maximum remote calls to be ``x + 1``. +Assuming you prefer ``1`` turn for automatic function calling: + +.. code-block:: python + + from google.genai import types + + def get_current_weather(location: str) -> str: + """Returns the current weather. + + Args: + location: The city and state, e.g. San Francisco, CA + """ + return "sunny" + + response = client.models.generate_content( + model="gemini-flash-latest", + contents="What is the weather like in Boston?", + config=types.GenerateContentConfig( + tools=[get_current_weather], + automatic_function_calling=types.AutomaticFunctionCallingConfig( + maximum_remote_calls=2 + ), + tool_config=types.ToolConfig( + function_calling_config=types.FunctionCallingConfig(mode='ANY') + ), + ), + ) + +Model Context Protocol (MCP) support (experimental) +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +Built-in `MCP `_ support is an +experimental feature. You can pass a local MCP server as a tool directly. + +.. code:: python + + import os + import asyncio + from datetime import datetime + from mcp import ClientSession, StdioServerParameters + from mcp.client.stdio import stdio_client + from google import genai + + client = genai.Client() + + # Create server parameters for stdio connection + server_params = StdioServerParameters( + command="npx", # Executable + args=["-y", "@philschmid/weather-mcp"], # MCP Server + env=None, # Optional environment variables + ) + + async def run(): + async with stdio_client(server_params) as (read, write): + async with ClientSession(read, write) as session: + # Prompt to get the weather for the current day in London. + prompt = f"What is the weather in London in {datetime.now().strftime('%Y-%m-%d')}?" + + # Initialize the connection between client and server + await session.initialize() + + # Send request to the model with MCP function declarations + response = await client.aio.models.generate_content( + model="gemini-flash-latest", + contents=prompt, + config=genai.types.GenerateContentConfig( + temperature=0, + tools=[session], # uses the session, will automatically call the tool using automatic function calling + ), + ) + print(response.text) + + # Start the asyncio event loop and run the main function + asyncio.run(run()) + + +JSON Response Schema +-------------------- + +However you define your schema, don't duplicate it in your input prompt, +including by giving examples of expected JSON output. If you do, the generated +output might be lower in quality. + +JSON Schema support +^^^^^^^^^^^^^^^^^^^ + +Schemas can be provided as standard JSON schema. + +.. code:: python + + user_profile = { + 'properties': { + 'age': { + 'anyOf': [ + {'maximum': 20, 'minimum': 0, 'type': 'integer'}, + {'type': 'null'}, + ], + 'title': 'Age', + }, + 'username': { + 'description': "User's unique name", + 'title': 'Username', + 'type': 'string', + }, + }, + 'required': ['username', 'age'], + 'title': 'User Schema', + 'type': 'object', + } + + response = client.models.generate_content( + model='gemini-flash-latest', + contents='Give me a random user profile.', + config={ + 'response_mime_type': 'application/json', + 'response_json_schema': user_profile + }, + ) + print(response.parsed) + + +Pydantic Model Schema support +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +Schemas can be provided as Pydantic Models. + +.. code:: python + + from pydantic import BaseModel + from google.genai import types + + + class CountryInfo(BaseModel): + name: str + population: int + capital: str + continent: str + gdp: int + official_language: str + total_area_sq_mi: int + + + response = client.models.generate_content( + model='gemini-flash-latest', + contents='Give me information for the United States.', + config=types.GenerateContentConfig( + response_mime_type='application/json', + response_schema=CountryInfo, + ), + ) + print(response.text) + +.. code:: python + + from google.genai import types + + response = client.models.generate_content( + model='gemini-flash-latest', + contents='Give me information for the United States.', + config=types.GenerateContentConfig( + response_mime_type='application/json', + response_schema={ + 'required': [ + 'name', + 'population', + 'capital', + 'continent', + 'gdp', + 'official_language', + 'total_area_sq_mi', + ], + 'properties': { + 'name': {'type': 'STRING'}, + 'population': {'type': 'INTEGER'}, + 'capital': {'type': 'STRING'}, + 'continent': {'type': 'STRING'}, + 'gdp': {'type': 'INTEGER'}, + 'official_language': {'type': 'STRING'}, + 'total_area_sq_mi': {'type': 'INTEGER'}, + }, + 'type': 'OBJECT', + }, + ), + ) + print(response.text) + +Enum Response Schema +-------------------- + +Text Response +^^^^^^^^^^^^^^ + +You can set ``response_mime_type`` to ``'text/x.enum'`` to return one of those enum +values as the response. + +.. code:: python + + from enum import Enum + + class InstrumentEnum(Enum): + PERCUSSION = 'Percussion' + STRING = 'String' + WOODWIND = 'Woodwind' + BRASS = 'Brass' + KEYBOARD = 'Keyboard' + + response = client.models.generate_content( + model='gemini-flash-latest', + contents='What instrument plays multiple notes at once?', + config={ + 'response_mime_type': 'text/x.enum', + 'response_schema': InstrumentEnum, + }, + ) + print(response.text) + +JSON Response +^^^^^^^^^^^^^^ + +You can also set ``response_mime_type`` to ``'application/json'``, the response will be +identical but in quotes. + +.. code:: python + + from enum import Enum + + class InstrumentEnum(Enum): + PERCUSSION = 'Percussion' + STRING = 'String' + WOODWIND = 'Woodwind' + BRASS = 'Brass' + KEYBOARD = 'Keyboard' + + response = client.models.generate_content( + model='gemini-flash-latest', + contents='What instrument plays multiple notes at once?', + config={ + 'response_mime_type': 'application/json', + 'response_schema': InstrumentEnum, + }, + ) + print(response.text) + +Generate Content (Synchronous Streaming) +---------------------------------------- + +Generate content in a streaming format so that the model outputs streams back +to you, rather than being returned as one chunk. + +Streaming for text content +^^^^^^^^^^^^^^^^^^^^^^^^^^ + +.. code:: python + + for chunk in client.models.generate_content_stream( + model='gemini-flash-latest', contents='Tell me a story in 300 words.' + ): + print(chunk.text, end='') + +Streaming for image content +^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +If your image is stored in `Google Cloud Storage `_, you can use the ``from_uri`` class method to create a ``Part`` object. + +.. code:: python + + from google.genai import types + + for chunk in client.models.generate_content_stream( + model='gemini-flash-latest', + contents=[ + 'What is this image about?', + types.Part.from_uri( + file_uri='gs://generativeai-downloads/images/scones.jpg', + mime_type='image/jpeg', + ), + ], + ): + print(chunk.text, end='') + + +If your image is stored in your local file system, you can read it in as bytes +data and use the ``from_bytes`` class method to create a ``Part`` object. + +.. code:: python + + from google.genai import types + + YOUR_IMAGE_PATH = 'your_image_path' + YOUR_IMAGE_MIME_TYPE = 'your_image_mime_type' + with open(YOUR_IMAGE_PATH, 'rb') as f: + image_bytes = f.read() + + for chunk in client.models.generate_content_stream( + model='gemini-flash-latest', + contents=[ + 'What is this image about?', + types.Part.from_bytes(data=image_bytes, mime_type=YOUR_IMAGE_MIME_TYPE), + ], + ): + print(chunk.text, end='') + +Generate Content (Asynchronous Non Streaming) +--------------------------------------------- + +``client.aio`` exposes all the analogous `async methods `_ that are available on ``client``. +Note that it applies to all the modules. + +For example, ``client.aio.models.generate_content`` is the ``async`` version of ``client.models.generate_content`` + +.. code:: python + + response = await client.aio.models.generate_content( + model='gemini-flash-latest', contents='Tell me a story in 300 words.' + ) + + print(response.text) + +Generate Content (Asynchronous Streaming) +----------------------------------------- + +.. code:: python + + async for chunk in await client.aio.models.generate_content_stream( + model='gemini-flash-latest', contents='Tell me a story in 300 words.' + ): + print(chunk.text, end='') + +Count Tokens and Compute Tokens +------------------------------- + +.. code:: python + + response = client.models.count_tokens( + model='gemini-flash-latest', + contents='why is the sky blue?', + ) + print(response) + +Compute Tokens +^^^^^^^^^^^^^^ + +Compute tokens is only supported in Gemini Enterprise Agent Platform. + +.. code:: python + + response = client.models.compute_tokens( + model='gemini-flash-latest', + contents='why is the sky blue?', + ) + print(response) + +Count Tokens (Asynchronous) +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +.. code:: python + + response = await client.aio.models.count_tokens( + model='gemini-flash-latest', + contents='why is the sky blue?', + ) + print(response) + +Local Count Tokens +^^^^^^^^^^^^^^^^^^ + +.. code:: python + from google.genai import local_tokenizer + + tokenizer = local_tokenizer.LocalTokenizer(model_name='gemini-2.5-flash') + result = tokenizer.count_tokens("What is your name?") + + +Local Compute Tokens +^^^^^^^^^^^^^^^^^^^^ + +.. code:: python + from google.genai import local_tokenizer + + tokenizer = local_tokenizer.LocalTokenizer(model_name='gemini-2.5-flash') + result = tokenizer.compute_tokens("What is your name?") + + +Embed Content +------------- + +.. code:: python + + response = client.models.embed_content( + model='gemini-embedding-001', + contents='why is the sky blue?', + ) + print(response) + +.. code:: python + + from google.genai import types + + # multiple contents with config + response = client.models.embed_content( + model='gemini-embedding-001', + contents=['why is the sky blue?', 'What is your age?'], + config=types.EmbedContentConfig(output_dimensionality=10), + ) + + print(response) + +Imagen +------ + +Generate Images +^^^^^^^^^^^^^^^ + +Support for generate images in Gemini Developer API is behind an allowlist + +.. code:: python + + from google.genai import types + + # Generate Image + response1 = client.models.generate_images( + model='imagen-4.0-generate-001', + prompt='An umbrella in the foreground, and a rainy night sky in the background', + config=types.GenerateImagesConfig( + number_of_images=1, + include_rai_reason=True, + output_mime_type='image/jpeg', + ), + ) + response1.generated_images[0].image.show() + +Upscale Image +^^^^^^^^^^^^^ + +Upscale image is only supported in Gemini Enterprise Agent Platform. + +.. code:: python + + from google.genai import types + + # Upscale the generated image from above + response2 = client.models.upscale_image( + model='imagen-4.0-upscale-preview', + image=response1.generated_images[0].image, + upscale_factor='x2', + config=types.UpscaleImageConfig( + include_rai_reason=True, + output_mime_type='image/jpeg', + ), + ) + response2.generated_images[0].image.show() + +Edit Image +^^^^^^^^^^^ + +Edit image uses a separate model from generate and upscale. + +Edit image is only supported in Gemini Enterprise Agent Platform. + +.. code:: python + + # Edit the generated image from above + from google.genai import types + from google.genai.types import RawReferenceImage, MaskReferenceImage + + raw_ref_image = RawReferenceImage( + reference_id=1, + reference_image=response1.generated_images[0].image, + ) + + # Model computes a mask of the background + mask_ref_image = MaskReferenceImage( + reference_id=2, + config=types.MaskReferenceConfig( + mask_mode='MASK_MODE_BACKGROUND', + mask_dilation=0, + ), + ) + + response3 = client.models.edit_image( + model='imagen-3.0-capability-001', + prompt='Sunlight and clear sky', + reference_images=[raw_ref_image, mask_ref_image], + config=types.EditImageConfig( + edit_mode='EDIT_MODE_INPAINT_INSERTION', + number_of_images=1, + include_rai_reason=True, + output_mime_type='image/jpeg', + ), + ) + response3.generated_images[0].image.show() + +Veo +------ +Support for generating videos is considered public preview + +Generate Videos (Text to Video) +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +.. code:: python + + from google.genai import types + + # Create operation + operation = client.models.generate_videos( + model='veo-3.1-generate-preview', + source=types.GenerateVideosSource( + prompt='A neon hologram of a cat driving at top speed', + ), + config=types.GenerateVideosConfig( + number_of_videos=1, + duration_seconds=5, + enhance_prompt=True, + ), + ) + + # Poll operation + while not operation.done: + time.sleep(20) + operation = client.operations.get(operation) + + video = operation.response.generated_videos[0].video + video.show() + + +Generate Videos (Image to Video) +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +.. code:: python + + from google.genai import types + + # Read local image (uses mimetypes.guess_type to infer mime type) + image = types.Image.from_file(location="local/path/file.png") + + # Create operation + operation = client.models.generate_videos( + model='veo-3.1-generate-preview', + source=types.GenerateVideosSource( + # Prompt is optional if image is provided + prompt='Night sky', + image=image, + ), + config=types.GenerateVideosConfig( + number_of_videos=1, + duration_seconds=5, + enhance_prompt=True, + # Can also pass an Image into last_frame for frame interpolation + ), + ) + + # Poll operation + while not operation.done: + time.sleep(20) + operation = client.operations.get(operation) + + video = operation.response.generated_videos[0].video + video.show() + + +Generate Videos (Video to Video) +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +Currently, only Gemini Enterprise Agent Platform supports Video to Video generation (Video extension). + + +.. code:: python + + from google.genai import types + + # Read local video (uses mimetypes.guess_type to infer mime type) + video = types.Video.from_file("local/path/video.mp4") + + # Create operation + operation = client.models.generate_videos( + model='veo-3.1-generate-preview', + source=types.GenerateVideosSource( + # Prompt is optional if Video is provided + prompt='Night sky', + # Input video must be in GCS + video=types.Video( + uri="gs://bucket-name/inputs/videos/cat_driving.mp4", + ), + ), + config=types.GenerateVideosConfig( + number_of_videos=1, + duration_seconds=5, + enhance_prompt=True, + ), + ) + + # Poll operation + while not operation.done: + time.sleep(20) + operation = client.operations.get(operation) + + video = operation.response.generated_videos[0].video + video.show() + + +Chats +===== + +Create a chat session to start a multi-turn conversations with the model. Then, +use `chat.send_message` function multiple times within the same chat session so +that it can reflect on its previous responses (i.e., engage in an ongoing +conversation). See the 'Create a client' section above to initialize a client. + +Send Message (Synchronous Non-Streaming) +---------------------------------------- + +.. code:: python + + chat = client.chats.create(model='gemini-flash-latest') + response = chat.send_message('tell me a story') + print(response.text) + response = chat.send_message('summarize the story you told me in 1 sentence') + print(response.text) + +Send Message (Synchronous Streaming) +------------------------------------ + +.. code:: python + + chat = client.chats.create(model='gemini-flash-latest') + for chunk in chat.send_message_stream('tell me a story'): + print(chunk.text) + +Send Message (Asynchronous Non-Streaming) +----------------------------------------- + +.. code:: python + + chat = client.aio.chats.create(model='gemini-flash-latest') + response = await chat.send_message('tell me a story') + print(response.text) + +Send Message (Asynchronous Streaming) +------------------------------------- + +.. code:: python + + chat = client.aio.chats.create(model='gemini-flash-latest') + async for chunk in await chat.send_message_stream('tell me a story'): + print(chunk.text) + +Files +====================== + +Files are only supported in Gemini Developer API. See the 'Create a client' +section above to initialize a client. + +.. code:: console + + gcloud storage cp gs://cloud-samples-data/generative-ai/pdf/2312.11805v3.pdf . + gcloud storage cp gs://cloud-samples-data/generative-ai/pdf/2403.05530.pdf . + +Upload +------ + +.. code:: python + + file1 = client.files.upload(file='2312.11805v3.pdf') + file2 = client.files.upload(file='2403.05530.pdf') + + print(file1) + print(file2) + +Get +--- + +.. code:: python + + file1 = client.files.upload(file='2312.11805v3.pdf') + file_info = client.files.get(name=file1.name) + + +Delete +------ + +.. code:: python + + file3 = client.files.upload(file='2312.11805v3.pdf') + + client.files.delete(name=file3.name) + +Caches +====== + +``client.caches`` contains the control plane APIs for cached content. + See the 'Create a client' section above to initialize a client. + +Create +------ + +.. code:: python + + from google.genai import types + + if client.enterprise: + file_uris = [ + 'gs://cloud-samples-data/generative-ai/pdf/2312.11805v3.pdf', + 'gs://cloud-samples-data/generative-ai/pdf/2403.05530.pdf', + ] + else: + file_uris = [file1.uri, file2.uri] + + cached_content = client.caches.create( + model='gemini-flash-latest', + config=types.CreateCachedContentConfig( + contents=[ + types.Content( + role='user', + parts=[ + types.Part.from_uri( + file_uri=file_uris[0], mime_type='application/pdf' + ), + types.Part.from_uri( + file_uri=file_uris[1], + mime_type='application/pdf', + ), + ], + ) + ], + system_instruction='What is the sum of the two pdfs?', + display_name='test cache', + ttl='3600s', + ), + ) + +Get +--- + +.. code:: python + + cached_content = client.caches.get(name=cached_content.name) + +Generate Content with Caches +----------------------------- + +.. code:: python + + from google.genai import types + + response = client.models.generate_content( + model='gemini-flash-latest', + contents='Summarize the pdfs', + config=types.GenerateContentConfig( + cached_content=cached_content.name, + ), + ) + print(response.text) + +Interactions +============ + +The Interactions API is a unified interface for interacting with Gemini models and agents. It simplifies state management, tool orchestration, and long-running tasks. +See the `Interactions documentation `_ for more details. + +Basic Interaction +----------------- + +.. code:: python + + interaction = client.interactions.create( + model='gemini-flash-latest', + input='Tell me a short joke about programming.' + ) + print(interaction.output_text) + +Stateful Conversation +--------------------- + +The Interactions API supports server-side state management. You can continue a conversation by referencing the ``previous_interaction_id``. + +.. code:: python + + # 1. First turn + interaction1 = client.interactions.create( + model='gemini-flash-latest', + input='Hi, my name is Amir.' + ) + print(f"Model: {interaction1.output_text}") + + # 2. Second turn (passing previous_interaction_id) + interaction2 = client.interactions.create( + model='gemini-flash-latest', + input='What is my name?', + previous_interaction_id=interaction1.id, + ) + print(f"Model: {interaction2.output_text}") + +Multimodal Output (Images and Audio) +------------------------------------ + +The Interactions API can generate multimodal outputs, such as images or audio, by specifying ``response_modalities``. + +.. code:: python + + import base64 + + # Generate an image + interaction = client.interactions.create( + model='gemini-3.1-flash-lite-image', + input='Generate an image of a futuristic city.', + response_modalities=['IMAGE'], + ) + + if interaction.output_image: + print(f"Generated image with mime_type: {interaction.output_image.mime_type}") + with open("generated_city.png", "wb") as f: + f.write(base64.b64decode(interaction.output_image.data)) + +.. code:: python + + import base64 + + # Generate speech + interaction = client.interactions.create( + model='gemini-3.8-flash-tts', + input='Say hello and give a one sentence motivational quote.', + response_modalities=['AUDIO'], + ) + + if interaction.output_audio: + print(f"Generated audio with mime_type: {interaction.output_audio.mime_type}") + with open("greeting.wav", "wb") as f: + f.write(base64.b64decode(interaction.output_audio.data)) + +Built-in Tools +-------------- + +You can use Google's built-in tools such as Google Search or Code Execution. + +.. code:: python + + interaction = client.interactions.create( + model='gemini-flash-latest', + input='Who won the last Super Bowl?', + tools=[{'type': 'google_search'}], + ) + print(interaction.output_text) + +Tunings +======= + +``client.tunings`` contains tuning job APIs and supports supervised fine +tuning through ``tune``. Only supported in Gemini Enterprise Agent Platform. See the 'Create a client' +section above to initialize a client. + +Tune +---- + +- Gemini Enterprise Agent Platform supports tuning from GCS source or from a `Gemini Enterprise Agent Platform Multimodal Dataset `_ + +.. code:: python + + from google.genai import types + + model = 'gemini-flash-latest' + training_dataset = types.TuningDataset( + # or gcs_uri=my_enterprise_multimodal_dataset + gcs_uri='gs://your-gcs-bucket/your-tuning-data.jsonl', + ) + + +.. code:: python + + from google.genai import types + + tuning_job = client.tunings.tune( + base_model=model, + training_dataset=training_dataset, + config=types.CreateTuningJobConfig( + epoch_count=1, tuned_model_display_name='test_dataset_examples model' + ), + ) + print(tuning_job) + +Get Tuning Job +-------------- + +.. code:: python + + tuning_job = client.tunings.get(name=tuning_job.name) + print(tuning_job) + +.. code:: python + + import time + + completed_states = set( + [ + 'JOB_STATE_SUCCEEDED', + 'JOB_STATE_FAILED', + 'JOB_STATE_CANCELLED', + ] + ) + + while tuning_job.state not in completed_states: + print(tuning_job.state) + tuning_job = client.tunings.get(name=tuning_job.name) + time.sleep(10) + +Use Tuned Model +--------------- + +.. code:: python + + response = client.models.generate_content( + model=tuning_job.tuned_model.endpoint, + contents='why is the sky blue?', + ) + + print(response.text) + +Get Tuned Model +--------------- + +.. code:: python + + tuned_model = client.models.get(model=tuning_job.tuned_model.model) + print(tuned_model) + +Update Tuned Model +------------------ + +.. code:: python + + from google.genai import types + + tuned_model = client.models.update( + model=tuning_job.tuned_model.model, + config=types.UpdateModelConfig( + display_name='my tuned model', description='my tuned model description' + ), + ) + print(tuned_model) + +.. _List Tuned Models: + +List Tuned Models +----------------- + +To retrieve base models, see: :ref:`List Base Models` + +.. code:: python + + for model in client.models.list(config={'page_size': 10, 'query_base': False}): + print(model) + +.. code:: python + + pager = client.models.list(config={'page_size': 10, 'query_base': False}) + print(pager.page_size) + print(pager[0]) + pager.next_page() + print(pager[0]) + +List Tuned Models (Asynchronous) +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +.. code:: python + + async for job in await client.aio.models.list(config={'page_size': 10, 'query_base': False}): + print(job) + +.. code:: python + + async_pager = await client.aio.models.list(config={'page_size': 10, 'query_base': False}) + print(async_pager.page_size) + print(async_pager[0]) + await async_pager.next_page() + print(async_pager[0]) + +Update Tuned Model +------------------ + +.. code:: python + + from google.genai import types + + model = pager[0] + + model = client.models.update( + model=model.name, + config=types.UpdateModelConfig( + display_name='my tuned model', description='my tuned model description' + ), + ) + + print(model) + + +List Tuning Jobs +---------------- + +.. code:: python + + for job in client.tunings.list(config={'page_size': 10}): + print(job) + +.. code:: python + + pager = client.tunings.list(config={'page_size': 10}) + print(pager.page_size) + print(pager[0]) + pager.next_page() + print(pager[0]) + +List Tuning Jobs (Asynchronous): + +.. code:: python + + async for job in await client.aio.tunings.list(config={'page_size': 10}): + print(job) + +.. code:: python + + async_pager = await client.aio.tunings.list(config={'page_size': 10}) + print(async_pager.page_size) + print(async_pager[0]) + await async_pager.next_page() + print(async_pager[0]) + +Batch Prediction +================ + +Create a batch job. See the 'Create a client' section above to +initialize a client. + +Create +------ + +Vertex AI client support using a BigQuery table or a GCS file as the source. + +.. code:: python + + # Specify model and source file only, destination and job display name will be auto-populated + job = client.batches.create( + model='gemini-flash-latest', + src='bq://my-project.my-dataset.my-table', # or "gs://path/to/input/data" + ) + + print(job) + + +Gemini Developer API +^^^^^^^^^^^^^^^^^^^^ + +.. code:: python + + # Create a batch job with inlined requests + batch_job = client.batches.create( + model="gemini-flash-latest", + src=[{ + "contents": [{ + "parts": [{ + "text": "Hello!", + }], + "role": "user", + }], + "config": {"response_modalities": ["text"]}, + }], + ) + + job + + +In order to create a batch job with file name. Need to upload a json file. +For example myrequests.json: + +.. code:: json + + {"key":"request_1", "request": {"contents": [{"parts": [{"text": + "Explain how AI works in a few words"}]}], "generation_config": {"response_modalities": ["TEXT"]}}} + {"key":"request_2", "request": {"contents": [{"parts": [{"text": "Explain how Crypto works in a few words"}]}]}} + + +Then upload the file. + +.. code:: python + + # Upload a file to Gemini Developer API + file_name = client.files.upload( + file='myrequests.json', + config=types.UploadFileConfig(display_name='test-json'), + ) + # Create a batch job with file name + batch_job = client.batches.create( + model="gemini-flash-latest", + src="files/test-json", + ) + + +.. code:: python + + # Get a job by name + job = client.batches.get(name=job.name) + + job.state + +.. code:: python + + completed_states = set( + [ + 'JOB_STATE_SUCCEEDED', + 'JOB_STATE_FAILED', + 'JOB_STATE_CANCELLED', + 'JOB_STATE_PAUSED', + ] + ) + + while job.state not in completed_states: + print(job.state) + job = client.batches.get(name=job.name) + time.sleep(30) + + job + +List +---- + +.. code:: python + + from google.genai import types + + for job in client.batches.list(config=types.ListBatchJobsConfig(page_size=10)): + print(job) + +List Batch Jobs with Pager +^^^^^^^^^^^^^^^^^^^^^^^^^ + +.. code:: python + + from google.genai import types + + pager = client.batches.list(config=types.ListBatchJobsConfig(page_size=10)) + print(pager.page_size) + print(pager[0]) + pager.next_page() + print(pager[0]) + +List Batch Jobs (Asynchronous) +^^^^^^^^^^^^^^^^^^^^^^^^^ + +.. code:: python + + from google.genai import types + + async for job in await client.aio.batches.list( + config=types.ListBatchJobsConfig(page_size=10) + ): + print(job) + +List Batch Jobs with Pager (Asynchronous) +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +.. code:: python + + from google.genai import types + + async_pager = await client.aio.batches.list( + config=types.ListBatchJobsConfig(page_size=10) + ) + print(async_pager.page_size) + print(async_pager[0]) + await async_pager.next_page() + print(async_pager[0]) + +Delete +------ + +.. code:: python + + # Delete the job resource + delete_job = client.batches.delete(name=job.name) + + delete_job + +Error Handling +============== + +To handle errors raised by the model service, the SDK provides this `APIError `_ class. + +.. code:: python + + from google.genai import errors + + try: + client.models.generate_content( + model="invalid-model-name", + contents="What is your name?", + ) + except errors.APIError as e: + print(e.code) # 404 + print(e.message) + +Extra Request Body +================== + +The ``extra_body`` field in ``HttpOptions`` accepts a dictionary of additional JSON +properties to include in the request body. This can be used to access new or +experimental backend features that are not yet formally supported in the SDK. +The structure of the dictionary must match the backend API's request structure. + +- Gemini Enterprise Agent Platform backend API docs: https://docs.cloud.google.com/gemini-enterprise-agent-platform/reference/rest +- GeminiAPI backend API docs: https://ai.google.dev/api/rest + +.. code:: python + + response = client.models.generate_content( + model="gemini-flash-latest", + contents="What is the weather in Boston? and how about Sunnyvale?", + config=types.GenerateContentConfig( + tools=[get_current_weather], + http_options=types.HttpOptions(extra_body={'tool_config': {'function_calling_config': {'mode': 'COMPOSITIONAL'}}}), + ), + ) + + +Reference +========= +.. toctree:: + :maxdepth: 4 + + genai diff --git a/docs/source/modules.rst b/docs/source/modules.rst new file mode 100644 index 000000000..ff03010d6 --- /dev/null +++ b/docs/source/modules.rst @@ -0,0 +1,7 @@ +google +====== + +.. toctree:: + :maxdepth: 4 + + genai