google-genai 1.28.0__tar.gz → 1.29.0__tar.gz
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-1.28.0/google_genai.egg-info → google_genai-1.29.0}/PKG-INFO +2 -2
- {google_genai-1.28.0 → google_genai-1.29.0}/google/genai/_api_client.py +139 -54
- {google_genai-1.28.0 → google_genai-1.29.0}/google/genai/_automatic_function_calling_util.py +35 -7
- {google_genai-1.28.0 → google_genai-1.29.0}/google/genai/_live_converters.py +14 -0
- {google_genai-1.28.0 → google_genai-1.29.0}/google/genai/batches.py +19 -2
- {google_genai-1.28.0 → google_genai-1.29.0}/google/genai/errors.py +5 -2
- {google_genai-1.28.0 → google_genai-1.29.0}/google/genai/models.py +393 -12
- {google_genai-1.28.0 → google_genai-1.29.0}/google/genai/types.py +336 -39
- {google_genai-1.28.0 → google_genai-1.29.0}/google/genai/version.py +1 -1
- {google_genai-1.28.0 → google_genai-1.29.0/google_genai.egg-info}/PKG-INFO +2 -2
- {google_genai-1.28.0 → google_genai-1.29.0}/google_genai.egg-info/requires.txt +1 -1
- {google_genai-1.28.0 → google_genai-1.29.0}/pyproject.toml +2 -2
- {google_genai-1.28.0 → google_genai-1.29.0}/LICENSE +0 -0
- {google_genai-1.28.0 → google_genai-1.29.0}/MANIFEST.in +0 -0
- {google_genai-1.28.0 → google_genai-1.29.0}/README.md +0 -0
- {google_genai-1.28.0 → google_genai-1.29.0}/google/genai/__init__.py +0 -0
- {google_genai-1.28.0 → google_genai-1.29.0}/google/genai/_adapters.py +0 -0
- {google_genai-1.28.0 → google_genai-1.29.0}/google/genai/_api_module.py +0 -0
- {google_genai-1.28.0 → google_genai-1.29.0}/google/genai/_base_url.py +0 -0
- {google_genai-1.28.0 → google_genai-1.29.0}/google/genai/_common.py +0 -0
- {google_genai-1.28.0 → google_genai-1.29.0}/google/genai/_extra_utils.py +0 -0
- {google_genai-1.28.0 → google_genai-1.29.0}/google/genai/_mcp_utils.py +0 -0
- {google_genai-1.28.0 → google_genai-1.29.0}/google/genai/_replay_api_client.py +0 -0
- {google_genai-1.28.0 → google_genai-1.29.0}/google/genai/_test_api_client.py +0 -0
- {google_genai-1.28.0 → google_genai-1.29.0}/google/genai/_tokens_converters.py +0 -0
- {google_genai-1.28.0 → google_genai-1.29.0}/google/genai/_transformers.py +0 -0
- {google_genai-1.28.0 → google_genai-1.29.0}/google/genai/caches.py +0 -0
- {google_genai-1.28.0 → google_genai-1.29.0}/google/genai/chats.py +0 -0
- {google_genai-1.28.0 → google_genai-1.29.0}/google/genai/client.py +0 -0
- {google_genai-1.28.0 → google_genai-1.29.0}/google/genai/files.py +0 -0
- {google_genai-1.28.0 → google_genai-1.29.0}/google/genai/live.py +0 -0
- {google_genai-1.28.0 → google_genai-1.29.0}/google/genai/live_music.py +0 -0
- {google_genai-1.28.0 → google_genai-1.29.0}/google/genai/operations.py +0 -0
- {google_genai-1.28.0 → google_genai-1.29.0}/google/genai/pagers.py +0 -0
- {google_genai-1.28.0 → google_genai-1.29.0}/google/genai/py.typed +0 -0
- {google_genai-1.28.0 → google_genai-1.29.0}/google/genai/tokens.py +0 -0
- {google_genai-1.28.0 → google_genai-1.29.0}/google/genai/tunings.py +0 -0
- {google_genai-1.28.0 → google_genai-1.29.0}/google_genai.egg-info/SOURCES.txt +0 -0
- {google_genai-1.28.0 → google_genai-1.29.0}/google_genai.egg-info/dependency_links.txt +0 -0
- {google_genai-1.28.0 → google_genai-1.29.0}/google_genai.egg-info/top_level.txt +0 -0
- {google_genai-1.28.0 → google_genai-1.29.0}/setup.cfg +0 -0
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.4
|
2
2
|
Name: google-genai
|
3
|
-
Version: 1.
|
3
|
+
Version: 1.29.0
|
4
4
|
Summary: GenAI Python SDK
|
5
5
|
Author-email: Google LLC <googleapis-packages@google.com>
|
6
6
|
License: Apache-2.0
|
@@ -25,7 +25,7 @@ Requires-Dist: google-auth<3.0.0,>=2.14.1
|
|
25
25
|
Requires-Dist: httpx<1.0.0,>=0.28.1
|
26
26
|
Requires-Dist: pydantic<3.0.0,>=2.0.0
|
27
27
|
Requires-Dist: requests<3.0.0,>=2.28.1
|
28
|
-
Requires-Dist: tenacity<9.
|
28
|
+
Requires-Dist: tenacity<9.2.0,>=8.2.3
|
29
29
|
Requires-Dist: websockets<15.1.0,>=13.0.0
|
30
30
|
Requires-Dist: typing-extensions<5.0.0,>=4.11.0
|
31
31
|
Provides-Extra: aiohttp
|
@@ -20,23 +20,21 @@ The BaseApiClient is intended to be a private module and is subject to change.
|
|
20
20
|
"""
|
21
21
|
|
22
22
|
import asyncio
|
23
|
-
from collections.abc import
|
23
|
+
from collections.abc import Generator
|
24
24
|
import copy
|
25
25
|
from dataclasses import dataclass
|
26
|
-
import datetime
|
27
|
-
import http
|
28
26
|
import inspect
|
29
27
|
import io
|
30
28
|
import json
|
31
29
|
import logging
|
32
30
|
import math
|
33
31
|
import os
|
34
|
-
import ssl
|
35
32
|
import random
|
33
|
+
import ssl
|
36
34
|
import sys
|
37
35
|
import threading
|
38
36
|
import time
|
39
|
-
from typing import Any, AsyncIterator,
|
37
|
+
from typing import Any, AsyncIterator, Iterator, Optional, Tuple, TYPE_CHECKING, Union
|
40
38
|
from urllib.parse import urlparse
|
41
39
|
from urllib.parse import urlunparse
|
42
40
|
|
@@ -48,7 +46,6 @@ from google.auth.credentials import Credentials
|
|
48
46
|
from google.auth.transport.requests import Request
|
49
47
|
import httpx
|
50
48
|
from pydantic import BaseModel
|
51
|
-
from pydantic import Field
|
52
49
|
from pydantic import ValidationError
|
53
50
|
import tenacity
|
54
51
|
|
@@ -56,11 +53,11 @@ from . import _common
|
|
56
53
|
from . import errors
|
57
54
|
from . import version
|
58
55
|
from .types import HttpOptions
|
59
|
-
from .types import HttpOptionsDict
|
60
56
|
from .types import HttpOptionsOrDict
|
61
57
|
from .types import HttpResponse as SdkHttpResponse
|
62
58
|
from .types import HttpRetryOptions
|
63
59
|
|
60
|
+
|
64
61
|
try:
|
65
62
|
from websockets.asyncio.client import connect as ws_connect
|
66
63
|
except ModuleNotFoundError:
|
@@ -238,12 +235,12 @@ class HttpResponse:
|
|
238
235
|
self.headers = headers
|
239
236
|
elif isinstance(headers, httpx.Headers):
|
240
237
|
self.headers = {
|
241
|
-
|
242
|
-
|
238
|
+
key: ', '.join(headers.get_list(key)) for key in headers.keys()
|
239
|
+
}
|
243
240
|
elif type(headers).__name__ == 'CIMultiDictProxy':
|
244
241
|
self.headers = {
|
245
|
-
key: ', '.join(headers.getall(key))
|
246
|
-
|
242
|
+
key: ', '.join(headers.getall(key)) for key in headers.keys()
|
243
|
+
}
|
247
244
|
|
248
245
|
self.status_code: int = 200
|
249
246
|
self.response_stream = response_stream
|
@@ -265,68 +262,32 @@ class HttpResponse:
|
|
265
262
|
def json(self) -> Any:
|
266
263
|
if not self.response_stream[0]: # Empty response
|
267
264
|
return ''
|
268
|
-
return
|
265
|
+
return self._load_json_from_response(self.response_stream[0])
|
269
266
|
|
270
267
|
def segments(self) -> Generator[Any, None, None]:
|
271
268
|
if isinstance(self.response_stream, list):
|
272
269
|
# list of objects retrieved from replay or from non-streaming API.
|
273
270
|
for chunk in self.response_stream:
|
274
|
-
yield
|
271
|
+
yield self._load_json_from_response(chunk) if chunk else {}
|
275
272
|
elif self.response_stream is None:
|
276
273
|
yield from []
|
277
274
|
else:
|
278
275
|
# Iterator of objects retrieved from the API.
|
279
|
-
for chunk in self.
|
280
|
-
|
281
|
-
# In streaming mode, the chunk of JSON is prefixed with "data:" which
|
282
|
-
# we must strip before parsing.
|
283
|
-
if not isinstance(chunk, str):
|
284
|
-
chunk = chunk.decode('utf-8')
|
285
|
-
if chunk.startswith('data: '):
|
286
|
-
chunk = chunk[len('data: ') :]
|
287
|
-
yield json.loads(chunk)
|
276
|
+
for chunk in self._iter_response_stream():
|
277
|
+
yield self._load_json_from_response(chunk)
|
288
278
|
|
289
279
|
async def async_segments(self) -> AsyncIterator[Any]:
|
290
280
|
if isinstance(self.response_stream, list):
|
291
281
|
# list of objects retrieved from replay or from non-streaming API.
|
292
282
|
for chunk in self.response_stream:
|
293
|
-
yield
|
283
|
+
yield self._load_json_from_response(chunk) if chunk else {}
|
294
284
|
elif self.response_stream is None:
|
295
285
|
async for c in []: # type: ignore[attr-defined]
|
296
286
|
yield c
|
297
287
|
else:
|
298
288
|
# Iterator of objects retrieved from the API.
|
299
|
-
|
300
|
-
|
301
|
-
# This is httpx.Response.
|
302
|
-
if chunk:
|
303
|
-
# In async streaming mode, the chunk of JSON is prefixed with
|
304
|
-
# "data:" which we must strip before parsing.
|
305
|
-
if not isinstance(chunk, str):
|
306
|
-
chunk = chunk.decode('utf-8')
|
307
|
-
if chunk.startswith('data: '):
|
308
|
-
chunk = chunk[len('data: ') :]
|
309
|
-
yield json.loads(chunk)
|
310
|
-
elif hasattr(self.response_stream, 'content'):
|
311
|
-
# This is aiohttp.ClientResponse.
|
312
|
-
try:
|
313
|
-
while True:
|
314
|
-
chunk = await self.response_stream.content.readline()
|
315
|
-
if not chunk:
|
316
|
-
break
|
317
|
-
# In async streaming mode, the chunk of JSON is prefixed with
|
318
|
-
# "data:" which we must strip before parsing.
|
319
|
-
chunk = chunk.decode('utf-8')
|
320
|
-
if chunk.startswith('data: '):
|
321
|
-
chunk = chunk[len('data: ') :]
|
322
|
-
chunk = chunk.strip()
|
323
|
-
if chunk:
|
324
|
-
yield json.loads(chunk)
|
325
|
-
finally:
|
326
|
-
if hasattr(self, '_session') and self._session:
|
327
|
-
await self._session.close()
|
328
|
-
else:
|
329
|
-
raise ValueError('Error parsing streaming response.')
|
289
|
+
async for chunk in self._aiter_response_stream():
|
290
|
+
yield self._load_json_from_response(chunk)
|
330
291
|
|
331
292
|
def byte_segments(self) -> Generator[Union[bytes, Any], None, None]:
|
332
293
|
if isinstance(self.byte_stream, list):
|
@@ -345,6 +306,130 @@ class HttpResponse:
|
|
345
306
|
for attribute in dir(self):
|
346
307
|
response_payload[attribute] = copy.deepcopy(getattr(self, attribute))
|
347
308
|
|
309
|
+
def _iter_response_stream(self) -> Iterator[str]:
|
310
|
+
"""Iterates over chunks retrieved from the API."""
|
311
|
+
if not isinstance(self.response_stream, httpx.Response):
|
312
|
+
raise TypeError(
|
313
|
+
'Expected self.response_stream to be an httpx.Response object, '
|
314
|
+
f'but got {type(self.response_stream).__name__}.'
|
315
|
+
)
|
316
|
+
|
317
|
+
chunk = ''
|
318
|
+
balance = 0
|
319
|
+
for line in self.response_stream.iter_lines():
|
320
|
+
if not line:
|
321
|
+
continue
|
322
|
+
|
323
|
+
# In streaming mode, the response of JSON is prefixed with "data: " which
|
324
|
+
# we must strip before parsing.
|
325
|
+
if line.startswith('data: '):
|
326
|
+
yield line[len('data: '):]
|
327
|
+
continue
|
328
|
+
|
329
|
+
# When API returns an error message, it comes line by line. So we buffer
|
330
|
+
# the lines until a complete JSON string is read. A complete JSON string
|
331
|
+
# is found when the balance is 0.
|
332
|
+
for c in line:
|
333
|
+
if c == '{':
|
334
|
+
balance += 1
|
335
|
+
elif c == '}':
|
336
|
+
balance -= 1
|
337
|
+
|
338
|
+
chunk += line
|
339
|
+
if balance == 0:
|
340
|
+
yield chunk
|
341
|
+
chunk = ''
|
342
|
+
|
343
|
+
# If there is any remaining chunk, yield it.
|
344
|
+
if chunk:
|
345
|
+
yield chunk
|
346
|
+
|
347
|
+
async def _aiter_response_stream(self) -> AsyncIterator[str]:
|
348
|
+
"""Asynchronously iterates over chunks retrieved from the API."""
|
349
|
+
if not isinstance(
|
350
|
+
self.response_stream, (httpx.Response, aiohttp.ClientResponse)
|
351
|
+
):
|
352
|
+
raise TypeError(
|
353
|
+
'Expected self.response_stream to be an httpx.Response or'
|
354
|
+
' aiohttp.ClientResponse object, but got'
|
355
|
+
f' {type(self.response_stream).__name__}.'
|
356
|
+
)
|
357
|
+
|
358
|
+
chunk = ''
|
359
|
+
balance = 0
|
360
|
+
# httpx.Response has a dedicated async line iterator.
|
361
|
+
if isinstance(self.response_stream, httpx.Response):
|
362
|
+
async for line in self.response_stream.aiter_lines():
|
363
|
+
if not line:
|
364
|
+
continue
|
365
|
+
# In streaming mode, the response of JSON is prefixed with "data: "
|
366
|
+
# which we must strip before parsing.
|
367
|
+
if line.startswith('data: '):
|
368
|
+
yield line[len('data: '):]
|
369
|
+
continue
|
370
|
+
|
371
|
+
# When API returns an error message, it comes line by line. So we buffer
|
372
|
+
# the lines until a complete JSON string is read. A complete JSON string
|
373
|
+
# is found when the balance is 0.
|
374
|
+
for c in line:
|
375
|
+
if c == '{':
|
376
|
+
balance += 1
|
377
|
+
elif c == '}':
|
378
|
+
balance -= 1
|
379
|
+
|
380
|
+
chunk += line
|
381
|
+
if balance == 0:
|
382
|
+
yield chunk
|
383
|
+
chunk = ''
|
384
|
+
|
385
|
+
# aiohttp.ClientResponse uses a content stream that we read line by line.
|
386
|
+
elif isinstance(self.response_stream, aiohttp.ClientResponse):
|
387
|
+
while True:
|
388
|
+
# Read a line from the stream. This returns bytes.
|
389
|
+
line_bytes = await self.response_stream.content.readline()
|
390
|
+
if not line_bytes:
|
391
|
+
break
|
392
|
+
# Decode the bytes and remove trailing whitespace and newlines.
|
393
|
+
line = line_bytes.decode('utf-8').rstrip()
|
394
|
+
if not line:
|
395
|
+
continue
|
396
|
+
|
397
|
+
# In streaming mode, the response of JSON is prefixed with "data: "
|
398
|
+
# which we must strip before parsing.
|
399
|
+
if line.startswith('data: '):
|
400
|
+
yield line[len('data: '):]
|
401
|
+
continue
|
402
|
+
|
403
|
+
# When API returns an error message, it comes line by line. So we buffer
|
404
|
+
# the lines until a complete JSON string is read. A complete JSON string
|
405
|
+
# is found when the balance is 0.
|
406
|
+
for c in line:
|
407
|
+
if c == '{':
|
408
|
+
balance += 1
|
409
|
+
elif c == '}':
|
410
|
+
balance -= 1
|
411
|
+
|
412
|
+
chunk += line
|
413
|
+
if balance == 0:
|
414
|
+
yield chunk
|
415
|
+
chunk = ''
|
416
|
+
|
417
|
+
# If there is any remaining chunk, yield it.
|
418
|
+
if chunk:
|
419
|
+
yield chunk
|
420
|
+
|
421
|
+
if hasattr(self, '_session') and self._session:
|
422
|
+
await self._session.close()
|
423
|
+
|
424
|
+
@classmethod
|
425
|
+
def _load_json_from_response(cls, response: Any) -> Any:
|
426
|
+
"""Loads JSON from the response, or raises an error if the parsing fails."""
|
427
|
+
try:
|
428
|
+
return json.loads(response)
|
429
|
+
except json.JSONDecodeError as e:
|
430
|
+
raise errors.UnknownApiResponseError(
|
431
|
+
f'Failed to parse response as JSON. Raw response: {response}'
|
432
|
+
) from e
|
348
433
|
|
349
434
|
# Default retry options.
|
350
435
|
# The config is based on https://cloud.google.com/storage/docs/retry-strategy.
|
{google_genai-1.28.0 → google_genai-1.29.0}/google/genai/_automatic_function_calling_util.py
RENAMED
@@ -41,6 +41,39 @@ _py_builtin_type_to_schema_type = {
|
|
41
41
|
}
|
42
42
|
|
43
43
|
|
44
|
+
def _raise_for_unsupported_param(
|
45
|
+
param: inspect.Parameter, func_name: str, exception: Union[Exception, type[Exception]]
|
46
|
+
) -> None:
|
47
|
+
raise ValueError(
|
48
|
+
f'Failed to parse the parameter {param} of function {func_name} for'
|
49
|
+
' automatic function calling.Automatic function calling works best with'
|
50
|
+
' simpler function signature schema, consider manually parsing your'
|
51
|
+
f' function declaration for function {func_name}.'
|
52
|
+
) from exception
|
53
|
+
|
54
|
+
|
55
|
+
def _handle_params_as_deferred_annotations(param: inspect.Parameter, annotation_under_future: dict[str, Any], name: str) -> inspect.Parameter:
|
56
|
+
"""Catches the case when type hints are stored as strings."""
|
57
|
+
if isinstance(param.annotation, str):
|
58
|
+
param = param.replace(annotation=annotation_under_future[name])
|
59
|
+
return param
|
60
|
+
|
61
|
+
|
62
|
+
def _add_unevaluated_items_to_fixed_len_tuple_schema(
|
63
|
+
json_schema: dict[str, Any]
|
64
|
+
) -> dict[str, Any]:
|
65
|
+
if (
|
66
|
+
json_schema.get('maxItems')
|
67
|
+
and (
|
68
|
+
json_schema.get('prefixItems')
|
69
|
+
and len(json_schema['prefixItems']) == json_schema['maxItems']
|
70
|
+
)
|
71
|
+
and json_schema.get('type') == 'array'
|
72
|
+
):
|
73
|
+
json_schema['unevaluatedItems'] = False
|
74
|
+
return json_schema
|
75
|
+
|
76
|
+
|
44
77
|
def _is_builtin_primitive_or_compound(
|
45
78
|
annotation: inspect.Parameter.annotation, # type: ignore[valid-type]
|
46
79
|
) -> bool:
|
@@ -92,7 +125,7 @@ def _is_default_value_compatible(
|
|
92
125
|
return False
|
93
126
|
|
94
127
|
|
95
|
-
def _parse_schema_from_parameter(
|
128
|
+
def _parse_schema_from_parameter( # type: ignore[return]
|
96
129
|
api_option: Literal['VERTEX_AI', 'GEMINI_API'],
|
97
130
|
param: inspect.Parameter,
|
98
131
|
func_name: str,
|
@@ -267,12 +300,7 @@ def _parse_schema_from_parameter(
|
|
267
300
|
)
|
268
301
|
schema.required = _get_required_fields(schema)
|
269
302
|
return schema
|
270
|
-
|
271
|
-
f'Failed to parse the parameter {param} of function {func_name} for'
|
272
|
-
' automatic function calling.Automatic function calling works best with'
|
273
|
-
' simpler function signature schema, consider manually parsing your'
|
274
|
-
f' function declaration for function {func_name}.'
|
275
|
-
)
|
303
|
+
_raise_for_unsupported_param(param, func_name, ValueError)
|
276
304
|
|
277
305
|
|
278
306
|
def _get_required_fields(schema: types.Schema) -> Optional[list[str]]:
|
@@ -1098,6 +1098,13 @@ def _LiveMusicGenerationConfig_to_mldev(
|
|
1098
1098
|
getv(from_object, ['only_bass_and_drums']),
|
1099
1099
|
)
|
1100
1100
|
|
1101
|
+
if getv(from_object, ['music_generation_mode']) is not None:
|
1102
|
+
setv(
|
1103
|
+
to_object,
|
1104
|
+
['musicGenerationMode'],
|
1105
|
+
getv(from_object, ['music_generation_mode']),
|
1106
|
+
)
|
1107
|
+
|
1101
1108
|
return to_object
|
1102
1109
|
|
1103
1110
|
|
@@ -2871,6 +2878,13 @@ def _LiveMusicGenerationConfig_from_mldev(
|
|
2871
2878
|
getv(from_object, ['onlyBassAndDrums']),
|
2872
2879
|
)
|
2873
2880
|
|
2881
|
+
if getv(from_object, ['musicGenerationMode']) is not None:
|
2882
|
+
setv(
|
2883
|
+
to_object,
|
2884
|
+
['music_generation_mode'],
|
2885
|
+
getv(from_object, ['musicGenerationMode']),
|
2886
|
+
)
|
2887
|
+
|
2874
2888
|
return to_object
|
2875
2889
|
|
2876
2890
|
|
@@ -1492,6 +1492,9 @@ def _GenerateContentResponse_from_mldev(
|
|
1492
1492
|
if getv(from_object, ['promptFeedback']) is not None:
|
1493
1493
|
setv(to_object, ['prompt_feedback'], getv(from_object, ['promptFeedback']))
|
1494
1494
|
|
1495
|
+
if getv(from_object, ['responseId']) is not None:
|
1496
|
+
setv(to_object, ['response_id'], getv(from_object, ['responseId']))
|
1497
|
+
|
1495
1498
|
if getv(from_object, ['usageMetadata']) is not None:
|
1496
1499
|
setv(to_object, ['usage_metadata'], getv(from_object, ['usageMetadata']))
|
1497
1500
|
|
@@ -1648,6 +1651,11 @@ def _DeleteResourceJob_from_mldev(
|
|
1648
1651
|
parent_object: Optional[dict[str, Any]] = None,
|
1649
1652
|
) -> dict[str, Any]:
|
1650
1653
|
to_object: dict[str, Any] = {}
|
1654
|
+
if getv(from_object, ['sdkHttpResponse']) is not None:
|
1655
|
+
setv(
|
1656
|
+
to_object, ['sdk_http_response'], getv(from_object, ['sdkHttpResponse'])
|
1657
|
+
)
|
1658
|
+
|
1651
1659
|
if getv(from_object, ['name']) is not None:
|
1652
1660
|
setv(to_object, ['name'], getv(from_object, ['name']))
|
1653
1661
|
|
@@ -1815,6 +1823,11 @@ def _DeleteResourceJob_from_vertex(
|
|
1815
1823
|
parent_object: Optional[dict[str, Any]] = None,
|
1816
1824
|
) -> dict[str, Any]:
|
1817
1825
|
to_object: dict[str, Any] = {}
|
1826
|
+
if getv(from_object, ['sdkHttpResponse']) is not None:
|
1827
|
+
setv(
|
1828
|
+
to_object, ['sdk_http_response'], getv(from_object, ['sdkHttpResponse'])
|
1829
|
+
)
|
1830
|
+
|
1818
1831
|
if getv(from_object, ['name']) is not None:
|
1819
1832
|
setv(to_object, ['name'], getv(from_object, ['name']))
|
1820
1833
|
|
@@ -2186,7 +2199,9 @@ class Batches(_api_module.BaseModule):
|
|
2186
2199
|
return_value = types.DeleteResourceJob._from_response(
|
2187
2200
|
response=response_dict, kwargs=parameter_model.model_dump()
|
2188
2201
|
)
|
2189
|
-
|
2202
|
+
return_value.sdk_http_response = types.HttpResponse(
|
2203
|
+
headers=response.headers
|
2204
|
+
)
|
2190
2205
|
self._api_client._verify_response(return_value)
|
2191
2206
|
return return_value
|
2192
2207
|
|
@@ -2619,7 +2634,9 @@ class AsyncBatches(_api_module.BaseModule):
|
|
2619
2634
|
return_value = types.DeleteResourceJob._from_response(
|
2620
2635
|
response=response_dict, kwargs=parameter_model.model_dump()
|
2621
2636
|
)
|
2622
|
-
|
2637
|
+
return_value.sdk_http_response = types.HttpResponse(
|
2638
|
+
headers=response.headers
|
2639
|
+
)
|
2623
2640
|
self._api_client._verify_response(return_value)
|
2624
2641
|
return return_value
|
2625
2642
|
|
@@ -172,18 +172,21 @@ class ServerError(APIError):
|
|
172
172
|
|
173
173
|
class UnknownFunctionCallArgumentError(ValueError):
|
174
174
|
"""Raised when the function call argument cannot be converted to the parameter annotation."""
|
175
|
-
|
176
175
|
pass
|
177
176
|
|
178
177
|
|
179
178
|
class UnsupportedFunctionError(ValueError):
|
180
179
|
"""Raised when the function is not supported."""
|
180
|
+
pass
|
181
181
|
|
182
182
|
|
183
183
|
class FunctionInvocationError(ValueError):
|
184
184
|
"""Raised when the function cannot be invoked with the given arguments."""
|
185
|
-
|
186
185
|
pass
|
187
186
|
|
188
187
|
|
188
|
+
class UnknownApiResponseError(ValueError):
|
189
|
+
"""Raised when the response from the API cannot be parsed as JSON."""
|
190
|
+
pass
|
191
|
+
|
189
192
|
ExperimentalWarning = _common.ExperimentalWarning
|