google-genai 1.33.0__py3-none-any.whl → 1.53.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- google/genai/_api_client.py +361 -208
- google/genai/_common.py +260 -69
- google/genai/_extra_utils.py +142 -12
- google/genai/_live_converters.py +691 -2746
- google/genai/_local_tokenizer_loader.py +0 -9
- google/genai/_operations_converters.py +186 -99
- google/genai/_replay_api_client.py +48 -51
- google/genai/_tokens_converters.py +169 -489
- google/genai/_transformers.py +193 -90
- google/genai/batches.py +1014 -1307
- google/genai/caches.py +458 -1107
- google/genai/client.py +101 -0
- google/genai/documents.py +532 -0
- google/genai/errors.py +58 -4
- google/genai/file_search_stores.py +1296 -0
- google/genai/files.py +108 -358
- google/genai/live.py +90 -32
- google/genai/live_music.py +24 -27
- google/genai/local_tokenizer.py +36 -3
- google/genai/models.py +2308 -3375
- google/genai/operations.py +129 -21
- google/genai/pagers.py +7 -1
- google/genai/tokens.py +2 -12
- google/genai/tunings.py +770 -436
- google/genai/types.py +4341 -1218
- google/genai/version.py +1 -1
- {google_genai-1.33.0.dist-info → google_genai-1.53.0.dist-info}/METADATA +359 -201
- google_genai-1.53.0.dist-info/RECORD +41 -0
- google_genai-1.33.0.dist-info/RECORD +0 -39
- {google_genai-1.33.0.dist-info → google_genai-1.53.0.dist-info}/WHEEL +0 -0
- {google_genai-1.33.0.dist-info → google_genai-1.53.0.dist-info}/licenses/LICENSE +0 -0
- {google_genai-1.33.0.dist-info → google_genai-1.53.0.dist-info}/top_level.txt +0 -0
|
@@ -28,9 +28,6 @@ from sentencepiece import sentencepiece_model_pb2
|
|
|
28
28
|
|
|
29
29
|
# Source of truth: https://cloud.google.com/vertex-ai/generative-ai/docs/learn/models
|
|
30
30
|
_GEMINI_MODELS_TO_TOKENIZER_NAMES = {
|
|
31
|
-
"gemini-1.0-pro": "gemma2",
|
|
32
|
-
"gemini-1.5-pro": "gemma2",
|
|
33
|
-
"gemini-1.5-flash": "gemma2",
|
|
34
31
|
"gemini-2.5-pro": "gemma3",
|
|
35
32
|
"gemini-2.5-flash": "gemma3",
|
|
36
33
|
"gemini-2.5-flash-lite": "gemma3",
|
|
@@ -38,12 +35,6 @@ _GEMINI_MODELS_TO_TOKENIZER_NAMES = {
|
|
|
38
35
|
"gemini-2.0-flash-lite": "gemma3",
|
|
39
36
|
}
|
|
40
37
|
_GEMINI_STABLE_MODELS_TO_TOKENIZER_NAMES = {
|
|
41
|
-
"gemini-1.0-pro-001": "gemma2",
|
|
42
|
-
"gemini-1.0-pro-002": "gemma2",
|
|
43
|
-
"gemini-1.5-pro-001": "gemma2",
|
|
44
|
-
"gemini-1.5-flash-001": "gemma2",
|
|
45
|
-
"gemini-1.5-flash-002": "gemma2",
|
|
46
|
-
"gemini-1.5-pro-002": "gemma2",
|
|
47
38
|
"gemini-2.5-pro-preview-06-05": "gemma3",
|
|
48
39
|
"gemini-2.5-pro-preview-05-06": "gemma3",
|
|
49
40
|
"gemini-2.5-pro-exp-03-25": "gemma3",
|
|
@@ -38,24 +38,6 @@ def _FetchPredictOperationParameters_to_mldev(
|
|
|
38
38
|
return to_object
|
|
39
39
|
|
|
40
40
|
|
|
41
|
-
def _GetOperationParameters_to_mldev(
|
|
42
|
-
from_object: Union[dict[str, Any], object],
|
|
43
|
-
parent_object: Optional[dict[str, Any]] = None,
|
|
44
|
-
) -> dict[str, Any]:
|
|
45
|
-
to_object: dict[str, Any] = {}
|
|
46
|
-
if getv(from_object, ['operation_name']) is not None:
|
|
47
|
-
setv(
|
|
48
|
-
to_object,
|
|
49
|
-
['_url', 'operationName'],
|
|
50
|
-
getv(from_object, ['operation_name']),
|
|
51
|
-
)
|
|
52
|
-
|
|
53
|
-
if getv(from_object, ['config']) is not None:
|
|
54
|
-
setv(to_object, ['config'], getv(from_object, ['config']))
|
|
55
|
-
|
|
56
|
-
return to_object
|
|
57
|
-
|
|
58
|
-
|
|
59
41
|
def _FetchPredictOperationParameters_to_vertex(
|
|
60
42
|
from_object: Union[dict[str, Any], object],
|
|
61
43
|
parent_object: Optional[dict[str, Any]] = None,
|
|
@@ -71,61 +53,80 @@ def _FetchPredictOperationParameters_to_vertex(
|
|
|
71
53
|
getv(from_object, ['resource_name']),
|
|
72
54
|
)
|
|
73
55
|
|
|
74
|
-
if getv(from_object, ['config']) is not None:
|
|
75
|
-
setv(to_object, ['config'], getv(from_object, ['config']))
|
|
76
|
-
|
|
77
56
|
return to_object
|
|
78
57
|
|
|
79
58
|
|
|
80
|
-
def
|
|
59
|
+
def _GenerateVideosOperation_from_mldev(
|
|
81
60
|
from_object: Union[dict[str, Any], object],
|
|
82
61
|
parent_object: Optional[dict[str, Any]] = None,
|
|
83
62
|
) -> dict[str, Any]:
|
|
84
63
|
to_object: dict[str, Any] = {}
|
|
85
|
-
if getv(from_object, ['
|
|
64
|
+
if getv(from_object, ['name']) is not None:
|
|
65
|
+
setv(to_object, ['name'], getv(from_object, ['name']))
|
|
66
|
+
|
|
67
|
+
if getv(from_object, ['metadata']) is not None:
|
|
68
|
+
setv(to_object, ['metadata'], getv(from_object, ['metadata']))
|
|
69
|
+
|
|
70
|
+
if getv(from_object, ['done']) is not None:
|
|
71
|
+
setv(to_object, ['done'], getv(from_object, ['done']))
|
|
72
|
+
|
|
73
|
+
if getv(from_object, ['error']) is not None:
|
|
74
|
+
setv(to_object, ['error'], getv(from_object, ['error']))
|
|
75
|
+
|
|
76
|
+
if getv(from_object, ['response', 'generateVideoResponse']) is not None:
|
|
86
77
|
setv(
|
|
87
78
|
to_object,
|
|
88
|
-
['
|
|
89
|
-
|
|
79
|
+
['response'],
|
|
80
|
+
_GenerateVideosResponse_from_mldev(
|
|
81
|
+
getv(from_object, ['response', 'generateVideoResponse']), to_object
|
|
82
|
+
),
|
|
90
83
|
)
|
|
91
84
|
|
|
92
|
-
if getv(from_object, ['
|
|
93
|
-
setv(
|
|
85
|
+
if getv(from_object, ['response', 'generateVideoResponse']) is not None:
|
|
86
|
+
setv(
|
|
87
|
+
to_object,
|
|
88
|
+
['result'],
|
|
89
|
+
_GenerateVideosResponse_from_mldev(
|
|
90
|
+
getv(from_object, ['response', 'generateVideoResponse']), to_object
|
|
91
|
+
),
|
|
92
|
+
)
|
|
94
93
|
|
|
95
94
|
return to_object
|
|
96
95
|
|
|
97
96
|
|
|
98
|
-
def
|
|
97
|
+
def _GenerateVideosOperation_from_vertex(
|
|
99
98
|
from_object: Union[dict[str, Any], object],
|
|
100
99
|
parent_object: Optional[dict[str, Any]] = None,
|
|
101
100
|
) -> dict[str, Any]:
|
|
102
101
|
to_object: dict[str, Any] = {}
|
|
103
|
-
if getv(from_object, ['
|
|
104
|
-
setv(to_object, ['
|
|
102
|
+
if getv(from_object, ['name']) is not None:
|
|
103
|
+
setv(to_object, ['name'], getv(from_object, ['name']))
|
|
105
104
|
|
|
106
|
-
if getv(from_object, ['
|
|
107
|
-
setv(
|
|
108
|
-
to_object,
|
|
109
|
-
['video_bytes'],
|
|
110
|
-
base_t.t_bytes(getv(from_object, ['video', 'encodedVideo'])),
|
|
111
|
-
)
|
|
105
|
+
if getv(from_object, ['metadata']) is not None:
|
|
106
|
+
setv(to_object, ['metadata'], getv(from_object, ['metadata']))
|
|
112
107
|
|
|
113
|
-
if getv(from_object, ['
|
|
114
|
-
setv(to_object, ['
|
|
108
|
+
if getv(from_object, ['done']) is not None:
|
|
109
|
+
setv(to_object, ['done'], getv(from_object, ['done']))
|
|
115
110
|
|
|
116
|
-
|
|
111
|
+
if getv(from_object, ['error']) is not None:
|
|
112
|
+
setv(to_object, ['error'], getv(from_object, ['error']))
|
|
117
113
|
|
|
114
|
+
if getv(from_object, ['response']) is not None:
|
|
115
|
+
setv(
|
|
116
|
+
to_object,
|
|
117
|
+
['response'],
|
|
118
|
+
_GenerateVideosResponse_from_vertex(
|
|
119
|
+
getv(from_object, ['response']), to_object
|
|
120
|
+
),
|
|
121
|
+
)
|
|
118
122
|
|
|
119
|
-
|
|
120
|
-
from_object: Union[dict[str, Any], object],
|
|
121
|
-
parent_object: Optional[dict[str, Any]] = None,
|
|
122
|
-
) -> dict[str, Any]:
|
|
123
|
-
to_object: dict[str, Any] = {}
|
|
124
|
-
if getv(from_object, ['_self']) is not None:
|
|
123
|
+
if getv(from_object, ['response']) is not None:
|
|
125
124
|
setv(
|
|
126
125
|
to_object,
|
|
127
|
-
['
|
|
128
|
-
|
|
126
|
+
['result'],
|
|
127
|
+
_GenerateVideosResponse_from_vertex(
|
|
128
|
+
getv(from_object, ['response']), to_object
|
|
129
|
+
),
|
|
129
130
|
)
|
|
130
131
|
|
|
131
132
|
return to_object
|
|
@@ -163,62 +164,50 @@ def _GenerateVideosResponse_from_mldev(
|
|
|
163
164
|
return to_object
|
|
164
165
|
|
|
165
166
|
|
|
166
|
-
def
|
|
167
|
+
def _GenerateVideosResponse_from_vertex(
|
|
167
168
|
from_object: Union[dict[str, Any], object],
|
|
168
169
|
parent_object: Optional[dict[str, Any]] = None,
|
|
169
170
|
) -> dict[str, Any]:
|
|
170
171
|
to_object: dict[str, Any] = {}
|
|
171
|
-
if getv(from_object, ['
|
|
172
|
-
setv(
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
if getv(from_object, ['error']) is not None:
|
|
181
|
-
setv(to_object, ['error'], getv(from_object, ['error']))
|
|
172
|
+
if getv(from_object, ['videos']) is not None:
|
|
173
|
+
setv(
|
|
174
|
+
to_object,
|
|
175
|
+
['generated_videos'],
|
|
176
|
+
[
|
|
177
|
+
_GeneratedVideo_from_vertex(item, to_object)
|
|
178
|
+
for item in getv(from_object, ['videos'])
|
|
179
|
+
],
|
|
180
|
+
)
|
|
182
181
|
|
|
183
|
-
if getv(from_object, ['
|
|
182
|
+
if getv(from_object, ['raiMediaFilteredCount']) is not None:
|
|
184
183
|
setv(
|
|
185
184
|
to_object,
|
|
186
|
-
['
|
|
187
|
-
|
|
188
|
-
getv(from_object, ['response', 'generateVideoResponse']), to_object
|
|
189
|
-
),
|
|
185
|
+
['rai_media_filtered_count'],
|
|
186
|
+
getv(from_object, ['raiMediaFilteredCount']),
|
|
190
187
|
)
|
|
191
188
|
|
|
192
|
-
if getv(from_object, ['
|
|
189
|
+
if getv(from_object, ['raiMediaFilteredReasons']) is not None:
|
|
193
190
|
setv(
|
|
194
191
|
to_object,
|
|
195
|
-
['
|
|
196
|
-
|
|
197
|
-
getv(from_object, ['response', 'generateVideoResponse']), to_object
|
|
198
|
-
),
|
|
192
|
+
['rai_media_filtered_reasons'],
|
|
193
|
+
getv(from_object, ['raiMediaFilteredReasons']),
|
|
199
194
|
)
|
|
200
195
|
|
|
201
196
|
return to_object
|
|
202
197
|
|
|
203
198
|
|
|
204
|
-
def
|
|
199
|
+
def _GeneratedVideo_from_mldev(
|
|
205
200
|
from_object: Union[dict[str, Any], object],
|
|
206
201
|
parent_object: Optional[dict[str, Any]] = None,
|
|
207
202
|
) -> dict[str, Any]:
|
|
208
203
|
to_object: dict[str, Any] = {}
|
|
209
|
-
if getv(from_object, ['
|
|
210
|
-
setv(to_object, ['uri'], getv(from_object, ['gcsUri']))
|
|
211
|
-
|
|
212
|
-
if getv(from_object, ['bytesBase64Encoded']) is not None:
|
|
204
|
+
if getv(from_object, ['video']) is not None:
|
|
213
205
|
setv(
|
|
214
206
|
to_object,
|
|
215
|
-
['
|
|
216
|
-
|
|
207
|
+
['video'],
|
|
208
|
+
_Video_from_mldev(getv(from_object, ['video']), to_object),
|
|
217
209
|
)
|
|
218
210
|
|
|
219
|
-
if getv(from_object, ['mimeType']) is not None:
|
|
220
|
-
setv(to_object, ['mime_type'], getv(from_object, ['mimeType']))
|
|
221
|
-
|
|
222
211
|
return to_object
|
|
223
212
|
|
|
224
213
|
|
|
@@ -237,39 +226,37 @@ def _GeneratedVideo_from_vertex(
|
|
|
237
226
|
return to_object
|
|
238
227
|
|
|
239
228
|
|
|
240
|
-
def
|
|
229
|
+
def _GetOperationParameters_to_mldev(
|
|
241
230
|
from_object: Union[dict[str, Any], object],
|
|
242
231
|
parent_object: Optional[dict[str, Any]] = None,
|
|
243
232
|
) -> dict[str, Any]:
|
|
244
233
|
to_object: dict[str, Any] = {}
|
|
245
|
-
if getv(from_object, ['
|
|
234
|
+
if getv(from_object, ['operation_name']) is not None:
|
|
246
235
|
setv(
|
|
247
236
|
to_object,
|
|
248
|
-
['
|
|
249
|
-
[
|
|
250
|
-
_GeneratedVideo_from_vertex(item, to_object)
|
|
251
|
-
for item in getv(from_object, ['videos'])
|
|
252
|
-
],
|
|
237
|
+
['_url', 'operationName'],
|
|
238
|
+
getv(from_object, ['operation_name']),
|
|
253
239
|
)
|
|
254
240
|
|
|
255
|
-
|
|
256
|
-
setv(
|
|
257
|
-
to_object,
|
|
258
|
-
['rai_media_filtered_count'],
|
|
259
|
-
getv(from_object, ['raiMediaFilteredCount']),
|
|
260
|
-
)
|
|
241
|
+
return to_object
|
|
261
242
|
|
|
262
|
-
|
|
243
|
+
|
|
244
|
+
def _GetOperationParameters_to_vertex(
|
|
245
|
+
from_object: Union[dict[str, Any], object],
|
|
246
|
+
parent_object: Optional[dict[str, Any]] = None,
|
|
247
|
+
) -> dict[str, Any]:
|
|
248
|
+
to_object: dict[str, Any] = {}
|
|
249
|
+
if getv(from_object, ['operation_name']) is not None:
|
|
263
250
|
setv(
|
|
264
251
|
to_object,
|
|
265
|
-
['
|
|
266
|
-
getv(from_object, ['
|
|
252
|
+
['_url', 'operationName'],
|
|
253
|
+
getv(from_object, ['operation_name']),
|
|
267
254
|
)
|
|
268
255
|
|
|
269
256
|
return to_object
|
|
270
257
|
|
|
271
258
|
|
|
272
|
-
def
|
|
259
|
+
def _ImportFileOperation_from_mldev(
|
|
273
260
|
from_object: Union[dict[str, Any], object],
|
|
274
261
|
parent_object: Optional[dict[str, Any]] = None,
|
|
275
262
|
) -> dict[str, Any]:
|
|
@@ -290,18 +277,118 @@ def _GenerateVideosOperation_from_vertex(
|
|
|
290
277
|
setv(
|
|
291
278
|
to_object,
|
|
292
279
|
['response'],
|
|
293
|
-
|
|
280
|
+
_ImportFileResponse_from_mldev(
|
|
294
281
|
getv(from_object, ['response']), to_object
|
|
295
282
|
),
|
|
296
283
|
)
|
|
297
284
|
|
|
285
|
+
return to_object
|
|
286
|
+
|
|
287
|
+
|
|
288
|
+
def _ImportFileResponse_from_mldev(
|
|
289
|
+
from_object: Union[dict[str, Any], object],
|
|
290
|
+
parent_object: Optional[dict[str, Any]] = None,
|
|
291
|
+
) -> dict[str, Any]:
|
|
292
|
+
to_object: dict[str, Any] = {}
|
|
293
|
+
if getv(from_object, ['sdkHttpResponse']) is not None:
|
|
294
|
+
setv(
|
|
295
|
+
to_object, ['sdk_http_response'], getv(from_object, ['sdkHttpResponse'])
|
|
296
|
+
)
|
|
297
|
+
|
|
298
|
+
if getv(from_object, ['parent']) is not None:
|
|
299
|
+
setv(to_object, ['parent'], getv(from_object, ['parent']))
|
|
300
|
+
|
|
301
|
+
if getv(from_object, ['documentName']) is not None:
|
|
302
|
+
setv(to_object, ['document_name'], getv(from_object, ['documentName']))
|
|
303
|
+
|
|
304
|
+
return to_object
|
|
305
|
+
|
|
306
|
+
|
|
307
|
+
def _UploadToFileSearchStoreOperation_from_mldev(
|
|
308
|
+
from_object: Union[dict[str, Any], object],
|
|
309
|
+
parent_object: Optional[dict[str, Any]] = None,
|
|
310
|
+
) -> dict[str, Any]:
|
|
311
|
+
to_object: dict[str, Any] = {}
|
|
312
|
+
if getv(from_object, ['name']) is not None:
|
|
313
|
+
setv(to_object, ['name'], getv(from_object, ['name']))
|
|
314
|
+
|
|
315
|
+
if getv(from_object, ['metadata']) is not None:
|
|
316
|
+
setv(to_object, ['metadata'], getv(from_object, ['metadata']))
|
|
317
|
+
|
|
318
|
+
if getv(from_object, ['done']) is not None:
|
|
319
|
+
setv(to_object, ['done'], getv(from_object, ['done']))
|
|
320
|
+
|
|
321
|
+
if getv(from_object, ['error']) is not None:
|
|
322
|
+
setv(to_object, ['error'], getv(from_object, ['error']))
|
|
323
|
+
|
|
298
324
|
if getv(from_object, ['response']) is not None:
|
|
299
325
|
setv(
|
|
300
326
|
to_object,
|
|
301
|
-
['
|
|
302
|
-
|
|
327
|
+
['response'],
|
|
328
|
+
_UploadToFileSearchStoreResponse_from_mldev(
|
|
303
329
|
getv(from_object, ['response']), to_object
|
|
304
330
|
),
|
|
305
331
|
)
|
|
306
332
|
|
|
307
333
|
return to_object
|
|
334
|
+
|
|
335
|
+
|
|
336
|
+
def _UploadToFileSearchStoreResponse_from_mldev(
|
|
337
|
+
from_object: Union[dict[str, Any], object],
|
|
338
|
+
parent_object: Optional[dict[str, Any]] = None,
|
|
339
|
+
) -> dict[str, Any]:
|
|
340
|
+
to_object: dict[str, Any] = {}
|
|
341
|
+
if getv(from_object, ['sdkHttpResponse']) is not None:
|
|
342
|
+
setv(
|
|
343
|
+
to_object, ['sdk_http_response'], getv(from_object, ['sdkHttpResponse'])
|
|
344
|
+
)
|
|
345
|
+
|
|
346
|
+
if getv(from_object, ['parent']) is not None:
|
|
347
|
+
setv(to_object, ['parent'], getv(from_object, ['parent']))
|
|
348
|
+
|
|
349
|
+
if getv(from_object, ['documentName']) is not None:
|
|
350
|
+
setv(to_object, ['document_name'], getv(from_object, ['documentName']))
|
|
351
|
+
|
|
352
|
+
return to_object
|
|
353
|
+
|
|
354
|
+
|
|
355
|
+
def _Video_from_mldev(
|
|
356
|
+
from_object: Union[dict[str, Any], object],
|
|
357
|
+
parent_object: Optional[dict[str, Any]] = None,
|
|
358
|
+
) -> dict[str, Any]:
|
|
359
|
+
to_object: dict[str, Any] = {}
|
|
360
|
+
if getv(from_object, ['uri']) is not None:
|
|
361
|
+
setv(to_object, ['uri'], getv(from_object, ['uri']))
|
|
362
|
+
|
|
363
|
+
if getv(from_object, ['encodedVideo']) is not None:
|
|
364
|
+
setv(
|
|
365
|
+
to_object,
|
|
366
|
+
['video_bytes'],
|
|
367
|
+
base_t.t_bytes(getv(from_object, ['encodedVideo'])),
|
|
368
|
+
)
|
|
369
|
+
|
|
370
|
+
if getv(from_object, ['encoding']) is not None:
|
|
371
|
+
setv(to_object, ['mime_type'], getv(from_object, ['encoding']))
|
|
372
|
+
|
|
373
|
+
return to_object
|
|
374
|
+
|
|
375
|
+
|
|
376
|
+
def _Video_from_vertex(
|
|
377
|
+
from_object: Union[dict[str, Any], object],
|
|
378
|
+
parent_object: Optional[dict[str, Any]] = None,
|
|
379
|
+
) -> dict[str, Any]:
|
|
380
|
+
to_object: dict[str, Any] = {}
|
|
381
|
+
if getv(from_object, ['gcsUri']) is not None:
|
|
382
|
+
setv(to_object, ['uri'], getv(from_object, ['gcsUri']))
|
|
383
|
+
|
|
384
|
+
if getv(from_object, ['bytesBase64Encoded']) is not None:
|
|
385
|
+
setv(
|
|
386
|
+
to_object,
|
|
387
|
+
['video_bytes'],
|
|
388
|
+
base_t.t_bytes(getv(from_object, ['bytesBase64Encoded'])),
|
|
389
|
+
)
|
|
390
|
+
|
|
391
|
+
if getv(from_object, ['mimeType']) is not None:
|
|
392
|
+
setv(to_object, ['mime_type'], getv(from_object, ['mimeType']))
|
|
393
|
+
|
|
394
|
+
return to_object
|
|
@@ -17,17 +17,16 @@
|
|
|
17
17
|
|
|
18
18
|
import base64
|
|
19
19
|
import copy
|
|
20
|
-
import
|
|
20
|
+
import contextlib
|
|
21
21
|
import enum
|
|
22
22
|
import inspect
|
|
23
23
|
import io
|
|
24
24
|
import json
|
|
25
25
|
import os
|
|
26
26
|
import re
|
|
27
|
-
from typing import Any, Literal, Optional, Union
|
|
27
|
+
from typing import Any, Literal, Optional, Union, Iterator, AsyncIterator
|
|
28
28
|
|
|
29
29
|
import google.auth
|
|
30
|
-
from requests.exceptions import HTTPError
|
|
31
30
|
|
|
32
31
|
from . import errors
|
|
33
32
|
from ._api_client import BaseApiClient
|
|
@@ -35,7 +34,6 @@ from ._api_client import HttpRequest
|
|
|
35
34
|
from ._api_client import HttpResponse
|
|
36
35
|
from ._common import BaseModel
|
|
37
36
|
from .types import HttpOptions, HttpOptionsOrDict
|
|
38
|
-
from .types import GenerateVideosOperation
|
|
39
37
|
|
|
40
38
|
|
|
41
39
|
def to_snake_case(name: str) -> str:
|
|
@@ -57,8 +55,13 @@ def _normalize_json_case(obj: Any) -> Any:
|
|
|
57
55
|
return [_normalize_json_case(item) for item in obj]
|
|
58
56
|
elif isinstance(obj, enum.Enum):
|
|
59
57
|
return obj.value
|
|
60
|
-
|
|
61
|
-
|
|
58
|
+
elif isinstance(obj, str):
|
|
59
|
+
# Python >= 3.14 has a new division by zero error message.
|
|
60
|
+
if 'division by zero' in obj:
|
|
61
|
+
return obj.replace(
|
|
62
|
+
'division by zero', 'integer division or modulo by zero'
|
|
63
|
+
)
|
|
64
|
+
return obj
|
|
62
65
|
|
|
63
66
|
|
|
64
67
|
def _equals_ignore_key_case(obj1: Any, obj2: Any) -> bool:
|
|
@@ -89,7 +92,7 @@ def _equals_ignore_key_case(obj1: Any, obj2: Any) -> bool:
|
|
|
89
92
|
|
|
90
93
|
def _redact_version_numbers(version_string: str) -> str:
|
|
91
94
|
"""Redacts version numbers in the form x.y.z from a string."""
|
|
92
|
-
return re.sub(r'\d+\.\d+\.\d+', '{VERSION_NUMBER}', version_string)
|
|
95
|
+
return re.sub(r'\d+\.\d+\.\d+[a-zA-Z0-9]*', '{VERSION_NUMBER}', version_string)
|
|
93
96
|
|
|
94
97
|
|
|
95
98
|
def _redact_language_label(language_label: str) -> str:
|
|
@@ -139,7 +142,7 @@ def _redact_request_url(url: str) -> str:
|
|
|
139
142
|
result,
|
|
140
143
|
)
|
|
141
144
|
result = re.sub(
|
|
142
|
-
r'
|
|
145
|
+
r'.*generativelanguage.*.googleapis.com/[^/]+',
|
|
143
146
|
'{MLDEV_URL_PREFIX}',
|
|
144
147
|
result,
|
|
145
148
|
)
|
|
@@ -206,6 +209,22 @@ def pop_undeterministic_headers(headers: dict[str, str]) -> None:
|
|
|
206
209
|
headers.pop('Server-Timing', None) # pytype: disable=attribute-error
|
|
207
210
|
|
|
208
211
|
|
|
212
|
+
@contextlib.contextmanager
|
|
213
|
+
def _record_on_api_error(client: 'ReplayApiClient', http_request: HttpRequest) -> Iterator[None]:
|
|
214
|
+
try:
|
|
215
|
+
yield
|
|
216
|
+
except errors.APIError as e:
|
|
217
|
+
client._record_interaction(http_request, e)
|
|
218
|
+
raise e
|
|
219
|
+
|
|
220
|
+
@contextlib.asynccontextmanager
|
|
221
|
+
async def _async_record_on_api_error(client: 'ReplayApiClient', http_request: HttpRequest) -> AsyncIterator[None]:
|
|
222
|
+
try:
|
|
223
|
+
yield
|
|
224
|
+
except errors.APIError as e:
|
|
225
|
+
client._record_interaction(http_request, e)
|
|
226
|
+
raise e
|
|
227
|
+
|
|
209
228
|
class ReplayRequest(BaseModel):
|
|
210
229
|
"""Represents a single request in a replay."""
|
|
211
230
|
|
|
@@ -256,6 +275,7 @@ class ReplayApiClient(BaseApiClient):
|
|
|
256
275
|
project: Optional[str] = None,
|
|
257
276
|
location: Optional[str] = None,
|
|
258
277
|
http_options: Optional[HttpOptions] = None,
|
|
278
|
+
private: bool = False,
|
|
259
279
|
):
|
|
260
280
|
super().__init__(
|
|
261
281
|
vertexai=vertexai,
|
|
@@ -274,6 +294,7 @@ class ReplayApiClient(BaseApiClient):
|
|
|
274
294
|
self.replay_session: Union[ReplayFile, None] = None
|
|
275
295
|
self._mode = mode
|
|
276
296
|
self._replay_id = replay_id
|
|
297
|
+
self._private = private
|
|
277
298
|
|
|
278
299
|
def initialize_replay_session(self, replay_id: str) -> None:
|
|
279
300
|
self._replay_id = replay_id
|
|
@@ -394,6 +415,8 @@ class ReplayApiClient(BaseApiClient):
|
|
|
394
415
|
http_request: HttpRequest,
|
|
395
416
|
interaction: ReplayInteraction,
|
|
396
417
|
) -> None:
|
|
418
|
+
_debug_print(f'http_request.url: {http_request.url}')
|
|
419
|
+
_debug_print(f'interaction.request.url: {interaction.request.url}')
|
|
397
420
|
assert http_request.url == interaction.request.url
|
|
398
421
|
assert http_request.headers == interaction.request.headers, (
|
|
399
422
|
'Request headers mismatch:\n'
|
|
@@ -466,7 +489,9 @@ class ReplayApiClient(BaseApiClient):
|
|
|
466
489
|
|
|
467
490
|
if isinstance(response_model, list):
|
|
468
491
|
response_model = response_model[0]
|
|
469
|
-
|
|
492
|
+
_debug_print(
|
|
493
|
+
f'response_model: {response_model.model_dump(exclude_none=True)}'
|
|
494
|
+
)
|
|
470
495
|
actual = response_model.model_dump(exclude_none=True, mode='json')
|
|
471
496
|
expected = interaction.response.sdk_response_segments[
|
|
472
497
|
self._sdk_response_index
|
|
@@ -479,16 +504,18 @@ class ReplayApiClient(BaseApiClient):
|
|
|
479
504
|
):
|
|
480
505
|
if 'body' in expected['sdk_http_response']:
|
|
481
506
|
raw_body = expected['sdk_http_response']['body']
|
|
482
|
-
|
|
483
|
-
|
|
507
|
+
_debug_print(f'raw_body length: {len(raw_body)}')
|
|
508
|
+
_debug_print(f'raw_body: {raw_body}')
|
|
484
509
|
if isinstance(raw_body, str) and raw_body != '':
|
|
485
510
|
raw_body = json.loads(raw_body)
|
|
486
511
|
raw_body = json.dumps(raw_body)
|
|
487
512
|
expected['sdk_http_response']['body'] = raw_body
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
513
|
+
if not self._private:
|
|
514
|
+
assert (
|
|
515
|
+
actual == expected
|
|
516
|
+
), f'SDK response mismatch:\nActual: {actual}\nExpected: {expected}'
|
|
517
|
+
else:
|
|
518
|
+
_debug_print(f'Expected SDK response mismatch:\nActual: {actual}\nExpected: {expected}')
|
|
492
519
|
self._sdk_response_index += 1
|
|
493
520
|
|
|
494
521
|
def _request(
|
|
@@ -500,11 +527,8 @@ class ReplayApiClient(BaseApiClient):
|
|
|
500
527
|
self._initialize_replay_session_if_not_loaded()
|
|
501
528
|
if self._should_call_api():
|
|
502
529
|
_debug_print('api mode request: %s' % http_request)
|
|
503
|
-
|
|
530
|
+
with _record_on_api_error(self, http_request):
|
|
504
531
|
result = super()._request(http_request, http_options, stream)
|
|
505
|
-
except errors.APIError as e:
|
|
506
|
-
self._record_interaction(http_request, e)
|
|
507
|
-
raise e
|
|
508
532
|
if stream:
|
|
509
533
|
result_segments = []
|
|
510
534
|
for segment in result.segments():
|
|
@@ -529,13 +553,10 @@ class ReplayApiClient(BaseApiClient):
|
|
|
529
553
|
self._initialize_replay_session_if_not_loaded()
|
|
530
554
|
if self._should_call_api():
|
|
531
555
|
_debug_print('api mode request: %s' % http_request)
|
|
532
|
-
|
|
556
|
+
async with _async_record_on_api_error(self, http_request):
|
|
533
557
|
result = await super()._async_request(
|
|
534
558
|
http_request, http_options, stream
|
|
535
559
|
)
|
|
536
|
-
except errors.APIError as e:
|
|
537
|
-
self._record_interaction(http_request, e)
|
|
538
|
-
raise e
|
|
539
560
|
if stream:
|
|
540
561
|
result_segments = []
|
|
541
562
|
async for segment in result.async_segments():
|
|
@@ -575,16 +596,10 @@ class ReplayApiClient(BaseApiClient):
|
|
|
575
596
|
)
|
|
576
597
|
if self._should_call_api():
|
|
577
598
|
result: Union[str, HttpResponse]
|
|
578
|
-
|
|
599
|
+
with _record_on_api_error(self, request):
|
|
579
600
|
result = super().upload_file(
|
|
580
601
|
file_path, upload_url, upload_size, http_options=http_options
|
|
581
602
|
)
|
|
582
|
-
except HTTPError as e:
|
|
583
|
-
result = HttpResponse(
|
|
584
|
-
dict(e.response.headers), [json.dumps({'reason': e.response.reason})]
|
|
585
|
-
)
|
|
586
|
-
result.status_code = e.response.status_code
|
|
587
|
-
raise e
|
|
588
603
|
self._record_interaction(request, result)
|
|
589
604
|
return result
|
|
590
605
|
else:
|
|
@@ -614,16 +629,10 @@ class ReplayApiClient(BaseApiClient):
|
|
|
614
629
|
)
|
|
615
630
|
if self._should_call_api():
|
|
616
631
|
result: HttpResponse
|
|
617
|
-
|
|
632
|
+
async with _async_record_on_api_error(self, request):
|
|
618
633
|
result = await super().async_upload_file(
|
|
619
634
|
file_path, upload_url, upload_size, http_options=http_options
|
|
620
635
|
)
|
|
621
|
-
except HTTPError as e:
|
|
622
|
-
result = HttpResponse(
|
|
623
|
-
dict(e.response.headers), [json.dumps({'reason': e.response.reason})]
|
|
624
|
-
)
|
|
625
|
-
result.status_code = e.response.status_code
|
|
626
|
-
raise e
|
|
627
636
|
self._record_interaction(request, result)
|
|
628
637
|
return result
|
|
629
638
|
else:
|
|
@@ -637,14 +646,8 @@ class ReplayApiClient(BaseApiClient):
|
|
|
637
646
|
'get', path=path, request_dict={}, http_options=http_options
|
|
638
647
|
)
|
|
639
648
|
if self._should_call_api():
|
|
640
|
-
|
|
649
|
+
with _record_on_api_error(self, request):
|
|
641
650
|
result = super().download_file(path, http_options=http_options)
|
|
642
|
-
except HTTPError as e:
|
|
643
|
-
result = HttpResponse(
|
|
644
|
-
dict(e.response.headers), [json.dumps({'reason': e.response.reason})]
|
|
645
|
-
)
|
|
646
|
-
result.status_code = e.response.status_code
|
|
647
|
-
raise e
|
|
648
651
|
self._record_interaction(request, result)
|
|
649
652
|
return result
|
|
650
653
|
else:
|
|
@@ -658,16 +661,10 @@ class ReplayApiClient(BaseApiClient):
|
|
|
658
661
|
'get', path=path, request_dict={}, http_options=http_options
|
|
659
662
|
)
|
|
660
663
|
if self._should_call_api():
|
|
661
|
-
|
|
664
|
+
async with _async_record_on_api_error(self, request):
|
|
662
665
|
result = await super().async_download_file(
|
|
663
666
|
path, http_options=http_options
|
|
664
667
|
)
|
|
665
|
-
except HTTPError as e:
|
|
666
|
-
result = HttpResponse(
|
|
667
|
-
dict(e.response.headers), [json.dumps({'reason': e.response.reason})]
|
|
668
|
-
)
|
|
669
|
-
result.status_code = e.response.status_code
|
|
670
|
-
raise e
|
|
671
668
|
self._record_interaction(request, result)
|
|
672
669
|
return result
|
|
673
670
|
else:
|