From 5437427f380e79f9e2b78882772845257dcb4225 Mon Sep 17 00:00:00 2001 From: Prabhjit Singh Dhillon Date: Mon, 10 Mar 2025 21:08:42 -0400 Subject: [PATCH 1/2] Improve key naming clarity and consistency across REST API examples - Standardize on camelCase for REST API parameter names - Update README.md to document parameter naming conventions - Create new inline_pdf_example.sh with consistent naming - Fix inconsistent naming in several example files - Fixes #683 --- samples/rest/README.md | 11 ++++ samples/rest/cache.sh | 4 +- samples/rest/chat.sh | 4 +- samples/rest/controlled_generation.sh | 6 +- samples/rest/count_tokens.sh | 12 ++-- samples/rest/function_calling.sh | 2 +- samples/rest/inline_pdf_example.sh | 88 +++++++++++++++++++++++++++ samples/rest/system_instruction.sh | 2 +- samples/rest/text_generation.sh | 20 +++--- 9 files changed, 124 insertions(+), 25 deletions(-) create mode 100644 samples/rest/inline_pdf_example.sh diff --git a/samples/rest/README.md b/samples/rest/README.md index 7969097d2..2d88c94fc 100644 --- a/samples/rest/README.md +++ b/samples/rest/README.md @@ -6,6 +6,16 @@ These samples are embedded in parts of the [documentation](https://ai.google.dev Each file is structured as a runnable script, ensuring that samples are executable and functional. Each filee contains region tags that are used to demarcate the script from the spotlight code. If you are contributing, code within region tags should follow sample code best practices - being clear, complete and concise. +## Parameter Naming Conventions + +The Gemini API accepts REST parameters in camelCase format, which is the convention used in these examples and the official API reference. For example: +- `generationConfig` +- `maxOutputTokens` +- `systemInstruction` +- `topP`, `topK` + +**Note:** While the API also accepts snake_case format for compatibility (e.g., `system_instruction` instead of `systemInstruction`), the official and recommended style is camelCase for REST API requests. + ## Contents | File | Description | @@ -19,6 +29,7 @@ Each file is structured as a runnable script, ensuring that samples are executab | [embed.sh](./embed.sh) | Generating embeddings | | [files.sh](./files.sh) | Managing files with the File API | | [function_calling.sh](./function_calling.sh) | Using function calling | +| [inline_pdf_example.sh](./inline_pdf_example.sh) | Using inline PDF data with the API | | [models.sh](./models.sh) | Listing models and model metadata | | [safety_settings.sh](./safety_settings.sh) | Setting and using safety controls | | [system_instruction.sh](./system_instruction.sh) | Setting system instructions | diff --git a/samples/rest/cache.sh b/samples/rest/cache.sh index 8df687886..ddbc44863 100644 --- a/samples/rest/cache.sh +++ b/samples/rest/cache.sh @@ -15,8 +15,8 @@ echo '{ { "parts":[ { - "inline_data": { - "mime_type":"text/plain", + "inlineData": { + "mimeType":"text/plain", "data": "'$(base64 $B64FLAGS a11.txt)'" } } diff --git a/samples/rest/chat.sh b/samples/rest/chat.sh index 0243e4152..607e86c32 100644 --- a/samples/rest/chat.sh +++ b/samples/rest/chat.sh @@ -81,8 +81,8 @@ curl https://generativelanguage.googleapis.com/v1beta/models/gemini-2.0-flash:st "text": "Tell me about this instrument" }, { - "inline_data": { - "mime_type": "image/jpeg", + "inlineData": { + "mimeType": "image/jpeg", "data": "'$(base64 $B64FLAGS $IMG_PATH)'" } } diff --git a/samples/rest/controlled_generation.sh b/samples/rest/controlled_generation.sh index 352b435de..a4cc4fc19 100644 --- a/samples/rest/controlled_generation.sh +++ b/samples/rest/controlled_generation.sh @@ -11,8 +11,8 @@ curl "https://generativelanguage.googleapis.com/v1beta/models/gemini-2.0-flash:g ] }], "generationConfig": { - "response_mime_type": "application/json", - "response_schema": { + "responseMimeType": "application/json", + "responseSchema": { "type": "ARRAY", "items": { "type": "OBJECT", @@ -39,6 +39,6 @@ curl "https://generativelanguage.googleapis.com/v1beta/models/gemini-2.0-flash:g } ] }], - "generationConfig": { "response_mime_type": "application/json" } + "generationConfig": { "responseMimeType": "application/json" } }' 2> /dev/null | head # [END json_no_schema] diff --git a/samples/rest/count_tokens.sh b/samples/rest/count_tokens.sh index 3c6be6719..e151eaf84 100644 --- a/samples/rest/count_tokens.sh +++ b/samples/rest/count_tokens.sh @@ -65,8 +65,8 @@ curl "https://generativelanguage.googleapis.com/v1beta/models/gemini-2.0-flash:c "parts":[ {"text": "Tell me about this instrument"}, { - "inline_data": { - "mime_type":"image/jpeg", + "inlineData": { + "mimeType":"image/jpeg", "data": "'$(base64 $B64FLAGS $IMG_PATH)'" } } @@ -184,8 +184,8 @@ echo '{ { "parts":[ { - "inline_data": { - "mime_type":"text/plain", + "inlineData": { + "mimeType":"text/plain", "data": "'$(base64 $B64FLAGS $A11_PATH)'" } } @@ -215,7 +215,7 @@ echo "[START tokens_system_instruction]" # [START tokens_system_instruction] curl "https://generativelanguage.googleapis.com/v1beta/models/gemini-1.5-pro-latest:generateContent?key=$GOOGLE_API_KEY" \ -H 'Content-Type: application/json' \ --d '{ "system_instruction": { +-d '{ "systemInstruction": { "parts": { "text": "You are a cat. Your name is Neko."}}, "contents": { @@ -264,7 +264,7 @@ curl "https://generativelanguage.googleapis.com/v1beta/models/gemini-1.5-pro-lat -H 'Content-Type: application/json' \ -d ' { - "system_instruction": { + "systemInstruction": { "parts": { "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." } diff --git a/samples/rest/function_calling.sh b/samples/rest/function_calling.sh index a0e0fa28d..0c1cb036a 100644 --- a/samples/rest/function_calling.sh +++ b/samples/rest/function_calling.sh @@ -38,7 +38,7 @@ curl "https://generativelanguage.googleapis.com/v1beta/models/gemini-2.0-flash:g -H 'Content-Type: application/json' \ -d @<(echo ' { - "system_instruction": { + "systemInstruction": { "parts": { "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." } diff --git a/samples/rest/inline_pdf_example.sh b/samples/rest/inline_pdf_example.sh new file mode 100644 index 000000000..3dea04e8a --- /dev/null +++ b/samples/rest/inline_pdf_example.sh @@ -0,0 +1,88 @@ +#!/bin/bash +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# This example demonstrates how to use inline PDF data with the generative API + +# Set default values for environment variables if they don't exist +MEDIA_DIR="${MEDIA_DIR:-$(dirname "$0")/../../third_party}" + +# Check if we're on macOS or Linux +if [[ "$OSTYPE" == "darwin"* ]]; then + B64FLAGS="-b 0" +else + B64FLAGS="--wrap=0" +fi + +echo "[START text_gen_multimodal_two_pdf_inline]" +# Use temporary files to hold the base64 encoded pdf data +PDF_PATH_1=${MEDIA_DIR}/test.pdf +PDF_PATH_2=${MEDIA_DIR}/test.pdf + +TEMP_1_B64=$(mktemp) +trap 'rm -f "$TEMP_1_B64"' EXIT +base64 $B64FLAGS $PDF_PATH_1 > "$TEMP_1_B64" + +TEMP_2_B64=$(mktemp) +trap 'rm -f "$TEMP_2_B64"' EXIT +base64 $B64FLAGS $PDF_PATH_2 > "$TEMP_2_B64" + +# Use a temporary file to hold the JSON payload +TEMP_JSON=$(mktemp) +trap 'rm -f "$TEMP_JSON"' EXIT + +cat > "$TEMP_JSON" << EOF +{ + "contents": [{ + "role": "user", + "parts":[ + {"text": "Extract the pet names, type and ages from these documents."}, + { + "inlineData": { + "mimeType":"application/pdf", + "data": "$(cat "$TEMP_1_B64")" + } + }, + { + "inlineData": { + "mimeType":"application/pdf", + "data": "$(cat "$TEMP_2_B64")" + } + } + ] + }], + "systemInstruction": { + "parts": [ + {"text": "Extract the pet names and ages from these documents and return them in the following JSON format: + + Pet = {\"name\": str, \"type\": str, \"age\": int} + Return: list[Pet]" + } + ] + }, + "generationConfig": { + "temperature": 0.2, + "topP": 0.95, + "topK": 40, + "maxOutputTokens": 1000, + "responseMimeType": "application/json" + } +} +EOF + +curl "https://generativelanguage.googleapis.com/v1beta/models/gemini-2.0-flash:generateContent?key=$GOOGLE_API_KEY" \ + -H 'Content-Type: application/json' \ + -X POST \ + -d "@$TEMP_JSON" 2> /dev/null diff --git a/samples/rest/system_instruction.sh b/samples/rest/system_instruction.sh index 44f77ea04..6f1155985 100644 --- a/samples/rest/system_instruction.sh +++ b/samples/rest/system_instruction.sh @@ -4,7 +4,7 @@ echo "[START system_instruction]" # [START system_instruction] curl "https://generativelanguage.googleapis.com/v1beta/models/gemini-2.0-flash:generateContent?key=$GEMINI_API_KEY" \ -H 'Content-Type: application/json' \ --d '{ "system_instruction": { +-d '{ "systemInstruction": { "parts": { "text": "You are a cat. Your name is Neko."}}, "contents": { diff --git a/samples/rest/text_generation.sh b/samples/rest/text_generation.sh index fc21e7d00..575d92ad3 100755 --- a/samples/rest/text_generation.sh +++ b/samples/rest/text_generation.sh @@ -54,8 +54,8 @@ cat > "$TEMP_JSON" << EOF "parts":[ {"text": "Tell me about this instrument"}, { - "inline_data": { - "mime_type":"image/jpeg", + "inlineData": { + "mimeType":"image/jpeg", "data": "$(cat "$TEMP_B64")" } } @@ -78,8 +78,8 @@ cat > "$TEMP_JSON" << EOF "parts":[ {"text": "Tell me about this instrument"}, { - "inline_data": { - "mime_type":"image/jpeg", + "inlineData": { + "mimeType":"image/jpeg", "data": "$(cat "$TEMP_B64")" } } @@ -109,14 +109,14 @@ cat > "$TEMP_JSON" << EOF "contents": [{ "parts":[ { - "inline_data": { - "mime_type": "image/jpeg", + "inlineData": { + "mimeType": "image/jpeg", "data": "$(cat "$TEMP_B64_1")" } }, { - "inline_data": { - "mime_type": "image/jpeg", + "inlineData": { + "mimeType": "image/jpeg", "data": "$(cat "$TEMP_B64_2")" } }, @@ -148,8 +148,8 @@ cat > "$TEMP_JSON" << EOF "contents": [{ "parts":[ { - "inline_data": { - "mime_type": "image/jpeg", + "inlineData": { + "mimeType": "image/jpeg", "data": "$(cat "$TEMP_B64_2")" } }, From b39f3cd7bc97d7bf52fc587511044f4c71df0b1d Mon Sep 17 00:00:00 2001 From: Prabhjit Singh Dhillon Date: Mon, 10 Mar 2025 21:44:26 -0400 Subject: [PATCH 2/2] Additional camelCase consistency fixes --- samples/rest/count_tokens.sh | 12 ++++++------ samples/rest/function_calling.sh | 4 ++-- samples/rest/text_generation.sh | 12 ++++++------ 3 files changed, 14 insertions(+), 14 deletions(-) diff --git a/samples/rest/count_tokens.sh b/samples/rest/count_tokens.sh index e151eaf84..edaff394a 100644 --- a/samples/rest/count_tokens.sh +++ b/samples/rest/count_tokens.sh @@ -113,9 +113,9 @@ curl "https://generativelanguage.googleapis.com/v1beta/models/gemini-1.5-flash:c "contents": [{ "parts":[ {"text": "Can you tell me about the instruments in this photo?"}, - {"file_data": - {"mime_type": "image/jpeg", - "file_uri": '$file_uri'} + {"fileData": + {"mimeType": "image/jpeg", + "fileUri": '$file_uri'} }] }] }' @@ -171,7 +171,7 @@ curl "https://generativelanguage.googleapis.com/v1beta/models/gemini-1.5-flash:c "contents": [{ "parts":[ {"text": "Describe this video clip"}, - {"file_data":{"mime_type": "video/mp4", "file_uri": '$file_uri'}}] + {"fileData":{"mimeType": "video/mp4", "fileUri": '$file_uri'}}] }] }' # [END tokens_multimodal_video_audio_file_api] @@ -271,8 +271,8 @@ curl "https://generativelanguage.googleapis.com/v1beta/models/gemini-1.5-pro-lat }, "tools": ['$(source "$tools")'], - "tool_config": { - "function_calling_config": {"mode": "none"} + "toolConfig": { + "functionCallingConfig": {"mode": "none"} }, "contents": { diff --git a/samples/rest/function_calling.sh b/samples/rest/function_calling.sh index 0c1cb036a..18ee6831c 100644 --- a/samples/rest/function_calling.sh +++ b/samples/rest/function_calling.sh @@ -45,8 +45,8 @@ curl "https://generativelanguage.googleapis.com/v1beta/models/gemini-2.0-flash:g }, "tools": ['$(cat tools.json)'], - "tool_config": { - "function_calling_config": {"mode": "auto"} + "toolConfig": { + "functionCallingConfig": {"mode": "auto"} }, "contents": { diff --git a/samples/rest/text_generation.sh b/samples/rest/text_generation.sh index 575d92ad3..c591f8fe3 100755 --- a/samples/rest/text_generation.sh +++ b/samples/rest/text_generation.sh @@ -210,7 +210,7 @@ curl "https://generativelanguage.googleapis.com/v1beta/models/gemini-2.0-flash:g "contents": [{ "parts":[ {"text": "Please describe this file."}, - {"file_data":{"mime_type": "audio/mpeg", "file_uri": '$file_uri'}}] + {"fileData":{"mimeType": "audio/mpeg", "fileUri": '$file_uri'}}] }] }' 2> /dev/null > response.json @@ -260,7 +260,7 @@ curl "https://generativelanguage.googleapis.com/v1beta/models/gemini-2.0-flash:s "contents": [{ "parts":[ {"text": "Please describe this file."}, - {"file_data":{"mime_type": "audio/mpeg", "file_uri": '$file_uri'}}] + {"fileData":{"mimeType": "audio/mpeg", "fileUri": '$file_uri'}}] }] }' 2> /dev/null > response.json @@ -321,7 +321,7 @@ curl "https://generativelanguage.googleapis.com/v1beta/models/gemini-2.0-flash:g "contents": [{ "parts":[ {"text": "Transcribe the audio from this video, giving timestamps for salient events in the video. Also provide visual descriptions."}, - {"file_data":{"mime_type": "video/mp4", "file_uri": '$file_uri'}}] + {"fileData":{"mimeType": "video/mp4", "fileUri": '$file_uri'}}] }] }' 2> /dev/null > response.json @@ -381,7 +381,7 @@ curl "https://generativelanguage.googleapis.com/v1beta/models/gemini-2.0-flash:s "contents": [{ "parts":[ {"text": "Please describe this file."}, - {"file_data":{"mime_type": "video/mp4", "file_uri": '$file_uri'}}] + {"fileData":{"mimeType": "video/mp4", "fileUri": '$file_uri'}}] }] }' 2> /dev/null > response.json @@ -431,7 +431,7 @@ curl "https://generativelanguage.googleapis.com/v1beta/models/gemini-2.0-flash:g "contents": [{ "parts":[ {"text": "Can you add a few more lines to this poem?"}, - {"file_data":{"mime_type": "application/pdf", "file_uri": '$file_uri'}}] + {"fileData":{"mimeType": "application/pdf", "fileUri": '$file_uri'}}] }] }' 2> /dev/null > response.json @@ -483,7 +483,7 @@ curl "https://generativelanguage.googleapis.com/v1beta/models/gemini-2.0-flash:s "contents": [{ "parts":[ {"text": "Can you add a few more lines to this poem?"}, - {"file_data":{"mime_type": "application/pdf", "file_uri": '$file_uri'}}] + {"fileData":{"mimeType": "application/pdf", "fileUri": '$file_uri'}}] }] }' 2> /dev/null > response.json