google-genai 0.7.0__py3-none-any.whl → 1.0.0rc0__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 +2 -4
- google/genai/_automatic_function_calling_util.py +13 -17
- google/genai/_common.py +11 -2
- google/genai/_operations.py +365 -0
- google/genai/_replay_api_client.py +5 -0
- google/genai/_transformers.py +32 -14
- google/genai/files.py +63 -61
- google/genai/models.py +46 -28
- google/genai/types.py +195 -3
- google/genai/version.py +1 -1
- {google_genai-0.7.0.dist-info → google_genai-1.0.0rc0.dist-info}/METADATA +12 -47
- google_genai-1.0.0rc0.dist-info/RECORD +27 -0
- google_genai-0.7.0.dist-info/RECORD +0 -26
- {google_genai-0.7.0.dist-info → google_genai-1.0.0rc0.dist-info}/LICENSE +0 -0
- {google_genai-0.7.0.dist-info → google_genai-1.0.0rc0.dist-info}/WHEEL +0 -0
- {google_genai-0.7.0.dist-info → google_genai-1.0.0rc0.dist-info}/top_level.txt +0 -0
google/genai/_api_client.py
CHANGED
@@ -255,7 +255,7 @@ class ApiClient:
|
|
255
255
|
'Project and location or API key must be set when using the Vertex '
|
256
256
|
'AI API.'
|
257
257
|
)
|
258
|
-
if self.api_key:
|
258
|
+
if self.api_key or self.location == 'global':
|
259
259
|
self._http_options['base_url'] = (
|
260
260
|
f'https://aiplatform.googleapis.com/'
|
261
261
|
)
|
@@ -273,7 +273,7 @@ class ApiClient:
|
|
273
273
|
self._http_options['api_version'] = 'v1beta'
|
274
274
|
# Default options for both clients.
|
275
275
|
self._http_options['headers'] = {'Content-Type': 'application/json'}
|
276
|
-
if self.api_key
|
276
|
+
if self.api_key:
|
277
277
|
self._http_options['headers']['x-goog-api-key'] = self.api_key
|
278
278
|
# Update the http options with the user provided http options.
|
279
279
|
if http_options:
|
@@ -323,8 +323,6 @@ class ApiClient:
|
|
323
323
|
and not self.api_key
|
324
324
|
):
|
325
325
|
path = f'projects/{self.project}/locations/{self.location}/' + path
|
326
|
-
elif self.vertexai and self.api_key:
|
327
|
-
path = f'{path}?key={self.api_key}'
|
328
326
|
url = _join_url_path(
|
329
327
|
patched_http_options['base_url'],
|
330
328
|
patched_http_options['api_version'] + '/' + path,
|
@@ -22,9 +22,9 @@ import pydantic
|
|
22
22
|
from . import types
|
23
23
|
|
24
24
|
if sys.version_info >= (3, 10):
|
25
|
-
|
25
|
+
VersionedUnionType = builtin_types.UnionType
|
26
26
|
else:
|
27
|
-
|
27
|
+
VersionedUnionType = typing._UnionGenericAlias
|
28
28
|
|
29
29
|
_py_builtin_type_to_schema_type = {
|
30
30
|
str: 'STRING',
|
@@ -45,7 +45,8 @@ def _is_builtin_primitive_or_compound(
|
|
45
45
|
def _raise_for_any_of_if_mldev(schema: types.Schema):
|
46
46
|
if schema.any_of:
|
47
47
|
raise ValueError(
|
48
|
-
'AnyOf is not supported in function declaration schema for
|
48
|
+
'AnyOf is not supported in function declaration schema for'
|
49
|
+
' the Gemini API.'
|
49
50
|
)
|
50
51
|
|
51
52
|
|
@@ -53,15 +54,7 @@ def _raise_for_default_if_mldev(schema: types.Schema):
|
|
53
54
|
if schema.default is not None:
|
54
55
|
raise ValueError(
|
55
56
|
'Default value is not supported in function declaration schema for'
|
56
|
-
'
|
57
|
-
)
|
58
|
-
|
59
|
-
|
60
|
-
def _raise_for_nullable_if_mldev(schema: types.Schema):
|
61
|
-
if schema.nullable:
|
62
|
-
raise ValueError(
|
63
|
-
'Nullable is not supported in function declaration schema for'
|
64
|
-
' Google AI.'
|
57
|
+
' the Gemini API.'
|
65
58
|
)
|
66
59
|
|
67
60
|
|
@@ -69,7 +62,6 @@ def _raise_if_schema_unsupported(client, schema: types.Schema):
|
|
69
62
|
if not client.vertexai:
|
70
63
|
_raise_for_any_of_if_mldev(schema)
|
71
64
|
_raise_for_default_if_mldev(schema)
|
72
|
-
_raise_for_nullable_if_mldev(schema)
|
73
65
|
|
74
66
|
|
75
67
|
def _is_default_value_compatible(
|
@@ -82,10 +74,10 @@ def _is_default_value_compatible(
|
|
82
74
|
if (
|
83
75
|
isinstance(annotation, _GenericAlias)
|
84
76
|
or isinstance(annotation, builtin_types.GenericAlias)
|
85
|
-
or isinstance(annotation,
|
77
|
+
or isinstance(annotation, VersionedUnionType)
|
86
78
|
):
|
87
79
|
origin = get_origin(annotation)
|
88
|
-
if origin in (Union,
|
80
|
+
if origin in (Union, VersionedUnionType):
|
89
81
|
return any(
|
90
82
|
_is_default_value_compatible(default_value, arg)
|
91
83
|
for arg in get_args(annotation)
|
@@ -141,7 +133,7 @@ def _parse_schema_from_parameter(
|
|
141
133
|
_raise_if_schema_unsupported(client, schema)
|
142
134
|
return schema
|
143
135
|
if (
|
144
|
-
isinstance(param.annotation,
|
136
|
+
isinstance(param.annotation, VersionedUnionType)
|
145
137
|
# only parse simple UnionType, example int | str | float | bool
|
146
138
|
# complex UnionType will be invoked in raise branch
|
147
139
|
and all(
|
@@ -229,7 +221,11 @@ def _parse_schema_from_parameter(
|
|
229
221
|
schema.type = 'OBJECT'
|
230
222
|
unique_types = set()
|
231
223
|
for arg in args:
|
232
|
-
|
224
|
+
# The first check is for NoneType in Python 3.9, since the __name__
|
225
|
+
# attribute is not available in Python 3.9
|
226
|
+
if type(arg) is type(None) or (
|
227
|
+
hasattr(arg, '__name__') and arg.__name__ == 'NoneType'
|
228
|
+
): # Optional type
|
233
229
|
schema.nullable = True
|
234
230
|
continue
|
235
231
|
schema_in_any_of = _parse_schema_from_parameter(
|
google/genai/_common.py
CHANGED
@@ -21,6 +21,7 @@ import enum
|
|
21
21
|
import typing
|
22
22
|
from typing import Union
|
23
23
|
import uuid
|
24
|
+
import warnings
|
24
25
|
|
25
26
|
import pydantic
|
26
27
|
from pydantic import alias_generators
|
@@ -213,8 +214,16 @@ class CaseInSensitiveEnum(str, enum.Enum):
|
|
213
214
|
except KeyError:
|
214
215
|
try:
|
215
216
|
return cls[value.lower()] # Try to access directly with lowercase
|
216
|
-
except KeyError
|
217
|
-
|
217
|
+
except KeyError:
|
218
|
+
warnings.warn(f"{value} is not a valid {cls.__name__}")
|
219
|
+
try:
|
220
|
+
# Creating a enum instance based on the value
|
221
|
+
unknown_enum_val = cls._new_member_(cls) # pylint: disable=protected-access,attribute-error
|
222
|
+
unknown_enum_val._name_ = str(value) # pylint: disable=protected-access
|
223
|
+
unknown_enum_val._value_ = value # pylint: disable=protected-access
|
224
|
+
return unknown_enum_val
|
225
|
+
except:
|
226
|
+
return None
|
218
227
|
|
219
228
|
|
220
229
|
def timestamped_unique_name() -> str:
|
@@ -0,0 +1,365 @@
|
|
1
|
+
# Copyright 2024 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
|
+
|
16
|
+
# Code generated by the Google Gen AI SDK generator DO NOT EDIT.
|
17
|
+
|
18
|
+
from typing import Optional, Union
|
19
|
+
from urllib.parse import urlencode
|
20
|
+
from . import _api_module
|
21
|
+
from . import _common
|
22
|
+
from . import types
|
23
|
+
from ._api_client import ApiClient
|
24
|
+
from ._common import get_value_by_path as getv
|
25
|
+
from ._common import set_value_by_path as setv
|
26
|
+
|
27
|
+
|
28
|
+
def _GetOperationParameters_to_mldev(
|
29
|
+
api_client: ApiClient,
|
30
|
+
from_object: Union[dict, object],
|
31
|
+
parent_object: dict = None,
|
32
|
+
) -> dict:
|
33
|
+
to_object = {}
|
34
|
+
if getv(from_object, ['operation_name']) is not None:
|
35
|
+
setv(
|
36
|
+
to_object,
|
37
|
+
['_url', 'operationName'],
|
38
|
+
getv(from_object, ['operation_name']),
|
39
|
+
)
|
40
|
+
|
41
|
+
if getv(from_object, ['config']) is not None:
|
42
|
+
setv(to_object, ['config'], getv(from_object, ['config']))
|
43
|
+
|
44
|
+
return to_object
|
45
|
+
|
46
|
+
|
47
|
+
def _GetOperationParameters_to_vertex(
|
48
|
+
api_client: ApiClient,
|
49
|
+
from_object: Union[dict, object],
|
50
|
+
parent_object: dict = None,
|
51
|
+
) -> dict:
|
52
|
+
to_object = {}
|
53
|
+
if getv(from_object, ['operation_name']) is not None:
|
54
|
+
setv(
|
55
|
+
to_object,
|
56
|
+
['_url', 'operationName'],
|
57
|
+
getv(from_object, ['operation_name']),
|
58
|
+
)
|
59
|
+
|
60
|
+
if getv(from_object, ['config']) is not None:
|
61
|
+
setv(to_object, ['config'], getv(from_object, ['config']))
|
62
|
+
|
63
|
+
return to_object
|
64
|
+
|
65
|
+
|
66
|
+
def _FetchPredictOperationParameters_to_mldev(
|
67
|
+
api_client: ApiClient,
|
68
|
+
from_object: Union[dict, object],
|
69
|
+
parent_object: dict = None,
|
70
|
+
) -> dict:
|
71
|
+
to_object = {}
|
72
|
+
if getv(from_object, ['operation_name']) is not None:
|
73
|
+
raise ValueError('operation_name parameter is not supported in Gemini API.')
|
74
|
+
|
75
|
+
if getv(from_object, ['resource_name']) is not None:
|
76
|
+
raise ValueError('resource_name parameter is not supported in Gemini API.')
|
77
|
+
|
78
|
+
if getv(from_object, ['config']) is not None:
|
79
|
+
raise ValueError('config parameter is not supported in Gemini API.')
|
80
|
+
|
81
|
+
return to_object
|
82
|
+
|
83
|
+
|
84
|
+
def _FetchPredictOperationParameters_to_vertex(
|
85
|
+
api_client: ApiClient,
|
86
|
+
from_object: Union[dict, object],
|
87
|
+
parent_object: dict = None,
|
88
|
+
) -> dict:
|
89
|
+
to_object = {}
|
90
|
+
if getv(from_object, ['operation_name']) is not None:
|
91
|
+
setv(to_object, ['operationName'], getv(from_object, ['operation_name']))
|
92
|
+
|
93
|
+
if getv(from_object, ['resource_name']) is not None:
|
94
|
+
setv(
|
95
|
+
to_object,
|
96
|
+
['_url', 'resourceName'],
|
97
|
+
getv(from_object, ['resource_name']),
|
98
|
+
)
|
99
|
+
|
100
|
+
if getv(from_object, ['config']) is not None:
|
101
|
+
setv(to_object, ['config'], getv(from_object, ['config']))
|
102
|
+
|
103
|
+
return to_object
|
104
|
+
|
105
|
+
|
106
|
+
def _Operation_from_mldev(
|
107
|
+
api_client: ApiClient,
|
108
|
+
from_object: Union[dict, object],
|
109
|
+
parent_object: dict = None,
|
110
|
+
) -> dict:
|
111
|
+
to_object = {}
|
112
|
+
if getv(from_object, ['name']) is not None:
|
113
|
+
setv(to_object, ['name'], getv(from_object, ['name']))
|
114
|
+
|
115
|
+
if getv(from_object, ['metadata']) is not None:
|
116
|
+
setv(to_object, ['metadata'], getv(from_object, ['metadata']))
|
117
|
+
|
118
|
+
if getv(from_object, ['done']) is not None:
|
119
|
+
setv(to_object, ['done'], getv(from_object, ['done']))
|
120
|
+
|
121
|
+
if getv(from_object, ['error']) is not None:
|
122
|
+
setv(to_object, ['error'], getv(from_object, ['error']))
|
123
|
+
|
124
|
+
if getv(from_object, ['response']) is not None:
|
125
|
+
setv(to_object, ['response'], getv(from_object, ['response']))
|
126
|
+
|
127
|
+
return to_object
|
128
|
+
|
129
|
+
|
130
|
+
def _Operation_from_vertex(
|
131
|
+
api_client: ApiClient,
|
132
|
+
from_object: Union[dict, object],
|
133
|
+
parent_object: dict = None,
|
134
|
+
) -> dict:
|
135
|
+
to_object = {}
|
136
|
+
if getv(from_object, ['name']) is not None:
|
137
|
+
setv(to_object, ['name'], getv(from_object, ['name']))
|
138
|
+
|
139
|
+
if getv(from_object, ['metadata']) is not None:
|
140
|
+
setv(to_object, ['metadata'], getv(from_object, ['metadata']))
|
141
|
+
|
142
|
+
if getv(from_object, ['done']) is not None:
|
143
|
+
setv(to_object, ['done'], getv(from_object, ['done']))
|
144
|
+
|
145
|
+
if getv(from_object, ['error']) is not None:
|
146
|
+
setv(to_object, ['error'], getv(from_object, ['error']))
|
147
|
+
|
148
|
+
if getv(from_object, ['response']) is not None:
|
149
|
+
setv(to_object, ['response'], getv(from_object, ['response']))
|
150
|
+
|
151
|
+
return to_object
|
152
|
+
|
153
|
+
|
154
|
+
class _operations(_api_module.BaseModule):
|
155
|
+
|
156
|
+
def _get_operation(
|
157
|
+
self,
|
158
|
+
*,
|
159
|
+
operation_name: str,
|
160
|
+
config: Optional[types.GetOperationConfigOrDict] = None,
|
161
|
+
) -> types.Operation:
|
162
|
+
parameter_model = types._GetOperationParameters(
|
163
|
+
operation_name=operation_name,
|
164
|
+
config=config,
|
165
|
+
)
|
166
|
+
|
167
|
+
if self._api_client.vertexai:
|
168
|
+
request_dict = _GetOperationParameters_to_vertex(
|
169
|
+
self._api_client, parameter_model
|
170
|
+
)
|
171
|
+
path = '{operationName}'.format_map(request_dict.get('_url'))
|
172
|
+
else:
|
173
|
+
request_dict = _GetOperationParameters_to_mldev(
|
174
|
+
self._api_client, parameter_model
|
175
|
+
)
|
176
|
+
path = '{operationName}'.format_map(request_dict.get('_url'))
|
177
|
+
query_params = request_dict.get('_query')
|
178
|
+
if query_params:
|
179
|
+
path = f'{path}?{urlencode(query_params)}'
|
180
|
+
# TODO: remove the hack that pops config.
|
181
|
+
request_dict.pop('config', None)
|
182
|
+
|
183
|
+
http_options = None
|
184
|
+
if isinstance(config, dict):
|
185
|
+
http_options = config.get('http_options', None)
|
186
|
+
elif hasattr(config, 'http_options'):
|
187
|
+
http_options = config.http_options
|
188
|
+
|
189
|
+
request_dict = _common.convert_to_dict(request_dict)
|
190
|
+
request_dict = _common.encode_unserializable_types(request_dict)
|
191
|
+
|
192
|
+
response_dict = self._api_client.request(
|
193
|
+
'get', path, request_dict, http_options
|
194
|
+
)
|
195
|
+
|
196
|
+
if self._api_client.vertexai:
|
197
|
+
response_dict = _Operation_from_vertex(self._api_client, response_dict)
|
198
|
+
else:
|
199
|
+
response_dict = _Operation_from_mldev(self._api_client, response_dict)
|
200
|
+
|
201
|
+
return_value = types.Operation._from_response(
|
202
|
+
response=response_dict, kwargs=parameter_model
|
203
|
+
)
|
204
|
+
self._api_client._verify_response(return_value)
|
205
|
+
return return_value
|
206
|
+
|
207
|
+
def _fetch_predict_operation(
|
208
|
+
self,
|
209
|
+
*,
|
210
|
+
operation_name: str,
|
211
|
+
resource_name: str,
|
212
|
+
config: Optional[types.FetchPredictOperationConfigOrDict] = None,
|
213
|
+
) -> types.Operation:
|
214
|
+
parameter_model = types._FetchPredictOperationParameters(
|
215
|
+
operation_name=operation_name,
|
216
|
+
resource_name=resource_name,
|
217
|
+
config=config,
|
218
|
+
)
|
219
|
+
|
220
|
+
if not self._api_client.vertexai:
|
221
|
+
raise ValueError('This method is only supported in the Vertex AI client.')
|
222
|
+
else:
|
223
|
+
request_dict = _FetchPredictOperationParameters_to_vertex(
|
224
|
+
self._api_client, parameter_model
|
225
|
+
)
|
226
|
+
path = '{resourceName}:fetchPredictOperation'.format_map(
|
227
|
+
request_dict.get('_url')
|
228
|
+
)
|
229
|
+
|
230
|
+
query_params = request_dict.get('_query')
|
231
|
+
if query_params:
|
232
|
+
path = f'{path}?{urlencode(query_params)}'
|
233
|
+
# TODO: remove the hack that pops config.
|
234
|
+
request_dict.pop('config', None)
|
235
|
+
|
236
|
+
http_options = None
|
237
|
+
if isinstance(config, dict):
|
238
|
+
http_options = config.get('http_options', None)
|
239
|
+
elif hasattr(config, 'http_options'):
|
240
|
+
http_options = config.http_options
|
241
|
+
|
242
|
+
request_dict = _common.convert_to_dict(request_dict)
|
243
|
+
request_dict = _common.encode_unserializable_types(request_dict)
|
244
|
+
|
245
|
+
response_dict = self._api_client.request(
|
246
|
+
'post', path, request_dict, http_options
|
247
|
+
)
|
248
|
+
|
249
|
+
if self._api_client.vertexai:
|
250
|
+
response_dict = _Operation_from_vertex(self._api_client, response_dict)
|
251
|
+
else:
|
252
|
+
response_dict = _Operation_from_mldev(self._api_client, response_dict)
|
253
|
+
|
254
|
+
return_value = types.Operation._from_response(
|
255
|
+
response=response_dict, kwargs=parameter_model
|
256
|
+
)
|
257
|
+
self._api_client._verify_response(return_value)
|
258
|
+
return return_value
|
259
|
+
|
260
|
+
|
261
|
+
class Async_operations(_api_module.BaseModule):
|
262
|
+
|
263
|
+
async def _get_operation(
|
264
|
+
self,
|
265
|
+
*,
|
266
|
+
operation_name: str,
|
267
|
+
config: Optional[types.GetOperationConfigOrDict] = None,
|
268
|
+
) -> types.Operation:
|
269
|
+
parameter_model = types._GetOperationParameters(
|
270
|
+
operation_name=operation_name,
|
271
|
+
config=config,
|
272
|
+
)
|
273
|
+
|
274
|
+
if self._api_client.vertexai:
|
275
|
+
request_dict = _GetOperationParameters_to_vertex(
|
276
|
+
self._api_client, parameter_model
|
277
|
+
)
|
278
|
+
path = '{operationName}'.format_map(request_dict.get('_url'))
|
279
|
+
else:
|
280
|
+
request_dict = _GetOperationParameters_to_mldev(
|
281
|
+
self._api_client, parameter_model
|
282
|
+
)
|
283
|
+
path = '{operationName}'.format_map(request_dict.get('_url'))
|
284
|
+
query_params = request_dict.get('_query')
|
285
|
+
if query_params:
|
286
|
+
path = f'{path}?{urlencode(query_params)}'
|
287
|
+
# TODO: remove the hack that pops config.
|
288
|
+
request_dict.pop('config', None)
|
289
|
+
|
290
|
+
http_options = None
|
291
|
+
if isinstance(config, dict):
|
292
|
+
http_options = config.get('http_options', None)
|
293
|
+
elif hasattr(config, 'http_options'):
|
294
|
+
http_options = config.http_options
|
295
|
+
|
296
|
+
request_dict = _common.convert_to_dict(request_dict)
|
297
|
+
request_dict = _common.encode_unserializable_types(request_dict)
|
298
|
+
|
299
|
+
response_dict = await self._api_client.async_request(
|
300
|
+
'get', path, request_dict, http_options
|
301
|
+
)
|
302
|
+
|
303
|
+
if self._api_client.vertexai:
|
304
|
+
response_dict = _Operation_from_vertex(self._api_client, response_dict)
|
305
|
+
else:
|
306
|
+
response_dict = _Operation_from_mldev(self._api_client, response_dict)
|
307
|
+
|
308
|
+
return_value = types.Operation._from_response(
|
309
|
+
response=response_dict, kwargs=parameter_model
|
310
|
+
)
|
311
|
+
self._api_client._verify_response(return_value)
|
312
|
+
return return_value
|
313
|
+
|
314
|
+
async def _fetch_predict_operation(
|
315
|
+
self,
|
316
|
+
*,
|
317
|
+
operation_name: str,
|
318
|
+
resource_name: str,
|
319
|
+
config: Optional[types.FetchPredictOperationConfigOrDict] = None,
|
320
|
+
) -> types.Operation:
|
321
|
+
parameter_model = types._FetchPredictOperationParameters(
|
322
|
+
operation_name=operation_name,
|
323
|
+
resource_name=resource_name,
|
324
|
+
config=config,
|
325
|
+
)
|
326
|
+
|
327
|
+
if not self._api_client.vertexai:
|
328
|
+
raise ValueError('This method is only supported in the Vertex AI client.')
|
329
|
+
else:
|
330
|
+
request_dict = _FetchPredictOperationParameters_to_vertex(
|
331
|
+
self._api_client, parameter_model
|
332
|
+
)
|
333
|
+
path = '{resourceName}:fetchPredictOperation'.format_map(
|
334
|
+
request_dict.get('_url')
|
335
|
+
)
|
336
|
+
|
337
|
+
query_params = request_dict.get('_query')
|
338
|
+
if query_params:
|
339
|
+
path = f'{path}?{urlencode(query_params)}'
|
340
|
+
# TODO: remove the hack that pops config.
|
341
|
+
request_dict.pop('config', None)
|
342
|
+
|
343
|
+
http_options = None
|
344
|
+
if isinstance(config, dict):
|
345
|
+
http_options = config.get('http_options', None)
|
346
|
+
elif hasattr(config, 'http_options'):
|
347
|
+
http_options = config.http_options
|
348
|
+
|
349
|
+
request_dict = _common.convert_to_dict(request_dict)
|
350
|
+
request_dict = _common.encode_unserializable_types(request_dict)
|
351
|
+
|
352
|
+
response_dict = await self._api_client.async_request(
|
353
|
+
'post', path, request_dict, http_options
|
354
|
+
)
|
355
|
+
|
356
|
+
if self._api_client.vertexai:
|
357
|
+
response_dict = _Operation_from_vertex(self._api_client, response_dict)
|
358
|
+
else:
|
359
|
+
response_dict = _Operation_from_mldev(self._api_client, response_dict)
|
360
|
+
|
361
|
+
return_value = types.Operation._from_response(
|
362
|
+
response=response_dict, kwargs=parameter_model
|
363
|
+
)
|
364
|
+
self._api_client._verify_response(return_value)
|
365
|
+
return return_value
|
@@ -78,6 +78,11 @@ def _redact_request_url(url: str) -> str:
|
|
78
78
|
'{VERTEX_URL_PREFIX}/',
|
79
79
|
result,
|
80
80
|
)
|
81
|
+
result = re.sub(
|
82
|
+
r'.*aiplatform.googleapis.com/[^/]+/',
|
83
|
+
'{VERTEX_URL_PREFIX}/',
|
84
|
+
result,
|
85
|
+
)
|
81
86
|
result = re.sub(
|
82
87
|
r'https://generativelanguage.googleapis.com/[^/]+',
|
83
88
|
'{MLDEV_URL_PREFIX}',
|
google/genai/_transformers.py
CHANGED
@@ -34,10 +34,12 @@ import pydantic
|
|
34
34
|
from . import _api_client
|
35
35
|
from . import types
|
36
36
|
|
37
|
-
if sys.version_info >= (3,
|
38
|
-
|
37
|
+
if sys.version_info >= (3, 10):
|
38
|
+
VersionedUnionType = typing.types.UnionType
|
39
|
+
_UNION_TYPES = (typing.Union, typing.types.UnionType)
|
39
40
|
else:
|
40
|
-
|
41
|
+
VersionedUnionType = typing._UnionGenericAlias
|
42
|
+
_UNION_TYPES = (typing.Union,)
|
41
43
|
|
42
44
|
|
43
45
|
def _resource_name(
|
@@ -225,6 +227,7 @@ PartType = Union[types.Part, types.PartDict, str, 'PIL.Image.Image']
|
|
225
227
|
def t_part(client: _api_client.ApiClient, part: PartType) -> types.Part:
|
226
228
|
try:
|
227
229
|
import PIL.Image
|
230
|
+
|
228
231
|
PIL_Image = PIL.Image.Image
|
229
232
|
except ImportError:
|
230
233
|
PIL_Image = None
|
@@ -342,7 +345,7 @@ def handle_null_fields(schema: dict[str, Any]):
|
|
342
345
|
"type": "null"
|
343
346
|
}
|
344
347
|
],
|
345
|
-
"default":
|
348
|
+
"default": None,
|
346
349
|
"title": "Total Area Sq Mi"
|
347
350
|
}
|
348
351
|
}
|
@@ -356,16 +359,12 @@ def handle_null_fields(schema: dict[str, Any]):
|
|
356
359
|
"total_area_sq_mi": {
|
357
360
|
"type": "integer",
|
358
361
|
"nullable": true,
|
359
|
-
"default":
|
362
|
+
"default": None,
|
360
363
|
"title": "Total Area Sq Mi"
|
361
364
|
}
|
362
365
|
}
|
363
366
|
"""
|
364
|
-
if (
|
365
|
-
isinstance(schema, dict)
|
366
|
-
and 'type' in schema
|
367
|
-
and schema['type'] == 'null'
|
368
|
-
):
|
367
|
+
if schema.get('type', None) == 'null':
|
369
368
|
schema['nullable'] = True
|
370
369
|
del schema['type']
|
371
370
|
elif 'anyOf' in schema:
|
@@ -445,6 +444,11 @@ def process_schema(
|
|
445
444
|
if client and not client.vertexai:
|
446
445
|
schema.pop('title', None)
|
447
446
|
|
447
|
+
if schema.get('default') is not None:
|
448
|
+
raise ValueError(
|
449
|
+
'Default value is not supported in the response schema for the Gemmini API.'
|
450
|
+
)
|
451
|
+
|
448
452
|
if defs is None:
|
449
453
|
defs = schema.pop('$defs', {})
|
450
454
|
for _, sub_schema in defs.items():
|
@@ -454,8 +458,19 @@ def process_schema(
|
|
454
458
|
|
455
459
|
any_of = schema.get('anyOf', None)
|
456
460
|
if any_of is not None:
|
461
|
+
if not client.vertexai:
|
462
|
+
raise ValueError(
|
463
|
+
'AnyOf is not supported in the response schema for the Gemini API.'
|
464
|
+
)
|
457
465
|
for sub_schema in any_of:
|
458
|
-
|
466
|
+
# $ref is present in any_of if the schema is a union of Pydantic classes
|
467
|
+
ref_key = sub_schema.get('$ref', None)
|
468
|
+
if ref_key is None:
|
469
|
+
process_schema(sub_schema, client, defs)
|
470
|
+
else:
|
471
|
+
ref = defs[ref_key.split('defs/')[-1]]
|
472
|
+
any_of.append(ref)
|
473
|
+
schema['anyOf'] = [item for item in any_of if '$ref' not in item]
|
459
474
|
return
|
460
475
|
|
461
476
|
schema_type = schema.get('type', None)
|
@@ -526,15 +541,18 @@ def t_schema(
|
|
526
541
|
if (
|
527
542
|
# in Python 3.9 Generic alias list[int] counts as a type,
|
528
543
|
# and breaks issubclass because it's not a class.
|
529
|
-
not isinstance(origin, GenericAlias) and
|
530
|
-
isinstance(origin, type) and
|
544
|
+
not isinstance(origin, GenericAlias) and
|
545
|
+
isinstance(origin, type) and
|
531
546
|
issubclass(origin, pydantic.BaseModel)
|
532
547
|
):
|
533
548
|
schema = origin.model_json_schema()
|
534
549
|
process_schema(schema, client)
|
535
550
|
return types.Schema.model_validate(schema)
|
536
551
|
elif (
|
537
|
-
|
552
|
+
isinstance(origin, GenericAlias)
|
553
|
+
or isinstance(origin, type)
|
554
|
+
or isinstance(origin, VersionedUnionType)
|
555
|
+
or typing.get_origin(origin) in _UNION_TYPES
|
538
556
|
):
|
539
557
|
class Placeholder(pydantic.BaseModel):
|
540
558
|
placeholder: origin
|