Skip to content

Commit a0caa62

Browse files
authored
docs(generative_ai): Update Chat Completions API samples (GoogleCloudPlatform#13088)
* docs(generative_ai): Update Chat Completions API samples - Fix imports (tests were failing) - Add authentication sample - Combine credentials refresher region tags - Add samples for self-hosted models * Fix lint error * Update model endpoint id * Update generative_ai/chat_completions/chat_completions_authentication.py * Update generative_ai/chat_completions/chat_completions_authentication.py * Update generative_ai/chat_completions/chat_completions_authentication.py * Update Test to include new model Endpoint ID * Update Ednpoint ID * Change Model ID * Update endpoint to v1
1 parent e42ea58 commit a0caa62

11 files changed

+214
-48
lines changed
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
# Copyright 2025 Google LLC
2+
#
3+
# Licensed under the Apache License, Version 2.0 (the "License");
4+
# you may not use this file except in compliance with the License.
5+
# You may obtain a copy of the License at
6+
#
7+
# https://www.apache.org/licenses/LICENSE-2.0
8+
#
9+
# Unless required by applicable law or agreed to in writing, software
10+
# distributed under the License is distributed on an "AS IS" BASIS,
11+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
# See the License for the specific language governing permissions and
13+
# limitations under the License.
14+
15+
16+
def generate_text(project_id: str, location: str = "us-central1") -> object:
17+
# [START generativeaionvertexai_gemini_chat_completions_authentication]
18+
import openai
19+
20+
from google.auth import default
21+
import google.auth.transport.requests
22+
23+
# TODO(developer): Update and un-comment below lines
24+
# project_id = "PROJECT_ID"
25+
# location = "us-central1"
26+
27+
# Programmatically get an access token
28+
credentials, _ = default(scopes=["https://www.googleapis.com/auth/cloud-platform"])
29+
credentials.refresh(google.auth.transport.requests.Request())
30+
# Note: the credential lives for 1 hour by default (https://cloud.google.com/docs/authentication/token-types#at-lifetime); after expiration, it must be refreshed.
31+
32+
##############################
33+
# Choose one of the following:
34+
##############################
35+
36+
# If you are calling a Gemini model, set the ENDPOINT_ID variable to use openapi.
37+
ENDPOINT_ID = "openapi"
38+
39+
# If you are calling a self-deployed model from Model Garden, set the
40+
# ENDPOINT_ID variable and set the client's base URL to use your endpoint.
41+
# ENDPOINT_ID = "YOUR_ENDPOINT_ID"
42+
43+
# OpenAI Client
44+
client = openai.OpenAI(
45+
base_url=f"https://{location}-aiplatform.googleapis.com/v1/projects/{project_id}/locations/{location}/endpoints/{ENDPOINT_ID}",
46+
api_key=credentials.token,
47+
)
48+
# [END generativeaionvertexai_gemini_chat_completions_authentication]
49+
50+
return client

generative_ai/chat_completions/chat_completions_credentials_refresher.py

Lines changed: 8 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515
# Disable linting on `Any` type annotations (needed for OpenAI kwargs and attributes).
1616
# flake8: noqa ANN401
1717

18-
# [START generativeaionvertexai_credentials_refresher_class]
18+
# [START generativeaionvertexai_credentials_refresher]
1919
from typing import Any
2020

2121
import google.auth
@@ -25,16 +25,15 @@
2525

2626
class OpenAICredentialsRefresher:
2727
def __init__(self, **kwargs: Any) -> None:
28-
# Set a dummy key here
29-
self.client = openai.OpenAI(**kwargs, api_key="DUMMY")
28+
# Set a placeholder key here
29+
self.client = openai.OpenAI(**kwargs, api_key="PLACEHOLDER")
3030
self.creds, self.project = google.auth.default(
3131
scopes=["https://www.googleapis.com/auth/cloud-platform"]
3232
)
3333

3434
def __getattr__(self, name: str) -> Any:
3535
if not self.creds.valid:
36-
auth_req = google.auth.transport.requests.Request()
37-
self.creds.refresh(auth_req)
36+
self.creds.refresh(google.auth.transport.requests.Request())
3837

3938
if not self.creds.valid:
4039
raise RuntimeError("Unable to refresh auth")
@@ -43,18 +42,16 @@ def __getattr__(self, name: str) -> Any:
4342
return getattr(self.client, name)
4443

4544

46-
# [END generativeaionvertexai_credentials_refresher_class]
47-
48-
45+
# [END generativeaionvertexai_credentials_refresher]
4946
def generate_text(project_id: str, location: str = "us-central1") -> object:
50-
# [START generativeaionvertexai_credentials_refresher_usage]
47+
# [START generativeaionvertexai_credentials_refresher]
5148

5249
# TODO(developer): Update and un-comment below lines
5350
# project_id = "PROJECT_ID"
5451
# location = "us-central1"
5552

5653
client = OpenAICredentialsRefresher(
57-
base_url=f"https://{location}-aiplatform.googleapis.com/v1beta1/projects/{project_id}/locations/{location}/endpoints/openapi",
54+
base_url=f"https://{location}-aiplatform.googleapis.com/v1/projects/{project_id}/locations/{location}/endpoints/openapi",
5855
)
5956

6057
response = client.chat.completions.create(
@@ -63,6 +60,6 @@ def generate_text(project_id: str, location: str = "us-central1") -> object:
6360
)
6461

6562
print(response)
66-
# [END generativeaionvertexai_credentials_refresher_usage]
63+
# [END generativeaionvertexai_credentials_refresher]
6764

6865
return response

generative_ai/chat_completions/chat_completions_non_streaming_image.py

Lines changed: 6 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -15,25 +15,23 @@
1515

1616
def generate_text(project_id: str, location: str = "us-central1") -> object:
1717
# [START generativeaionvertexai_gemini_chat_completions_non_streaming_image]
18-
import vertexai
19-
import openai
2018

21-
from google.auth import default, transport
19+
from google.auth import default
20+
import google.auth.transport.requests
21+
22+
import openai
2223

2324
# TODO(developer): Update and un-comment below lines
2425
# project_id = "PROJECT_ID"
2526
# location = "us-central1"
2627

27-
vertexai.init(project=project_id, location=location)
28-
2928
# Programmatically get an access token
3029
credentials, _ = default(scopes=["https://www.googleapis.com/auth/cloud-platform"])
31-
auth_request = transport.requests.Request()
32-
credentials.refresh(auth_request)
30+
credentials.refresh(google.auth.transport.requests.Request())
3331

3432
# OpenAI Client
3533
client = openai.OpenAI(
36-
base_url=f"https://{location}-aiplatform.googleapis.com/v1beta1/projects/{project_id}/locations/{location}/endpoints/openapi",
34+
base_url=f"https://{location}-aiplatform.googleapis.com/v1/projects/{project_id}/locations/{location}/endpoints/openapi",
3735
api_key=credentials.token,
3836
)
3937

generative_ai/chat_completions/chat_completions_non_streaming_text.py

Lines changed: 6 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -15,25 +15,22 @@
1515

1616
def generate_text(project_id: str, location: str = "us-central1") -> object:
1717
# [START generativeaionvertexai_gemini_chat_completions_non_streaming]
18-
import vertexai
19-
import openai
18+
from google.auth import default
19+
import google.auth.transport.requests
2020

21-
from google.auth import default, transport
21+
import openai
2222

2323
# TODO(developer): Update and un-comment below lines
2424
# project_id = "PROJECT_ID"
2525
# location = "us-central1"
2626

27-
vertexai.init(project=project_id, location=location)
28-
2927
# Programmatically get an access token
3028
credentials, _ = default(scopes=["https://www.googleapis.com/auth/cloud-platform"])
31-
auth_request = transport.requests.Request()
32-
credentials.refresh(auth_request)
29+
credentials.refresh(google.auth.transport.requests.Request())
3330

34-
# # OpenAI Client
31+
# OpenAI Client
3532
client = openai.OpenAI(
36-
base_url=f"https://{location}-aiplatform.googleapis.com/v1beta1/projects/{project_id}/locations/{location}/endpoints/openapi",
33+
base_url=f"https://{location}-aiplatform.googleapis.com/v1/projects/{project_id}/locations/{location}/endpoints/openapi",
3734
api_key=credentials.token,
3835
)
3936

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
# Copyright 2025 Google LLC
2+
#
3+
# Licensed under the Apache License, Version 2.0 (the "License");
4+
# you may not use this file except in compliance with the License.
5+
# You may obtain a copy of the License at
6+
#
7+
# https://www.apache.org/licenses/LICENSE-2.0
8+
#
9+
# Unless required by applicable law or agreed to in writing, software
10+
# distributed under the License is distributed on an "AS IS" BASIS,
11+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
# See the License for the specific language governing permissions and
13+
# limitations under the License.
14+
15+
16+
def generate_text(
17+
project_id: str,
18+
location: str = "us-central1",
19+
model_id: str = "gemma-2-9b-it",
20+
endpoint_id: str = "YOUR_ENDPOINT_ID",
21+
) -> object:
22+
# [START generativeaionvertexai_gemini_chat_completions_non_streaming_self_deployed]
23+
from google.auth import default
24+
import google.auth.transport.requests
25+
26+
import openai
27+
28+
# TODO(developer): Update and un-comment below lines
29+
# project_id = "PROJECT_ID"
30+
# location = "us-central1"
31+
# model_id = "gemma-2-9b-it"
32+
# endpoint_id = "YOUR_ENDPOINT_ID"
33+
34+
# Programmatically get an access token
35+
credentials, _ = default(scopes=["https://www.googleapis.com/auth/cloud-platform"])
36+
credentials.refresh(google.auth.transport.requests.Request())
37+
38+
# OpenAI Client
39+
client = openai.OpenAI(
40+
base_url=f"https://{location}-aiplatform.googleapis.com/v1/projects/{project_id}/locations/{location}/endpoints/{endpoint_id}",
41+
api_key=credentials.token,
42+
)
43+
44+
response = client.chat.completions.create(
45+
model=model_id,
46+
messages=[{"role": "user", "content": "Why is the sky blue?"}],
47+
)
48+
print(response)
49+
50+
# [END generativeaionvertexai_gemini_chat_completions_non_streaming_self_deployed]
51+
52+
return response

generative_ai/chat_completions/chat_completions_streaming_image.py

Lines changed: 5 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -15,25 +15,22 @@
1515

1616
def generate_text(project_id: str, location: str = "us-central1") -> object:
1717
# [START generativeaionvertexai_gemini_chat_completions_streaming_image]
18-
import vertexai
19-
import openai
18+
from google.auth import default
19+
import google.auth.transport.requests
2020

21-
from google.auth import default, transport
21+
import openai
2222

2323
# TODO(developer): Update and un-comment below lines
2424
# project_id = "PROJECT_ID"
2525
# location = "us-central1"
2626

27-
vertexai.init(project=project_id, location=location)
28-
2927
# Programmatically get an access token
3028
credentials, _ = default(scopes=["https://www.googleapis.com/auth/cloud-platform"])
31-
auth_request = transport.requests.Request()
32-
credentials.refresh(auth_request)
29+
credentials.refresh(google.auth.transport.requests.Request())
3330

3431
# OpenAI Client
3532
client = openai.OpenAI(
36-
base_url=f"https://{location}-aiplatform.googleapis.com/v1beta1/projects/{project_id}/locations/{location}/endpoints/openapi",
33+
base_url=f"https://{location}-aiplatform.googleapis.com/v1/projects/{project_id}/locations/{location}/endpoints/openapi",
3734
api_key=credentials.token,
3835
)
3936

generative_ai/chat_completions/chat_completions_streaming_text.py

Lines changed: 5 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -15,25 +15,22 @@
1515

1616
def generate_text(project_id: str, location: str = "us-central1") -> object:
1717
# [START generativeaionvertexai_gemini_chat_completions_streaming]
18-
import vertexai
19-
import openai
18+
from google.auth import default
19+
import google.auth.transport.requests
2020

21-
from google.auth import default, transport
21+
import openai
2222

2323
# TODO(developer): Update and un-comment below lines
2424
# project_id = "PROJECT_ID"
2525
# location = "us-central1"
2626

27-
vertexai.init(project=project_id, location=location)
28-
2927
# Programmatically get an access token
3028
credentials, _ = default(scopes=["https://www.googleapis.com/auth/cloud-platform"])
31-
auth_request = transport.requests.Request()
32-
credentials.refresh(auth_request)
29+
credentials.refresh(google.auth.transport.requests.Request())
3330

3431
# OpenAI Client
3532
client = openai.OpenAI(
36-
base_url=f"https://{location}-aiplatform.googleapis.com/v1beta1/projects/{project_id}/locations/{location}/endpoints/openapi",
33+
base_url=f"https://{location}-aiplatform.googleapis.com/v1/projects/{project_id}/locations/{location}/endpoints/openapi",
3734
api_key=credentials.token,
3835
)
3936

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
# Copyright 2025 Google LLC
2+
#
3+
# Licensed under the Apache License, Version 2.0 (the "License");
4+
# you may not use this file except in compliance with the License.
5+
# You may obtain a copy of the License at
6+
#
7+
# https://www.apache.org/licenses/LICENSE-2.0
8+
#
9+
# Unless required by applicable law or agreed to in writing, software
10+
# distributed under the License is distributed on an "AS IS" BASIS,
11+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
# See the License for the specific language governing permissions and
13+
# limitations under the License.
14+
15+
16+
def generate_text(
17+
project_id: str,
18+
location: str = "us-central1",
19+
model_id: str = "gemma-2-9b-it",
20+
endpoint_id: str = "YOUR_ENDPOINT_ID",
21+
) -> object:
22+
# [START generativeaionvertexai_gemini_chat_completions_streaming_self_deployed]
23+
from google.auth import default
24+
import google.auth.transport.requests
25+
26+
import openai
27+
28+
# TODO(developer): Update and un-comment below lines
29+
# project_id = "PROJECT_ID"
30+
# location = "us-central1"
31+
# model_id = "gemma-2-9b-it"
32+
# endpoint_id = "YOUR_ENDPOINT_ID"
33+
34+
# Programmatically get an access token
35+
credentials, _ = default(scopes=["https://www.googleapis.com/auth/cloud-platform"])
36+
credentials.refresh(google.auth.transport.requests.Request())
37+
38+
# OpenAI Client
39+
client = openai.OpenAI(
40+
base_url=f"https://{location}-aiplatform.googleapis.com/v1/projects/{project_id}/locations/{location}/endpoints/{endpoint_id}",
41+
api_key=credentials.token,
42+
)
43+
44+
response = client.chat.completions.create(
45+
model=model_id,
46+
messages=[{"role": "user", "content": "Why is the sky blue?"}],
47+
stream=True,
48+
)
49+
for chunk in response:
50+
print(chunk)
51+
52+
# [END generativeaionvertexai_gemini_chat_completions_streaming_self_deployed]
53+
54+
return response

generative_ai/chat_completions/chat_completions_test.py

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,15 +14,25 @@
1414

1515
import os
1616

17+
import chat_completions_authentication
1718
import chat_completions_credentials_refresher
1819
import chat_completions_non_streaming_image
1920
import chat_completions_non_streaming_text
21+
import chat_completions_non_streaming_text_self_deployed
2022
import chat_completions_streaming_image
2123
import chat_completions_streaming_text
24+
import chat_completions_streaming_text_self_deployed
2225

2326

2427
PROJECT_ID = os.getenv("GOOGLE_CLOUD_PROJECT")
2528
LOCATION = "us-central1"
29+
SELF_HOSTED_MODEL_ID = "google/gemma-2-9b-it"
30+
ENDPOINT_ID = "6714120476014149632"
31+
32+
33+
def test_authentication() -> None:
34+
response = chat_completions_authentication.generate_text(PROJECT_ID, LOCATION)
35+
assert response
2636

2737

2838
def test_streaming_text() -> None:
@@ -50,3 +60,17 @@ def test_credentials_refresher() -> None:
5060
PROJECT_ID, LOCATION
5161
)
5262
assert response
63+
64+
65+
def test_streaming_text_self_deployed() -> None:
66+
response = chat_completions_streaming_text_self_deployed.generate_text(
67+
PROJECT_ID, LOCATION, SELF_HOSTED_MODEL_ID, ENDPOINT_ID
68+
)
69+
assert response
70+
71+
72+
def test_non_streaming_text_self_deployed() -> None:
73+
response = chat_completions_non_streaming_text_self_deployed.generate_text(
74+
PROJECT_ID, LOCATION, SELF_HOSTED_MODEL_ID, ENDPOINT_ID
75+
)
76+
assert response
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
11
backoff==2.2.1
2-
google-api-core==2.19.0
2+
google-api-core==2.24.0
33
pytest==8.2.0
44
pytest-asyncio==0.23.6

0 commit comments

Comments
 (0)