google-genai 1.45.0__py3-none-any.whl → 1.47.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.
@@ -599,7 +599,7 @@ class BaseApiClient:
599
599
  # Handle when to use Vertex AI in express mode (api key).
600
600
  # Explicit initializer arguments are already validated above.
601
601
  if self.vertexai:
602
- if credentials:
602
+ if credentials and env_api_key:
603
603
  # Explicit credentials take precedence over implicit api_key.
604
604
  logger.info(
605
605
  'The user provided Google Cloud credentials will take precedence'
@@ -629,6 +629,9 @@ class BaseApiClient:
629
629
  )
630
630
  self.api_key = None
631
631
 
632
+ if not self.location and not self.api_key:
633
+ self.location = 'global'
634
+
632
635
  self.custom_base_url = (
633
636
  validated_http_options.base_url
634
637
  if validated_http_options.base_url
@@ -650,16 +653,19 @@ class BaseApiClient:
650
653
  if not has_sufficient_auth and not self.custom_base_url:
651
654
  # Skip sufficient auth check if base url is provided in http options.
652
655
  raise ValueError(
653
- 'Project and location or API key must be set when using the Vertex '
656
+ 'Project or API key must be set when using the Vertex '
654
657
  'AI API.'
655
658
  )
656
659
  if self.api_key or self.location == 'global':
657
660
  self._http_options.base_url = f'https://aiplatform.googleapis.com/'
658
- elif self.custom_base_url and not has_sufficient_auth:
661
+ elif self.custom_base_url and not ((project and location) or api_key):
659
662
  # Avoid setting default base url and api version if base_url provided.
660
663
  # API gateway proxy can use the auth in custom headers, not url.
661
664
  # Enable custom url if auth is not sufficient.
662
665
  self._http_options.base_url = self.custom_base_url
666
+ # Clear project and location if base_url is provided.
667
+ self.project = None
668
+ self.location = None
663
669
  else:
664
670
  self._http_options.base_url = (
665
671
  f'https://{self.location}-aiplatform.googleapis.com/'
@@ -693,13 +699,25 @@ class BaseApiClient:
693
699
  self._http_options
694
700
  )
695
701
  self._async_httpx_client_args = async_client_args
696
- self._httpx_client = SyncHttpxClient(**client_args)
697
- self._async_httpx_client = AsyncHttpxClient(**async_client_args)
702
+
703
+ if self._http_options.httpx_client:
704
+ self._httpx_client = self._http_options.httpx_client
705
+ else:
706
+ self._httpx_client = SyncHttpxClient(**client_args)
707
+ if self._http_options.httpx_async_client:
708
+ self._async_httpx_client = self._http_options.httpx_async_client
709
+ else:
710
+ self._async_httpx_client = AsyncHttpxClient(**async_client_args)
698
711
  if self._use_aiohttp():
699
- # Do it once at the genai.Client level. Share among all requests.
700
- self._async_client_session_request_args = self._ensure_aiohttp_ssl_ctx(
701
- self._http_options
702
- )
712
+ try:
713
+ import aiohttp # pylint: disable=g-import-not-at-top
714
+ # Do it once at the genai.Client level. Share among all requests.
715
+ self._async_client_session_request_args = self._ensure_aiohttp_ssl_ctx(
716
+ self._http_options
717
+ )
718
+ except ImportError:
719
+ pass
720
+
703
721
  # Initialize the aiohttp client session.
704
722
  self._aiohttp_session: Optional[aiohttp.ClientSession] = None
705
723
 
@@ -904,6 +922,7 @@ class BaseApiClient:
904
922
  has_aiohttp
905
923
  and (self._http_options.async_client_args or {}).get('transport')
906
924
  is None
925
+ and (self._http_options.httpx_async_client is None)
907
926
  )
908
927
 
909
928
  def _websocket_base_url(self) -> str:
@@ -1049,11 +1068,16 @@ class BaseApiClient:
1049
1068
  _common.recursive_dict_update(
1050
1069
  request_dict, patched_http_options.extra_body
1051
1070
  )
1052
-
1053
- url = join_url_path(
1054
- base_url,
1055
- versioned_path,
1056
- )
1071
+ url = base_url
1072
+ if (
1073
+ not self.custom_base_url
1074
+ or (self.project and self.location)
1075
+ or self.api_key
1076
+ ):
1077
+ url = join_url_path(
1078
+ base_url,
1079
+ versioned_path,
1080
+ )
1057
1081
 
1058
1082
  if self.api_key and self.api_key.startswith('auth_tokens/'):
1059
1083
  raise EphemeralTokenAPIKeyError(
@@ -1800,11 +1824,17 @@ class BaseApiClient:
1800
1824
  """
1801
1825
 
1802
1826
  try:
1803
- self.close()
1827
+ # Let users close the custom client explicitly by themselves. Otherwise,
1828
+ # close the client when the object is garbage collected.
1829
+ if not self._http_options.httpx_client:
1830
+ self.close()
1804
1831
  except Exception: # pylint: disable=broad-except
1805
1832
  pass
1806
1833
 
1807
1834
  try:
1808
- asyncio.get_running_loop().create_task(self.aclose())
1835
+ # Let users close the custom client explicitly by themselves. Otherwise,
1836
+ # close the client when the object is garbage collected.
1837
+ if not self._http_options.httpx_async_client:
1838
+ asyncio.get_running_loop().create_task(self.aclose())
1809
1839
  except Exception: # pylint: disable=broad-except
1810
- pass
1840
+ pass
@@ -611,4 +611,8 @@ def prepare_resumable_upload(
611
611
  'X-Goog-Upload-Header-Content-Type': f'{mime_type}',
612
612
  },
613
613
  )
614
+ if isinstance(file, (str, os.PathLike)):
615
+ if http_options.headers is None:
616
+ http_options.headers = {}
617
+ http_options.headers['X-Goog-Upload-File-Name'] = os.path.basename(file)
614
618
  return http_options, size_bytes, mime_type
@@ -28,12 +28,12 @@ def _Blob_to_mldev(
28
28
  parent_object: Optional[dict[str, Any]] = None,
29
29
  ) -> dict[str, Any]:
30
30
  to_object: dict[str, Any] = {}
31
- if getv(from_object, ['display_name']) is not None:
32
- raise ValueError('display_name parameter is not supported in Gemini API.')
33
-
34
31
  if getv(from_object, ['data']) is not None:
35
32
  setv(to_object, ['data'], getv(from_object, ['data']))
36
33
 
34
+ if getv(from_object, ['display_name']) is not None:
35
+ raise ValueError('display_name parameter is not supported in Gemini API.')
36
+
37
37
  if getv(from_object, ['mime_type']) is not None:
38
38
  setv(to_object, ['mimeType'], getv(from_object, ['mime_type']))
39
39
 
@@ -226,6 +226,11 @@ def _GenerationConfig_to_vertex(
226
226
  if getv(from_object, ['top_p']) is not None:
227
227
  setv(to_object, ['topP'], getv(from_object, ['top_p']))
228
228
 
229
+ if getv(from_object, ['enable_enhanced_civic_answers']) is not None:
230
+ raise ValueError(
231
+ 'enable_enhanced_civic_answers parameter is not supported in Vertex AI.'
232
+ )
233
+
229
234
  return to_object
230
235
 
231
236
 
@@ -248,16 +253,16 @@ def _GoogleSearch_to_mldev(
248
253
  parent_object: Optional[dict[str, Any]] = None,
249
254
  ) -> dict[str, Any]:
250
255
  to_object: dict[str, Any] = {}
251
- if getv(from_object, ['time_range_filter']) is not None:
252
- setv(
253
- to_object, ['timeRangeFilter'], getv(from_object, ['time_range_filter'])
254
- )
255
-
256
256
  if getv(from_object, ['exclude_domains']) is not None:
257
257
  raise ValueError(
258
258
  'exclude_domains parameter is not supported in Gemini API.'
259
259
  )
260
260
 
261
+ if getv(from_object, ['time_range_filter']) is not None:
262
+ setv(
263
+ to_object, ['timeRangeFilter'], getv(from_object, ['time_range_filter'])
264
+ )
265
+
261
266
  return to_object
262
267
 
263
268
 
@@ -1151,19 +1156,19 @@ def _Part_to_mldev(
1151
1156
  parent_object: Optional[dict[str, Any]] = None,
1152
1157
  ) -> dict[str, Any]:
1153
1158
  to_object: dict[str, Any] = {}
1154
- if getv(from_object, ['video_metadata']) is not None:
1155
- setv(to_object, ['videoMetadata'], getv(from_object, ['video_metadata']))
1156
-
1157
- if getv(from_object, ['thought']) is not None:
1158
- setv(to_object, ['thought'], getv(from_object, ['thought']))
1159
+ if getv(from_object, ['function_call']) is not None:
1160
+ setv(to_object, ['functionCall'], getv(from_object, ['function_call']))
1159
1161
 
1160
- if getv(from_object, ['inline_data']) is not None:
1162
+ if getv(from_object, ['code_execution_result']) is not None:
1161
1163
  setv(
1162
1164
  to_object,
1163
- ['inlineData'],
1164
- _Blob_to_mldev(getv(from_object, ['inline_data']), to_object),
1165
+ ['codeExecutionResult'],
1166
+ getv(from_object, ['code_execution_result']),
1165
1167
  )
1166
1168
 
1169
+ if getv(from_object, ['executable_code']) is not None:
1170
+ setv(to_object, ['executableCode'], getv(from_object, ['executable_code']))
1171
+
1167
1172
  if getv(from_object, ['file_data']) is not None:
1168
1173
  setv(
1169
1174
  to_object,
@@ -1171,35 +1176,35 @@ def _Part_to_mldev(
1171
1176
  _FileData_to_mldev(getv(from_object, ['file_data']), to_object),
1172
1177
  )
1173
1178
 
1174
- if getv(from_object, ['thought_signature']) is not None:
1179
+ if getv(from_object, ['function_response']) is not None:
1175
1180
  setv(
1176
1181
  to_object,
1177
- ['thoughtSignature'],
1178
- getv(from_object, ['thought_signature']),
1182
+ ['functionResponse'],
1183
+ getv(from_object, ['function_response']),
1179
1184
  )
1180
1185
 
1181
- if getv(from_object, ['function_call']) is not None:
1182
- setv(to_object, ['functionCall'], getv(from_object, ['function_call']))
1183
-
1184
- if getv(from_object, ['code_execution_result']) is not None:
1186
+ if getv(from_object, ['inline_data']) is not None:
1185
1187
  setv(
1186
1188
  to_object,
1187
- ['codeExecutionResult'],
1188
- getv(from_object, ['code_execution_result']),
1189
+ ['inlineData'],
1190
+ _Blob_to_mldev(getv(from_object, ['inline_data']), to_object),
1189
1191
  )
1190
1192
 
1191
- if getv(from_object, ['executable_code']) is not None:
1192
- setv(to_object, ['executableCode'], getv(from_object, ['executable_code']))
1193
+ if getv(from_object, ['text']) is not None:
1194
+ setv(to_object, ['text'], getv(from_object, ['text']))
1193
1195
 
1194
- if getv(from_object, ['function_response']) is not None:
1196
+ if getv(from_object, ['thought']) is not None:
1197
+ setv(to_object, ['thought'], getv(from_object, ['thought']))
1198
+
1199
+ if getv(from_object, ['thought_signature']) is not None:
1195
1200
  setv(
1196
1201
  to_object,
1197
- ['functionResponse'],
1198
- getv(from_object, ['function_response']),
1202
+ ['thoughtSignature'],
1203
+ getv(from_object, ['thought_signature']),
1199
1204
  )
1200
1205
 
1201
- if getv(from_object, ['text']) is not None:
1202
- setv(to_object, ['text'], getv(from_object, ['text']))
1206
+ if getv(from_object, ['video_metadata']) is not None:
1207
+ setv(to_object, ['videoMetadata'], getv(from_object, ['video_metadata']))
1203
1208
 
1204
1209
  return to_object
1205
1210
 
@@ -1223,6 +1228,9 @@ def _SpeechConfig_to_vertex(
1223
1228
  parent_object: Optional[dict[str, Any]] = None,
1224
1229
  ) -> dict[str, Any]:
1225
1230
  to_object: dict[str, Any] = {}
1231
+ if getv(from_object, ['language_code']) is not None:
1232
+ setv(to_object, ['languageCode'], getv(from_object, ['language_code']))
1233
+
1226
1234
  if getv(from_object, ['voice_config']) is not None:
1227
1235
  setv(to_object, ['voiceConfig'], getv(from_object, ['voice_config']))
1228
1236
 
@@ -1231,9 +1239,6 @@ def _SpeechConfig_to_vertex(
1231
1239
  'multi_speaker_voice_config parameter is not supported in Vertex AI.'
1232
1240
  )
1233
1241
 
1234
- if getv(from_object, ['language_code']) is not None:
1235
- setv(to_object, ['languageCode'], getv(from_object, ['language_code']))
1236
-
1237
1242
  return to_object
1238
1243
 
1239
1244
 
@@ -1252,13 +1257,6 @@ def _Tool_to_mldev(
1252
1257
  if getv(from_object, ['retrieval']) is not None:
1253
1258
  raise ValueError('retrieval parameter is not supported in Gemini API.')
1254
1259
 
1255
- if getv(from_object, ['google_search']) is not None:
1256
- setv(
1257
- to_object,
1258
- ['googleSearch'],
1259
- _GoogleSearch_to_mldev(getv(from_object, ['google_search']), to_object),
1260
- )
1261
-
1262
1260
  if getv(from_object, ['google_search_retrieval']) is not None:
1263
1261
  setv(
1264
1262
  to_object,
@@ -1266,11 +1264,6 @@ def _Tool_to_mldev(
1266
1264
  getv(from_object, ['google_search_retrieval']),
1267
1265
  )
1268
1266
 
1269
- if getv(from_object, ['enterprise_web_search']) is not None:
1270
- raise ValueError(
1271
- 'enterprise_web_search parameter is not supported in Gemini API.'
1272
- )
1273
-
1274
1267
  if getv(from_object, ['google_maps']) is not None:
1275
1268
  setv(
1276
1269
  to_object,
@@ -1278,15 +1271,27 @@ def _Tool_to_mldev(
1278
1271
  _GoogleMaps_to_mldev(getv(from_object, ['google_maps']), to_object),
1279
1272
  )
1280
1273
 
1281
- if getv(from_object, ['url_context']) is not None:
1282
- setv(to_object, ['urlContext'], getv(from_object, ['url_context']))
1283
-
1284
1274
  if getv(from_object, ['computer_use']) is not None:
1285
1275
  setv(to_object, ['computerUse'], getv(from_object, ['computer_use']))
1286
1276
 
1287
1277
  if getv(from_object, ['code_execution']) is not None:
1288
1278
  setv(to_object, ['codeExecution'], getv(from_object, ['code_execution']))
1289
1279
 
1280
+ if getv(from_object, ['enterprise_web_search']) is not None:
1281
+ raise ValueError(
1282
+ 'enterprise_web_search parameter is not supported in Gemini API.'
1283
+ )
1284
+
1285
+ if getv(from_object, ['google_search']) is not None:
1286
+ setv(
1287
+ to_object,
1288
+ ['googleSearch'],
1289
+ _GoogleSearch_to_mldev(getv(from_object, ['google_search']), to_object),
1290
+ )
1291
+
1292
+ if getv(from_object, ['url_context']) is not None:
1293
+ setv(to_object, ['urlContext'], getv(from_object, ['url_context']))
1294
+
1290
1295
  return to_object
1291
1296
 
1292
1297
 
@@ -1308,9 +1313,6 @@ def _Tool_to_vertex(
1308
1313
  if getv(from_object, ['retrieval']) is not None:
1309
1314
  setv(to_object, ['retrieval'], getv(from_object, ['retrieval']))
1310
1315
 
1311
- if getv(from_object, ['google_search']) is not None:
1312
- setv(to_object, ['googleSearch'], getv(from_object, ['google_search']))
1313
-
1314
1316
  if getv(from_object, ['google_search_retrieval']) is not None:
1315
1317
  setv(
1316
1318
  to_object,
@@ -1318,6 +1320,15 @@ def _Tool_to_vertex(
1318
1320
  getv(from_object, ['google_search_retrieval']),
1319
1321
  )
1320
1322
 
1323
+ if getv(from_object, ['google_maps']) is not None:
1324
+ setv(to_object, ['googleMaps'], getv(from_object, ['google_maps']))
1325
+
1326
+ if getv(from_object, ['computer_use']) is not None:
1327
+ setv(to_object, ['computerUse'], getv(from_object, ['computer_use']))
1328
+
1329
+ if getv(from_object, ['code_execution']) is not None:
1330
+ setv(to_object, ['codeExecution'], getv(from_object, ['code_execution']))
1331
+
1321
1332
  if getv(from_object, ['enterprise_web_search']) is not None:
1322
1333
  setv(
1323
1334
  to_object,
@@ -1325,18 +1336,12 @@ def _Tool_to_vertex(
1325
1336
  getv(from_object, ['enterprise_web_search']),
1326
1337
  )
1327
1338
 
1328
- if getv(from_object, ['google_maps']) is not None:
1329
- setv(to_object, ['googleMaps'], getv(from_object, ['google_maps']))
1339
+ if getv(from_object, ['google_search']) is not None:
1340
+ setv(to_object, ['googleSearch'], getv(from_object, ['google_search']))
1330
1341
 
1331
1342
  if getv(from_object, ['url_context']) is not None:
1332
1343
  setv(to_object, ['urlContext'], getv(from_object, ['url_context']))
1333
1344
 
1334
- if getv(from_object, ['computer_use']) is not None:
1335
- setv(to_object, ['computerUse'], getv(from_object, ['computer_use']))
1336
-
1337
- if getv(from_object, ['code_execution']) is not None:
1338
- setv(to_object, ['codeExecution'], getv(from_object, ['code_execution']))
1339
-
1340
1345
  return to_object
1341
1346
 
1342
1347
 
@@ -28,12 +28,12 @@ def _Blob_to_mldev(
28
28
  parent_object: Optional[dict[str, Any]] = None,
29
29
  ) -> dict[str, Any]:
30
30
  to_object: dict[str, Any] = {}
31
- if getv(from_object, ['display_name']) is not None:
32
- raise ValueError('display_name parameter is not supported in Gemini API.')
33
-
34
31
  if getv(from_object, ['data']) is not None:
35
32
  setv(to_object, ['data'], getv(from_object, ['data']))
36
33
 
34
+ if getv(from_object, ['display_name']) is not None:
35
+ raise ValueError('display_name parameter is not supported in Gemini API.')
36
+
37
37
  if getv(from_object, ['mime_type']) is not None:
38
38
  setv(to_object, ['mimeType'], getv(from_object, ['mime_type']))
39
39
 
@@ -167,16 +167,16 @@ def _GoogleSearch_to_mldev(
167
167
  parent_object: Optional[dict[str, Any]] = None,
168
168
  ) -> dict[str, Any]:
169
169
  to_object: dict[str, Any] = {}
170
- if getv(from_object, ['time_range_filter']) is not None:
171
- setv(
172
- to_object, ['timeRangeFilter'], getv(from_object, ['time_range_filter'])
173
- )
174
-
175
170
  if getv(from_object, ['exclude_domains']) is not None:
176
171
  raise ValueError(
177
172
  'exclude_domains parameter is not supported in Gemini API.'
178
173
  )
179
174
 
175
+ if getv(from_object, ['time_range_filter']) is not None:
176
+ setv(
177
+ to_object, ['timeRangeFilter'], getv(from_object, ['time_range_filter'])
178
+ )
179
+
180
180
  return to_object
181
181
 
182
182
 
@@ -360,19 +360,19 @@ def _Part_to_mldev(
360
360
  parent_object: Optional[dict[str, Any]] = None,
361
361
  ) -> dict[str, Any]:
362
362
  to_object: dict[str, Any] = {}
363
- if getv(from_object, ['video_metadata']) is not None:
364
- setv(to_object, ['videoMetadata'], getv(from_object, ['video_metadata']))
365
-
366
- if getv(from_object, ['thought']) is not None:
367
- setv(to_object, ['thought'], getv(from_object, ['thought']))
363
+ if getv(from_object, ['function_call']) is not None:
364
+ setv(to_object, ['functionCall'], getv(from_object, ['function_call']))
368
365
 
369
- if getv(from_object, ['inline_data']) is not None:
366
+ if getv(from_object, ['code_execution_result']) is not None:
370
367
  setv(
371
368
  to_object,
372
- ['inlineData'],
373
- _Blob_to_mldev(getv(from_object, ['inline_data']), to_object),
369
+ ['codeExecutionResult'],
370
+ getv(from_object, ['code_execution_result']),
374
371
  )
375
372
 
373
+ if getv(from_object, ['executable_code']) is not None:
374
+ setv(to_object, ['executableCode'], getv(from_object, ['executable_code']))
375
+
376
376
  if getv(from_object, ['file_data']) is not None:
377
377
  setv(
378
378
  to_object,
@@ -380,35 +380,35 @@ def _Part_to_mldev(
380
380
  _FileData_to_mldev(getv(from_object, ['file_data']), to_object),
381
381
  )
382
382
 
383
- if getv(from_object, ['thought_signature']) is not None:
383
+ if getv(from_object, ['function_response']) is not None:
384
384
  setv(
385
385
  to_object,
386
- ['thoughtSignature'],
387
- getv(from_object, ['thought_signature']),
386
+ ['functionResponse'],
387
+ getv(from_object, ['function_response']),
388
388
  )
389
389
 
390
- if getv(from_object, ['function_call']) is not None:
391
- setv(to_object, ['functionCall'], getv(from_object, ['function_call']))
392
-
393
- if getv(from_object, ['code_execution_result']) is not None:
390
+ if getv(from_object, ['inline_data']) is not None:
394
391
  setv(
395
392
  to_object,
396
- ['codeExecutionResult'],
397
- getv(from_object, ['code_execution_result']),
393
+ ['inlineData'],
394
+ _Blob_to_mldev(getv(from_object, ['inline_data']), to_object),
398
395
  )
399
396
 
400
- if getv(from_object, ['executable_code']) is not None:
401
- setv(to_object, ['executableCode'], getv(from_object, ['executable_code']))
397
+ if getv(from_object, ['text']) is not None:
398
+ setv(to_object, ['text'], getv(from_object, ['text']))
402
399
 
403
- if getv(from_object, ['function_response']) is not None:
400
+ if getv(from_object, ['thought']) is not None:
401
+ setv(to_object, ['thought'], getv(from_object, ['thought']))
402
+
403
+ if getv(from_object, ['thought_signature']) is not None:
404
404
  setv(
405
405
  to_object,
406
- ['functionResponse'],
407
- getv(from_object, ['function_response']),
406
+ ['thoughtSignature'],
407
+ getv(from_object, ['thought_signature']),
408
408
  )
409
409
 
410
- if getv(from_object, ['text']) is not None:
411
- setv(to_object, ['text'], getv(from_object, ['text']))
410
+ if getv(from_object, ['video_metadata']) is not None:
411
+ setv(to_object, ['videoMetadata'], getv(from_object, ['video_metadata']))
412
412
 
413
413
  return to_object
414
414
 
@@ -442,13 +442,6 @@ def _Tool_to_mldev(
442
442
  if getv(from_object, ['retrieval']) is not None:
443
443
  raise ValueError('retrieval parameter is not supported in Gemini API.')
444
444
 
445
- if getv(from_object, ['google_search']) is not None:
446
- setv(
447
- to_object,
448
- ['googleSearch'],
449
- _GoogleSearch_to_mldev(getv(from_object, ['google_search']), to_object),
450
- )
451
-
452
445
  if getv(from_object, ['google_search_retrieval']) is not None:
453
446
  setv(
454
447
  to_object,
@@ -456,11 +449,6 @@ def _Tool_to_mldev(
456
449
  getv(from_object, ['google_search_retrieval']),
457
450
  )
458
451
 
459
- if getv(from_object, ['enterprise_web_search']) is not None:
460
- raise ValueError(
461
- 'enterprise_web_search parameter is not supported in Gemini API.'
462
- )
463
-
464
452
  if getv(from_object, ['google_maps']) is not None:
465
453
  setv(
466
454
  to_object,
@@ -468,13 +456,25 @@ def _Tool_to_mldev(
468
456
  _GoogleMaps_to_mldev(getv(from_object, ['google_maps']), to_object),
469
457
  )
470
458
 
471
- if getv(from_object, ['url_context']) is not None:
472
- setv(to_object, ['urlContext'], getv(from_object, ['url_context']))
473
-
474
459
  if getv(from_object, ['computer_use']) is not None:
475
460
  setv(to_object, ['computerUse'], getv(from_object, ['computer_use']))
476
461
 
477
462
  if getv(from_object, ['code_execution']) is not None:
478
463
  setv(to_object, ['codeExecution'], getv(from_object, ['code_execution']))
479
464
 
465
+ if getv(from_object, ['enterprise_web_search']) is not None:
466
+ raise ValueError(
467
+ 'enterprise_web_search parameter is not supported in Gemini API.'
468
+ )
469
+
470
+ if getv(from_object, ['google_search']) is not None:
471
+ setv(
472
+ to_object,
473
+ ['googleSearch'],
474
+ _GoogleSearch_to_mldev(getv(from_object, ['google_search']), to_object),
475
+ )
476
+
477
+ if getv(from_object, ['url_context']) is not None:
478
+ setv(to_object, ['urlContext'], getv(from_object, ['url_context']))
479
+
480
480
  return to_object
@@ -91,7 +91,16 @@ def _is_duck_type_of(obj: Any, cls: type[pydantic.BaseModel]) -> bool:
91
91
  return False
92
92
 
93
93
  # Check if the object has all of the Pydantic model's defined fields.
94
- return all(hasattr(obj, field) for field in cls.model_fields)
94
+ all_matched = all(hasattr(obj, field) for field in cls.model_fields)
95
+ if not all_matched and isinstance(obj, pydantic.BaseModel):
96
+ # Check the other way around if obj is a Pydantic model.
97
+ # Check if the Pydantic model has all of the object's defined fields.
98
+ try:
99
+ obj_private = cls()
100
+ all_matched = all(hasattr(obj_private, f) for f in type(obj).model_fields)
101
+ except ValueError:
102
+ return False
103
+ return all_matched
95
104
 
96
105
 
97
106
  def _resource_name(