Skip to content

Commit 905d733

Browse files
sararobcopybara-github
authored andcommitted
feat: GenAI SDK client - Update client.prompts.create_version to create a prompt and prompt version for a prompt. Recommend create_version instead of create
PiperOrigin-RevId: 889955089
1 parent 7142c62 commit 905d733

7 files changed

Lines changed: 518 additions & 164 deletions

File tree

tests/unit/vertexai/genai/replays/test_create_prompt.py

Lines changed: 28 additions & 63 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,7 @@
7575
)
7676
TEST_CREATE_PROMPT_CONFIG = types.CreatePromptConfig(
7777
prompt_display_name="my_prompt",
78+
version_display_name="my_version",
7879
)
7980

8081
TEST_CREATE_PROMPT_VERSION_CONFIG = types.CreatePromptVersionConfig(
@@ -147,8 +148,18 @@ def test_create(client):
147148
assert isinstance(prompt_resource.dataset, types.Dataset)
148149

149150

151+
def test_create_version(client):
152+
prompt_resource = client.prompts.create_version(
153+
prompt=TEST_PROMPT,
154+
config=TEST_CREATE_PROMPT_CONFIG,
155+
)
156+
assert isinstance(prompt_resource, types.Prompt)
157+
assert isinstance(prompt_resource.dataset, types.Dataset)
158+
assert isinstance(prompt_resource.dataset_version, types.DatasetVersion)
159+
160+
150161
def test_create_e2e(client):
151-
prompt_resource = client.prompts.create(
162+
prompt_resource = client.prompts.create_version(
152163
prompt=TEST_PROMPT,
153164
config=TEST_CREATE_PROMPT_CONFIG,
154165
)
@@ -183,13 +194,13 @@ def test_create_e2e(client):
183194
== prompt_resource.prompt_data.generation_config
184195
)
185196

186-
# Test calling create_version on the same prompt dataset and change the prompt
197+
# Test creating a new version on the same prompt dataset with update()
187198
new_prompt = TEST_PROMPT.model_copy(deep=True)
188199
new_prompt.prompt_data.contents[0].parts[0].text = "Is this Alice?"
189-
prompt_resource_2 = client.prompts.create_version(
200+
prompt_resource_2 = client.prompts.update(
190201
prompt_id=prompt_resource.prompt_id,
191202
prompt=new_prompt,
192-
config=types.CreatePromptVersionConfig(
203+
config=types.UpdatePromptConfig(
193204
version_display_name="my_version",
194205
),
195206
)
@@ -199,37 +210,17 @@ def test_create_e2e(client):
199210
# Update the prompt contents again and verify version history is preserved
200211
prompt_v3 = TEST_PROMPT.model_copy(deep=True)
201212
prompt_v3.prompt_data.contents[0].parts[0].text = "Is this Bob?"
202-
prompt_resource_3 = client.prompts.create_version(
213+
prompt_resource_3 = client.prompts.update(
203214
prompt_id=prompt_resource.prompt_id,
204215
prompt=prompt_v3,
205-
config=types.CreatePromptVersionConfig(
216+
config=types.UpdatePromptConfig(
206217
version_display_name="my_version_2",
207218
),
208219
)
209220
assert prompt_resource_3.dataset.name == prompt_resource.dataset.name
210221
assert prompt_resource_3.prompt_data.contents[0].parts[0].text == "Is this Bob?"
211222

212223

213-
def test_create_version(client):
214-
updated_prompt = TEST_PROMPT.model_copy(deep=True)
215-
new_prompt_text = "Is this {name}?"
216-
updated_prompt.prompt_data.contents[0].parts[0].text = new_prompt_text
217-
prompt_resource = client.prompts.create_version(
218-
prompt_id=TEST_PROMPT_DATASET_ID,
219-
prompt=updated_prompt,
220-
config=TEST_CREATE_PROMPT_VERSION_CONFIG,
221-
)
222-
assert isinstance(prompt_resource, types.Prompt)
223-
assert isinstance(prompt_resource.dataset, types.Dataset)
224-
assert isinstance(prompt_resource.dataset_version, types.DatasetVersion)
225-
assert prompt_resource.dataset.name.endswith(TEST_PROMPT_DATASET_ID)
226-
assert (
227-
prompt_resource.dataset_version.display_name
228-
== TEST_CREATE_PROMPT_VERSION_CONFIG.version_display_name
229-
)
230-
assert prompt_resource.prompt_data.contents[0].parts[0].text == new_prompt_text
231-
232-
233224
def test_create_with_file_data(client):
234225
audio_file_part = genai_types.Part(
235226
file_data=genai_types.FileData(
@@ -291,32 +282,20 @@ def test_create_with_file_data(client):
291282

292283
def test_create_with_encryption_spec(client):
293284
encryption_spec = genai_types.EncryptionSpec(
294-
kms_key_name="projects/vertex-sdk-dev/locations/us-central1/keyRings/my-key-ring/cryptoKeys/my-key",
285+
kms_key_name="projects/vertex-sdk-dev/locations/us-central1/keyRings/test-key-ring/cryptoKeys/my-key",
295286
)
296-
config = types.CreatePromptConfig(
287+
config = types.CreatePromptVersionConfig(
297288
prompt_display_name="my_prompt_with_encryption_spec",
289+
version_display_name="my_version_with_encryption_spec",
298290
encryption_spec=encryption_spec,
299291
)
300-
prompt_resource = client.prompts.create(
292+
prompt_resource = client.prompts.create_version(
301293
prompt=TEST_PROMPT,
302294
config=config,
303295
)
304296
assert isinstance(prompt_resource, types.Prompt)
305297
assert isinstance(prompt_resource.dataset, types.Dataset)
306-
307-
# Create a version on a prompt with an encryption spec.
308-
new_prompt = TEST_PROMPT.model_copy(deep=True)
309-
new_prompt.prompt_data.contents[0].parts[0].text = "Is this Alice?"
310-
prompt_version_resource = client.prompts.create_version(
311-
prompt_id=prompt_resource.prompt_id,
312-
prompt=new_prompt,
313-
config=types.CreatePromptVersionConfig(
314-
version_display_name="my_version_existing_dataset",
315-
),
316-
)
317-
assert isinstance(prompt_version_resource, types.Prompt)
318-
assert isinstance(prompt_version_resource.dataset, types.Dataset)
319-
assert isinstance(prompt_version_resource.dataset_version, types.DatasetVersion)
298+
assert isinstance(prompt_resource.dataset_version, types.DatasetVersion)
320299

321300

322301
pytestmark = pytest_helper.setup(
@@ -340,24 +319,10 @@ async def test_create_async(client):
340319

341320
@pytest.mark.asyncio
342321
async def test_create_version_async(client):
343-
prompt_resource = await client.aio.prompts.create(
344-
prompt=TEST_PROMPT.model_dump(),
345-
config=TEST_CREATE_PROMPT_CONFIG.model_dump(),
346-
)
347-
new_prompt = TEST_PROMPT.model_copy(deep=True)
348-
new_prompt.prompt_data.contents[0].parts[0].text = "Is this Alice?"
349-
prompt_version_resource = await client.aio.prompts.create_version(
350-
prompt_id=prompt_resource.prompt_id,
351-
prompt=new_prompt,
352-
config=types.CreatePromptVersionConfig(
353-
version_display_name="my_version_existing_dataset",
354-
),
355-
)
356-
assert isinstance(prompt_version_resource, types.Prompt)
357-
assert isinstance(prompt_version_resource.dataset, types.Dataset)
358-
assert isinstance(prompt_version_resource.dataset_version, types.DatasetVersion)
359-
assert prompt_version_resource.dataset.name.endswith(prompt_resource.prompt_id)
360-
assert (
361-
prompt_version_resource.prompt_data.contents[0].parts[0].text
362-
== "Is this Alice?"
322+
prompt_resource = await client.aio.prompts.create_version(
323+
prompt=TEST_PROMPT,
324+
config=TEST_CREATE_PROMPT_CONFIG,
363325
)
326+
assert isinstance(prompt_resource, types.Prompt)
327+
assert isinstance(prompt_resource.dataset, types.Dataset)
328+
assert isinstance(prompt_resource.dataset_version, types.DatasetVersion)

tests/unit/vertexai/genai/replays/test_delete_prompt.py

Lines changed: 2 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,7 @@ async def test_delete_dataset_async(client, caplog):
7070
@pytest.mark.asyncio
7171
async def test_delete_version_async(client, caplog):
7272
caplog.set_level(logging.INFO)
73-
prompt = client.prompts.create(
73+
prompt_version = client.prompts.create_version(
7474
prompt=types.Prompt(
7575
prompt_data=types.PromptData(
7676
model="gemini-2.5-flash",
@@ -83,18 +83,12 @@ async def test_delete_version_async(client, caplog):
8383
),
8484
config=types.CreatePromptConfig(
8585
prompt_display_name="test_delete_prompt_dataset",
86-
),
87-
)
88-
prompt_version = client.prompts.create_version(
89-
prompt_id=prompt.prompt_id,
90-
prompt=prompt,
91-
config=types.CreatePromptVersionConfig(
9286
version_display_name="test_delete_prompt_dataset_version",
9387
),
9488
)
9589
version_id = prompt_version.dataset_version.name.split("/")[-1]
9690
await client.aio.prompts.delete_version(
97-
prompt_id=prompt.prompt_id,
91+
prompt_id=prompt_version.prompt_id,
9892
version_id=version_id,
9993
)
10094
assert "Deleted prompt version" in caplog.text

tests/unit/vertexai/genai/replays/test_restore_prompt_version.py

Lines changed: 20 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -30,21 +30,21 @@
3030

3131

3232
def test_restore_version(client):
33-
my_prompt = client.prompts.create(
34-
prompt=test_create_prompt.TEST_PROMPT.model_dump(),
35-
config=test_create_prompt.TEST_CREATE_PROMPT_CONFIG,
36-
)
37-
3833
# Create 2 versions on my_prompt
3934
prompt_v1 = client.prompts.create_version(
40-
prompt_id=my_prompt.prompt_id,
4135
prompt=test_create_prompt.TEST_PROMPT.model_copy(deep=True),
42-
config=types.CreatePromptVersionConfig(version_display_name="my_prompt_v1"),
36+
config=types.CreatePromptVersionConfig(
37+
prompt_display_name="my_prompt",
38+
version_display_name="my_prompt_v1",
39+
),
4340
)
44-
prompt_v2 = client.prompts.create_version(
45-
prompt_id=my_prompt.prompt_id,
41+
prompt_v2 = client.prompts.update(
42+
prompt_id=prompt_v1.prompt_id,
4643
prompt=prompt_contents_2,
47-
config=types.CreatePromptVersionConfig(version_display_name="my_prompt_v2"),
44+
config=types.CreatePromptVersionConfig(
45+
prompt_display_name="my_prompt",
46+
version_display_name="my_prompt_v2",
47+
),
4848
)
4949
my_prompt_v1_id = prompt_v1.dataset_version.name.split("/")[-1]
5050
my_prompt_v2_id = prompt_v2.dataset_version.name.split("/")[-1]
@@ -58,7 +58,7 @@ def test_restore_version(client):
5858

5959
# Restore version to my_prompt_v1_id
6060
restored_prompt = client.prompts.restore_version(
61-
prompt_id=my_prompt.prompt_id,
61+
prompt_id=prompt_v1.prompt_id,
6262
version_id=my_prompt_v1_id,
6363
)
6464
assert restored_prompt.dataset_version.name.split("/")[-1] == my_prompt_v1_id
@@ -80,29 +80,27 @@ def test_restore_version(client):
8080

8181
@pytest.mark.asyncio
8282
async def test_restore_version_async(client):
83-
my_prompt = await client.aio.prompts.create(
84-
prompt=test_create_prompt.TEST_PROMPT.model_dump(),
85-
config=test_create_prompt.TEST_CREATE_PROMPT_CONFIG,
86-
)
87-
8883
# Create 2 versions on my_prompt
8984
prompt_v1 = client.prompts.create_version(
90-
prompt_id=my_prompt.prompt_id,
9185
prompt=test_create_prompt.TEST_PROMPT.model_copy(deep=True),
92-
config=types.CreatePromptVersionConfig(version_display_name="my_prompt_v1"),
86+
config=types.CreatePromptVersionConfig(
87+
prompt_display_name="my_prompt", version_display_name="my_prompt_v1"
88+
),
9389
)
94-
prompt_v2 = client.prompts.create_version(
95-
prompt_id=my_prompt.prompt_id,
90+
prompt_v2 = client.prompts.update(
91+
prompt_id=prompt_v1.prompt_id,
9692
prompt=prompt_contents_2,
97-
config=types.CreatePromptVersionConfig(version_display_name="my_prompt_v2"),
93+
config=types.CreatePromptVersionConfig(
94+
prompt_display_name="my_prompt", version_display_name="my_prompt_v2"
95+
),
9896
)
9997
my_prompt_v1_id = prompt_v1.dataset_version.name.split("/")[-1]
10098
my_prompt_v2_id = prompt_v2.dataset_version.name.split("/")[-1]
10199
assert my_prompt_v2_id != my_prompt_v1_id
102100

103101
# Restore version to my_prompt_v1_id
104102
restored_prompt = await client.aio.prompts.restore_version(
105-
prompt_id=my_prompt.prompt_id,
103+
prompt_id=prompt_v1.prompt_id,
106104
version_id=my_prompt_v1_id,
107105
)
108106
assert restored_prompt.dataset_version.name.split("/")[-1] == my_prompt_v1_id
Lines changed: 126 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,126 @@
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+
# http://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+
# pylint: disable=protected-access,bad-continuation,missing-function-docstring
16+
17+
from tests.unit.vertexai.genai.replays import pytest_helper
18+
from vertexai._genai import types
19+
from google.genai import types as genai_types
20+
import pytest
21+
22+
23+
TEST_PROMPT_DATASET_ID = "8005484238453342208"
24+
TEST_VARIABLES = [
25+
{"name": genai_types.Part(text="Alice")},
26+
{"name": genai_types.Part(text="Bob")},
27+
]
28+
TEST_RESPONSE_SCHEMA = {
29+
"type": "object",
30+
"properties": {"response": {"type": "string"}},
31+
}
32+
TEST_PROMPT = types.Prompt(
33+
prompt_data=types.PromptData(
34+
contents=[
35+
genai_types.Content(
36+
role="user",
37+
parts=[genai_types.Part(text="Hello, {name}! How are you?")],
38+
)
39+
],
40+
safety_settings=[
41+
genai_types.SafetySetting(
42+
category="HARM_CATEGORY_DANGEROUS_CONTENT",
43+
threshold="BLOCK_MEDIUM_AND_ABOVE",
44+
method="SEVERITY",
45+
),
46+
],
47+
generation_config=genai_types.GenerationConfig(
48+
temperature=0.1,
49+
candidate_count=1,
50+
top_p=0.95,
51+
top_k=40,
52+
response_modalities=["TEXT"],
53+
response_schema=TEST_RESPONSE_SCHEMA,
54+
),
55+
system_instruction=genai_types.Content(
56+
parts=[genai_types.Part(text="Please answer in a short sentence.")]
57+
),
58+
tools=[
59+
genai_types.Tool(
60+
google_search_retrieval=genai_types.GoogleSearchRetrieval(
61+
dynamic_retrieval_config=genai_types.DynamicRetrievalConfig(
62+
mode="MODE_DYNAMIC"
63+
)
64+
)
65+
),
66+
],
67+
tool_config=genai_types.ToolConfig(
68+
retrieval_config=genai_types.RetrievalConfig(
69+
lat_lng=genai_types.LatLng(latitude=37.7749, longitude=-122.4194)
70+
)
71+
),
72+
model="gemini-2.0-flash-001",
73+
variables=TEST_VARIABLES,
74+
),
75+
)
76+
TEST_CREATE_PROMPT_CONFIG = types.CreatePromptConfig(
77+
prompt_display_name="my_prompt",
78+
)
79+
80+
TEST_CREATE_PROMPT_VERSION_CONFIG = types.CreatePromptVersionConfig(
81+
version_display_name="my_version",
82+
)
83+
84+
85+
def test_update_creates_new_version(client):
86+
updated_prompt = TEST_PROMPT.model_copy(deep=True)
87+
updated_prompt.prompt_data.contents[0].parts[0].text = "Is this Alice?"
88+
89+
prompt_resource = client.prompts.update(
90+
prompt_id=TEST_PROMPT_DATASET_ID,
91+
prompt=updated_prompt,
92+
config=types.UpdatePromptConfig(
93+
version_display_name="my_version",
94+
),
95+
)
96+
assert isinstance(prompt_resource, types.Prompt)
97+
assert isinstance(prompt_resource.dataset, types.Dataset)
98+
assert isinstance(prompt_resource.dataset_version, types.DatasetVersion)
99+
assert prompt_resource.prompt_data.contents[0].parts[0].text == "Is this Alice?"
100+
101+
102+
pytestmark = pytest_helper.setup(
103+
file=__file__,
104+
globals_for_file=globals(),
105+
test_method="prompts.update",
106+
)
107+
108+
pytest_plugins = ("pytest_asyncio",)
109+
110+
111+
@pytest.mark.asyncio
112+
async def test_update_async(client):
113+
updated_prompt = TEST_PROMPT.model_copy(deep=True)
114+
updated_prompt.prompt_data.contents[0].parts[0].text = "Is this Alice?"
115+
116+
prompt_resource = await client.aio.prompts.update(
117+
prompt_id=TEST_PROMPT_DATASET_ID,
118+
prompt=updated_prompt,
119+
config=types.UpdatePromptConfig(
120+
version_display_name="my_updated_version",
121+
),
122+
)
123+
assert isinstance(prompt_resource, types.Prompt)
124+
assert isinstance(prompt_resource.dataset, types.Dataset)
125+
assert isinstance(prompt_resource.dataset_version, types.DatasetVersion)
126+
assert prompt_resource.prompt_data.contents[0].parts[0].text == "Is this Alice?"

0 commit comments

Comments
 (0)