google-genai 1.56.0__py3-none-any.whl → 1.58.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.
Files changed (246) hide show
  1. google/genai/_api_client.py +49 -26
  2. google/genai/_interactions/__init__.py +3 -0
  3. google/genai/_interactions/_base_client.py +1 -1
  4. google/genai/_interactions/_client.py +57 -3
  5. google/genai/_interactions/_client_adapter.py +48 -0
  6. google/genai/_interactions/types/__init__.py +6 -0
  7. google/genai/_interactions/types/audio_content.py +2 -0
  8. google/genai/_interactions/types/audio_content_param.py +2 -0
  9. google/genai/_interactions/types/content.py +65 -0
  10. google/genai/_interactions/types/content_delta.py +10 -2
  11. google/genai/_interactions/types/content_param.py +63 -0
  12. google/genai/_interactions/types/content_start.py +5 -46
  13. google/genai/_interactions/types/content_stop.py +1 -2
  14. google/genai/_interactions/types/document_content.py +2 -0
  15. google/genai/_interactions/types/document_content_param.py +2 -0
  16. google/genai/_interactions/types/error_event.py +1 -2
  17. google/genai/_interactions/types/file_search_call_content.py +32 -0
  18. google/genai/_interactions/types/file_search_call_content_param.py +31 -0
  19. google/genai/_interactions/types/generation_config.py +4 -0
  20. google/genai/_interactions/types/generation_config_param.py +4 -0
  21. google/genai/_interactions/types/image_config.py +31 -0
  22. google/genai/_interactions/types/image_config_param.py +30 -0
  23. google/genai/_interactions/types/image_content.py +2 -0
  24. google/genai/_interactions/types/image_content_param.py +2 -0
  25. google/genai/_interactions/types/interaction.py +6 -52
  26. google/genai/_interactions/types/interaction_create_params.py +4 -22
  27. google/genai/_interactions/types/interaction_event.py +1 -2
  28. google/genai/_interactions/types/interaction_sse_event.py +5 -3
  29. google/genai/_interactions/types/interaction_status_update.py +1 -2
  30. google/genai/_interactions/types/model.py +1 -0
  31. google/genai/_interactions/types/model_param.py +1 -0
  32. google/genai/_interactions/types/turn.py +3 -44
  33. google/genai/_interactions/types/turn_param.py +4 -40
  34. google/genai/_interactions/types/usage.py +1 -1
  35. google/genai/_interactions/types/usage_param.py +1 -1
  36. google/genai/_interactions/types/video_content.py +2 -0
  37. google/genai/_interactions/types/video_content_param.py +2 -0
  38. google/genai/_live_converters.py +118 -34
  39. google/genai/_local_tokenizer_loader.py +1 -0
  40. google/genai/_tokens_converters.py +14 -14
  41. google/genai/_transformers.py +15 -21
  42. google/genai/batches.py +27 -22
  43. google/genai/caches.py +42 -42
  44. google/genai/chats.py +0 -2
  45. google/genai/client.py +61 -55
  46. google/genai/files.py +224 -0
  47. google/genai/live.py +1 -1
  48. google/genai/models.py +56 -44
  49. google/genai/tests/__init__.py +21 -0
  50. google/genai/tests/afc/__init__.py +21 -0
  51. google/genai/tests/afc/test_convert_if_exist_pydantic_model.py +309 -0
  52. google/genai/tests/afc/test_convert_number_values_for_function_call_args.py +63 -0
  53. google/genai/tests/afc/test_find_afc_incompatible_tool_indexes.py +240 -0
  54. google/genai/tests/afc/test_generate_content_stream_afc.py +530 -0
  55. google/genai/tests/afc/test_generate_content_stream_afc_thoughts.py +77 -0
  56. google/genai/tests/afc/test_get_function_map.py +176 -0
  57. google/genai/tests/afc/test_get_function_response_parts.py +277 -0
  58. google/genai/tests/afc/test_get_max_remote_calls_for_afc.py +130 -0
  59. google/genai/tests/afc/test_invoke_function_from_dict_args.py +241 -0
  60. google/genai/tests/afc/test_raise_error_for_afc_incompatible_config.py +159 -0
  61. google/genai/tests/afc/test_should_append_afc_history.py +53 -0
  62. google/genai/tests/afc/test_should_disable_afc.py +214 -0
  63. google/genai/tests/batches/__init__.py +17 -0
  64. google/genai/tests/batches/test_cancel.py +77 -0
  65. google/genai/tests/batches/test_create.py +78 -0
  66. google/genai/tests/batches/test_create_with_bigquery.py +113 -0
  67. google/genai/tests/batches/test_create_with_file.py +82 -0
  68. google/genai/tests/batches/test_create_with_gcs.py +125 -0
  69. google/genai/tests/batches/test_create_with_inlined_requests.py +255 -0
  70. google/genai/tests/batches/test_delete.py +86 -0
  71. google/genai/tests/batches/test_embedding.py +157 -0
  72. google/genai/tests/batches/test_get.py +78 -0
  73. google/genai/tests/batches/test_list.py +79 -0
  74. google/genai/tests/caches/__init__.py +17 -0
  75. google/genai/tests/caches/constants.py +29 -0
  76. google/genai/tests/caches/test_create.py +210 -0
  77. google/genai/tests/caches/test_create_custom_url.py +105 -0
  78. google/genai/tests/caches/test_delete.py +54 -0
  79. google/genai/tests/caches/test_delete_custom_url.py +52 -0
  80. google/genai/tests/caches/test_get.py +94 -0
  81. google/genai/tests/caches/test_get_custom_url.py +52 -0
  82. google/genai/tests/caches/test_list.py +68 -0
  83. google/genai/tests/caches/test_update.py +70 -0
  84. google/genai/tests/caches/test_update_custom_url.py +58 -0
  85. google/genai/tests/chats/__init__.py +1 -0
  86. google/genai/tests/chats/test_get_history.py +598 -0
  87. google/genai/tests/chats/test_send_message.py +844 -0
  88. google/genai/tests/chats/test_validate_response.py +90 -0
  89. google/genai/tests/client/__init__.py +17 -0
  90. google/genai/tests/client/test_async_stream.py +427 -0
  91. google/genai/tests/client/test_client_close.py +197 -0
  92. google/genai/tests/client/test_client_initialization.py +1687 -0
  93. google/genai/tests/client/test_client_requests.py +221 -0
  94. google/genai/tests/client/test_custom_client.py +104 -0
  95. google/genai/tests/client/test_http_options.py +178 -0
  96. google/genai/tests/client/test_replay_client_equality.py +168 -0
  97. google/genai/tests/client/test_retries.py +846 -0
  98. google/genai/tests/client/test_upload_errors.py +136 -0
  99. google/genai/tests/common/__init__.py +17 -0
  100. google/genai/tests/common/test_common.py +954 -0
  101. google/genai/tests/conftest.py +162 -0
  102. google/genai/tests/documents/__init__.py +17 -0
  103. google/genai/tests/documents/test_delete.py +51 -0
  104. google/genai/tests/documents/test_get.py +85 -0
  105. google/genai/tests/documents/test_list.py +72 -0
  106. google/genai/tests/errors/__init__.py +1 -0
  107. google/genai/tests/errors/test_api_error.py +417 -0
  108. google/genai/tests/file_search_stores/__init__.py +17 -0
  109. google/genai/tests/file_search_stores/test_create.py +66 -0
  110. google/genai/tests/file_search_stores/test_delete.py +64 -0
  111. google/genai/tests/file_search_stores/test_get.py +94 -0
  112. google/genai/tests/file_search_stores/test_import_file.py +112 -0
  113. google/genai/tests/file_search_stores/test_list.py +57 -0
  114. google/genai/tests/file_search_stores/test_upload_to_file_search_store.py +141 -0
  115. google/genai/tests/files/__init__.py +17 -0
  116. google/genai/tests/files/test_delete.py +46 -0
  117. google/genai/tests/files/test_download.py +85 -0
  118. google/genai/tests/files/test_get.py +46 -0
  119. google/genai/tests/files/test_list.py +72 -0
  120. google/genai/tests/files/test_register.py +272 -0
  121. google/genai/tests/files/test_register_table.py +70 -0
  122. google/genai/tests/files/test_upload.py +255 -0
  123. google/genai/tests/imports/test_no_optional_imports.py +28 -0
  124. google/genai/tests/interactions/test_auth.py +476 -0
  125. google/genai/tests/interactions/test_integration.py +84 -0
  126. google/genai/tests/interactions/test_paths.py +105 -0
  127. google/genai/tests/live/__init__.py +16 -0
  128. google/genai/tests/live/test_live.py +2143 -0
  129. google/genai/tests/live/test_live_music.py +362 -0
  130. google/genai/tests/live/test_live_response.py +163 -0
  131. google/genai/tests/live/test_send_client_content.py +147 -0
  132. google/genai/tests/live/test_send_realtime_input.py +268 -0
  133. google/genai/tests/live/test_send_tool_response.py +222 -0
  134. google/genai/tests/local_tokenizer/__init__.py +17 -0
  135. google/genai/tests/local_tokenizer/test_local_tokenizer.py +343 -0
  136. google/genai/tests/local_tokenizer/test_local_tokenizer_loader.py +235 -0
  137. google/genai/tests/mcp/__init__.py +17 -0
  138. google/genai/tests/mcp/test_has_mcp_tool_usage.py +89 -0
  139. google/genai/tests/mcp/test_mcp_to_gemini_tools.py +191 -0
  140. google/genai/tests/mcp/test_parse_config_for_mcp_sessions.py +201 -0
  141. google/genai/tests/mcp/test_parse_config_for_mcp_usage.py +130 -0
  142. google/genai/tests/mcp/test_set_mcp_usage_header.py +72 -0
  143. google/genai/tests/models/__init__.py +17 -0
  144. google/genai/tests/models/constants.py +8 -0
  145. google/genai/tests/models/test_compute_tokens.py +120 -0
  146. google/genai/tests/models/test_count_tokens.py +159 -0
  147. google/genai/tests/models/test_delete.py +107 -0
  148. google/genai/tests/models/test_edit_image.py +264 -0
  149. google/genai/tests/models/test_embed_content.py +94 -0
  150. google/genai/tests/models/test_function_call_streaming.py +442 -0
  151. google/genai/tests/models/test_generate_content.py +2501 -0
  152. google/genai/tests/models/test_generate_content_cached_content.py +132 -0
  153. google/genai/tests/models/test_generate_content_config_zero_value.py +103 -0
  154. google/genai/tests/models/test_generate_content_from_apikey.py +44 -0
  155. google/genai/tests/models/test_generate_content_http_options.py +40 -0
  156. google/genai/tests/models/test_generate_content_image_generation.py +143 -0
  157. google/genai/tests/models/test_generate_content_mcp.py +343 -0
  158. google/genai/tests/models/test_generate_content_media_resolution.py +97 -0
  159. google/genai/tests/models/test_generate_content_model.py +139 -0
  160. google/genai/tests/models/test_generate_content_part.py +821 -0
  161. google/genai/tests/models/test_generate_content_thought.py +76 -0
  162. google/genai/tests/models/test_generate_content_tools.py +1761 -0
  163. google/genai/tests/models/test_generate_images.py +191 -0
  164. google/genai/tests/models/test_generate_videos.py +759 -0
  165. google/genai/tests/models/test_get.py +104 -0
  166. google/genai/tests/models/test_list.py +233 -0
  167. google/genai/tests/models/test_recontext_image.py +189 -0
  168. google/genai/tests/models/test_segment_image.py +148 -0
  169. google/genai/tests/models/test_update.py +95 -0
  170. google/genai/tests/models/test_upscale_image.py +157 -0
  171. google/genai/tests/operations/__init__.py +17 -0
  172. google/genai/tests/operations/test_get.py +38 -0
  173. google/genai/tests/public_samples/__init__.py +17 -0
  174. google/genai/tests/public_samples/test_gemini_text_only.py +34 -0
  175. google/genai/tests/pytest_helper.py +246 -0
  176. google/genai/tests/shared/__init__.py +16 -0
  177. google/genai/tests/shared/batches/__init__.py +14 -0
  178. google/genai/tests/shared/batches/test_create_delete.py +57 -0
  179. google/genai/tests/shared/batches/test_create_get_cancel.py +56 -0
  180. google/genai/tests/shared/batches/test_list.py +40 -0
  181. google/genai/tests/shared/caches/__init__.py +14 -0
  182. google/genai/tests/shared/caches/test_create_get_delete.py +67 -0
  183. google/genai/tests/shared/caches/test_create_update_get.py +71 -0
  184. google/genai/tests/shared/caches/test_list.py +40 -0
  185. google/genai/tests/shared/chats/__init__.py +14 -0
  186. google/genai/tests/shared/chats/test_send_message.py +48 -0
  187. google/genai/tests/shared/chats/test_send_message_stream.py +50 -0
  188. google/genai/tests/shared/files/__init__.py +14 -0
  189. google/genai/tests/shared/files/test_list.py +41 -0
  190. google/genai/tests/shared/files/test_upload_get_delete.py +54 -0
  191. google/genai/tests/shared/models/__init__.py +14 -0
  192. google/genai/tests/shared/models/test_compute_tokens.py +41 -0
  193. google/genai/tests/shared/models/test_count_tokens.py +40 -0
  194. google/genai/tests/shared/models/test_edit_image.py +67 -0
  195. google/genai/tests/shared/models/test_embed.py +40 -0
  196. google/genai/tests/shared/models/test_generate_content.py +39 -0
  197. google/genai/tests/shared/models/test_generate_content_stream.py +54 -0
  198. google/genai/tests/shared/models/test_generate_images.py +40 -0
  199. google/genai/tests/shared/models/test_generate_videos.py +38 -0
  200. google/genai/tests/shared/models/test_list.py +37 -0
  201. google/genai/tests/shared/models/test_recontext_image.py +55 -0
  202. google/genai/tests/shared/models/test_segment_image.py +52 -0
  203. google/genai/tests/shared/models/test_upscale_image.py +52 -0
  204. google/genai/tests/shared/tunings/__init__.py +16 -0
  205. google/genai/tests/shared/tunings/test_create.py +46 -0
  206. google/genai/tests/shared/tunings/test_create_get_cancel.py +56 -0
  207. google/genai/tests/shared/tunings/test_list.py +39 -0
  208. google/genai/tests/tokens/__init__.py +16 -0
  209. google/genai/tests/tokens/test_create.py +154 -0
  210. google/genai/tests/transformers/__init__.py +17 -0
  211. google/genai/tests/transformers/test_blobs.py +84 -0
  212. google/genai/tests/transformers/test_bytes.py +15 -0
  213. google/genai/tests/transformers/test_duck_type.py +96 -0
  214. google/genai/tests/transformers/test_function_responses.py +72 -0
  215. google/genai/tests/transformers/test_schema.py +653 -0
  216. google/genai/tests/transformers/test_t_batch.py +286 -0
  217. google/genai/tests/transformers/test_t_content.py +160 -0
  218. google/genai/tests/transformers/test_t_contents.py +398 -0
  219. google/genai/tests/transformers/test_t_part.py +85 -0
  220. google/genai/tests/transformers/test_t_parts.py +87 -0
  221. google/genai/tests/transformers/test_t_tool.py +157 -0
  222. google/genai/tests/transformers/test_t_tools.py +195 -0
  223. google/genai/tests/tunings/__init__.py +16 -0
  224. google/genai/tests/tunings/test_cancel.py +39 -0
  225. google/genai/tests/tunings/test_end_to_end.py +106 -0
  226. google/genai/tests/tunings/test_get.py +67 -0
  227. google/genai/tests/tunings/test_list.py +75 -0
  228. google/genai/tests/tunings/test_tune.py +268 -0
  229. google/genai/tests/types/__init__.py +16 -0
  230. google/genai/tests/types/test_bytes_internal.py +271 -0
  231. google/genai/tests/types/test_bytes_type.py +152 -0
  232. google/genai/tests/types/test_future.py +101 -0
  233. google/genai/tests/types/test_optional_types.py +36 -0
  234. google/genai/tests/types/test_part_type.py +616 -0
  235. google/genai/tests/types/test_schema_from_json_schema.py +417 -0
  236. google/genai/tests/types/test_schema_json_schema.py +468 -0
  237. google/genai/tests/types/test_types.py +2903 -0
  238. google/genai/types.py +631 -488
  239. google/genai/version.py +1 -1
  240. {google_genai-1.56.0.dist-info → google_genai-1.58.0.dist-info}/METADATA +6 -11
  241. google_genai-1.58.0.dist-info/RECORD +358 -0
  242. google_genai-1.56.0.dist-info/RECORD +0 -162
  243. /google/genai/{_interactions/py.typed → tests/interactions/__init__.py} +0 -0
  244. {google_genai-1.56.0.dist-info → google_genai-1.58.0.dist-info}/WHEEL +0 -0
  245. {google_genai-1.56.0.dist-info → google_genai-1.58.0.dist-info}/licenses/LICENSE +0 -0
  246. {google_genai-1.56.0.dist-info → google_genai-1.58.0.dist-info}/top_level.txt +0 -0
@@ -715,19 +715,23 @@ class BaseApiClient:
715
715
  self._async_httpx_client = self._http_options.httpx_async_client
716
716
  else:
717
717
  self._async_httpx_client = AsyncHttpxClient(**async_client_args)
718
+
719
+ # Initialize the aiohttp client session.
720
+ self._aiohttp_session: Optional[aiohttp.ClientSession] = None
718
721
  if self._use_aiohttp():
719
722
  try:
720
723
  import aiohttp # pylint: disable=g-import-not-at-top
721
- # Do it once at the genai.Client level. Share among all requests.
722
- self._async_client_session_request_args = self._ensure_aiohttp_ssl_ctx(
723
- self._http_options
724
- )
724
+
725
+ if self._http_options.aiohttp_client:
726
+ self._aiohttp_session = self._http_options.aiohttp_client
727
+ else:
728
+ # Do it once at the genai.Client level. Share among all requests.
729
+ self._async_client_session_request_args = (
730
+ self._ensure_aiohttp_ssl_ctx(self._http_options)
731
+ )
725
732
  except ImportError:
726
733
  pass
727
734
 
728
- # Initialize the aiohttp client session.
729
- self._aiohttp_session: Optional[aiohttp.ClientSession] = None
730
-
731
735
  retry_kwargs = retry_args(self._http_options.retry_options)
732
736
  self._websocket_ssl_ctx = self._ensure_websocket_ssl_ctx(self._http_options)
733
737
  self._retry = tenacity.Retrying(**retry_kwargs)
@@ -984,12 +988,7 @@ class BaseApiClient:
984
988
  self.project = project
985
989
 
986
990
  if self._credentials:
987
- if self._credentials.expired or not self._credentials.token:
988
- # Only refresh when it needs to. Default expiration is 3600 seconds.
989
- refresh_auth(self._credentials)
990
- if not self._credentials.token:
991
- raise RuntimeError('Could not resolve API token from the environment')
992
- return self._credentials.token # type: ignore[no-any-return]
991
+ return get_token_from_credentials(self, self._credentials) # type: ignore[no-any-return]
993
992
  else:
994
993
  raise RuntimeError('Could not resolve API token from the environment')
995
994
 
@@ -1034,18 +1033,10 @@ class BaseApiClient:
1034
1033
  self.project = project
1035
1034
 
1036
1035
  if self._credentials:
1037
- if self._credentials.expired or not self._credentials.token:
1038
- # Only refresh when it needs to. Default expiration is 3600 seconds.
1039
- async_auth_lock = await self._get_async_auth_lock()
1040
- async with async_auth_lock:
1041
- if self._credentials.expired or not self._credentials.token:
1042
- # Double check that the credentials expired before refreshing.
1043
- await asyncio.to_thread(refresh_auth, self._credentials)
1044
-
1045
- if not self._credentials.token:
1046
- raise RuntimeError('Could not resolve API token from the environment')
1047
-
1048
- return self._credentials.token
1036
+ return await async_get_token_from_credentials(
1037
+ self,
1038
+ self._credentials
1039
+ ) # type: ignore[no-any-return]
1049
1040
  else:
1050
1041
  raise RuntimeError('Could not resolve API token from the environment')
1051
1042
 
@@ -1905,7 +1896,7 @@ class BaseApiClient:
1905
1896
  # close the client when the object is garbage collected.
1906
1897
  if not self._http_options.httpx_async_client:
1907
1898
  await self._async_httpx_client.aclose()
1908
- if self._aiohttp_session:
1899
+ if self._aiohttp_session and not self._http_options.aiohttp_client:
1909
1900
  await self._aiohttp_session.close()
1910
1901
 
1911
1902
  def __del__(self) -> None:
@@ -1925,3 +1916,35 @@ class BaseApiClient:
1925
1916
  asyncio.get_running_loop().create_task(self.aclose())
1926
1917
  except Exception: # pylint: disable=broad-except
1927
1918
  pass
1919
+
1920
+ def get_token_from_credentials(
1921
+ client: 'BaseApiClient',
1922
+ credentials: google.auth.credentials.Credentials
1923
+ ) -> str:
1924
+ """Refreshes the authentication token for the given credentials."""
1925
+ if credentials.expired or not credentials.token:
1926
+ # Only refresh when it needs to. Default expiration is 3600 seconds.
1927
+ refresh_auth(credentials)
1928
+ if not credentials.token:
1929
+ raise RuntimeError('Could not resolve API token from the environment')
1930
+ return credentials.token # type: ignore[no-any-return]
1931
+
1932
+ async def async_get_token_from_credentials(
1933
+ client: 'BaseApiClient',
1934
+ credentials: google.auth.credentials.Credentials
1935
+ ) -> str:
1936
+ """Refreshes the authentication token for the given credentials."""
1937
+ if credentials.expired or not credentials.token:
1938
+ # Only refresh when it needs to. Default expiration is 3600 seconds.
1939
+ async_auth_lock = await client._get_async_auth_lock()
1940
+ async with async_auth_lock:
1941
+ if credentials.expired or not credentials.token:
1942
+ # Double check that the credentials expired before refreshing.
1943
+ await asyncio.to_thread(refresh_auth, credentials)
1944
+
1945
+ if not credentials.token:
1946
+ raise RuntimeError('Could not resolve API token from the environment')
1947
+
1948
+ return credentials.token # type: ignore[no-any-return]
1949
+
1950
+
@@ -53,6 +53,7 @@ from ._exceptions import (
53
53
  )
54
54
  from ._base_client import DefaultHttpxClient, DefaultAioHttpClient, DefaultAsyncHttpxClient
55
55
  from ._utils._logs import setup_logging as _setup_logging
56
+ from ._client_adapter import GeminiNextGenAPIClientAdapter, AsyncGeminiNextGenAPIClientAdapter
56
57
 
57
58
  __all__ = [
58
59
  "types",
@@ -96,6 +97,8 @@ __all__ = [
96
97
  "DefaultHttpxClient",
97
98
  "DefaultAsyncHttpxClient",
98
99
  "DefaultAioHttpClient",
100
+ "AsyncGeminiNextGenAPIClientAdapter",
101
+ "GeminiNextGenAPIClientAdapter"
99
102
  ]
100
103
 
101
104
  if not _t.TYPE_CHECKING:
@@ -1798,7 +1798,7 @@ class AsyncAPIClient(BaseClient[httpx.AsyncClient, AsyncStream[Any]]):
1798
1798
  options: RequestOptions = {},
1799
1799
  ) -> ResponseT:
1800
1800
  opts = FinalRequestOptions.construct(
1801
- method="patch", url=path, json_data=body, files=to_httpx_files(files), **options
1801
+ method="patch", url=path, json_data=body, files=await async_to_httpx_files(files), **options
1802
1802
  )
1803
1803
  return await self.request(cast_to, opts)
1804
1804
 
@@ -37,6 +37,7 @@ from ._types import (
37
37
  )
38
38
  from ._utils import is_given, get_async_library
39
39
  from ._compat import cached_property
40
+ from ._models import FinalRequestOptions
40
41
  from ._version import __version__
41
42
  from ._streaming import Stream as Stream, AsyncStream as AsyncStream
42
43
  from ._exceptions import APIStatusError
@@ -45,6 +46,7 @@ from ._base_client import (
45
46
  SyncAPIClient,
46
47
  AsyncAPIClient,
47
48
  )
49
+ from ._client_adapter import GeminiNextGenAPIClientAdapter, AsyncGeminiNextGenAPIClientAdapter
48
50
 
49
51
  if TYPE_CHECKING:
50
52
  from .resources import interactions
@@ -66,6 +68,7 @@ class GeminiNextGenAPIClient(SyncAPIClient):
66
68
  # client options
67
69
  api_key: str | None
68
70
  api_version: str
71
+ client_adapter: GeminiNextGenAPIClientAdapter | None
69
72
 
70
73
  def __init__(
71
74
  self,
@@ -81,6 +84,7 @@ class GeminiNextGenAPIClient(SyncAPIClient):
81
84
  # We provide a `DefaultHttpxClient` class that you can pass to retain the default values we use for `limits`, `timeout` & `follow_redirects`.
82
85
  # See the [httpx documentation](https://www.python-httpx.org/api/#client) for more details.
83
86
  http_client: httpx.Client | None = None,
87
+ client_adapter: GeminiNextGenAPIClientAdapter | None = None,
84
88
  # Enable or disable schema validation for data returned by the API.
85
89
  # When enabled an error APIResponseValidationError is raised
86
90
  # if the API responds with invalid data for the expected schema.
@@ -108,6 +112,8 @@ class GeminiNextGenAPIClient(SyncAPIClient):
108
112
  if base_url is None:
109
113
  base_url = f"https://generativelanguage.googleapis.com"
110
114
 
115
+ self.client_adapter = client_adapter
116
+
111
117
  super().__init__(
112
118
  version=__version__,
113
119
  base_url=base_url,
@@ -159,15 +165,35 @@ class GeminiNextGenAPIClient(SyncAPIClient):
159
165
 
160
166
  @override
161
167
  def _validate_headers(self, headers: Headers, custom_headers: Headers) -> None:
168
+ if headers.get("Authorization") or custom_headers.get("Authorization") or isinstance(custom_headers.get("Authorization"), Omit):
169
+ return
162
170
  if self.api_key and headers.get("x-goog-api-key"):
163
171
  return
164
- if isinstance(custom_headers.get("x-goog-api-key"), Omit):
172
+ if custom_headers.get("x-goog-api-key") or isinstance(custom_headers.get("x-goog-api-key"), Omit):
165
173
  return
166
174
 
167
175
  raise TypeError(
168
176
  '"Could not resolve authentication method. Expected the api_key to be set. Or for the `x-goog-api-key` headers to be explicitly omitted"'
169
177
  )
170
-
178
+
179
+ @override
180
+ def _prepare_options(self, options: FinalRequestOptions) -> FinalRequestOptions:
181
+ if not self.client_adapter or not self.client_adapter.is_vertex_ai():
182
+ return options
183
+
184
+ headers = options.headers or {}
185
+ has_auth = headers.get("Authorization") or headers.get("x-goog-api-key") # pytype: disable=attribute-error
186
+ if has_auth:
187
+ return options
188
+
189
+ adapted_headers = self.client_adapter.get_auth_headers()
190
+ if adapted_headers:
191
+ options.headers = {
192
+ **adapted_headers,
193
+ **headers
194
+ }
195
+ return options
196
+
171
197
  def copy(
172
198
  self,
173
199
  *,
@@ -181,6 +207,7 @@ class GeminiNextGenAPIClient(SyncAPIClient):
181
207
  set_default_headers: Mapping[str, str] | None = None,
182
208
  default_query: Mapping[str, object] | None = None,
183
209
  set_default_query: Mapping[str, object] | None = None,
210
+ client_adapter: GeminiNextGenAPIClientAdapter | None = None,
184
211
  _extra_kwargs: Mapping[str, Any] = {},
185
212
  ) -> Self:
186
213
  """
@@ -214,6 +241,7 @@ class GeminiNextGenAPIClient(SyncAPIClient):
214
241
  max_retries=max_retries if is_given(max_retries) else self.max_retries,
215
242
  default_headers=headers,
216
243
  default_query=params,
244
+ client_adapter=self.client_adapter or client_adapter,
217
245
  **_extra_kwargs,
218
246
  )
219
247
 
@@ -262,6 +290,7 @@ class AsyncGeminiNextGenAPIClient(AsyncAPIClient):
262
290
  # client options
263
291
  api_key: str | None
264
292
  api_version: str
293
+ client_adapter: AsyncGeminiNextGenAPIClientAdapter | None
265
294
 
266
295
  def __init__(
267
296
  self,
@@ -277,6 +306,7 @@ class AsyncGeminiNextGenAPIClient(AsyncAPIClient):
277
306
  # We provide a `DefaultAsyncHttpxClient` class that you can pass to retain the default values we use for `limits`, `timeout` & `follow_redirects`.
278
307
  # See the [httpx documentation](https://www.python-httpx.org/api/#asyncclient) for more details.
279
308
  http_client: httpx.AsyncClient | None = None,
309
+ client_adapter: AsyncGeminiNextGenAPIClientAdapter | None = None,
280
310
  # Enable or disable schema validation for data returned by the API.
281
311
  # When enabled an error APIResponseValidationError is raised
282
312
  # if the API responds with invalid data for the expected schema.
@@ -304,6 +334,8 @@ class AsyncGeminiNextGenAPIClient(AsyncAPIClient):
304
334
  if base_url is None:
305
335
  base_url = f"https://generativelanguage.googleapis.com"
306
336
 
337
+ self.client_adapter = client_adapter
338
+
307
339
  super().__init__(
308
340
  version=__version__,
309
341
  base_url=base_url,
@@ -355,14 +387,34 @@ class AsyncGeminiNextGenAPIClient(AsyncAPIClient):
355
387
 
356
388
  @override
357
389
  def _validate_headers(self, headers: Headers, custom_headers: Headers) -> None:
390
+ if headers.get("Authorization") or custom_headers.get("Authorization") or isinstance(custom_headers.get("Authorization"), Omit):
391
+ return
358
392
  if self.api_key and headers.get("x-goog-api-key"):
359
393
  return
360
- if isinstance(custom_headers.get("x-goog-api-key"), Omit):
394
+ if custom_headers.get("x-goog-api-key") or isinstance(custom_headers.get("x-goog-api-key"), Omit):
361
395
  return
362
396
 
363
397
  raise TypeError(
364
398
  '"Could not resolve authentication method. Expected the api_key to be set. Or for the `x-goog-api-key` headers to be explicitly omitted"'
365
399
  )
400
+
401
+ @override
402
+ async def _prepare_options(self, options: FinalRequestOptions) -> FinalRequestOptions:
403
+ if not self.client_adapter or not self.client_adapter.is_vertex_ai():
404
+ return options
405
+
406
+ headers = options.headers or {}
407
+ has_auth = headers.get("Authorization") or headers.get("x-goog-api-key") # pytype: disable=attribute-error
408
+ if has_auth:
409
+ return options
410
+
411
+ adapted_headers = await self.client_adapter.async_get_auth_headers()
412
+ if adapted_headers:
413
+ options.headers = {
414
+ **adapted_headers,
415
+ **headers
416
+ }
417
+ return options
366
418
 
367
419
  def copy(
368
420
  self,
@@ -377,6 +429,7 @@ class AsyncGeminiNextGenAPIClient(AsyncAPIClient):
377
429
  set_default_headers: Mapping[str, str] | None = None,
378
430
  default_query: Mapping[str, object] | None = None,
379
431
  set_default_query: Mapping[str, object] | None = None,
432
+ client_adapter: AsyncGeminiNextGenAPIClientAdapter | None = None,
380
433
  _extra_kwargs: Mapping[str, Any] = {},
381
434
  ) -> Self:
382
435
  """
@@ -410,6 +463,7 @@ class AsyncGeminiNextGenAPIClient(AsyncAPIClient):
410
463
  max_retries=max_retries if is_given(max_retries) else self.max_retries,
411
464
  default_headers=headers,
412
465
  default_query=params,
466
+ client_adapter=self.client_adapter or client_adapter,
413
467
  **_extra_kwargs,
414
468
  )
415
469
 
@@ -0,0 +1,48 @@
1
+ # Copyright 2025 Google LLC
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License");
4
+ # you may not use this file except in compliance with the License.
5
+ # You may obtain a copy of the License at
6
+ #
7
+ # http://www.apache.org/licenses/LICENSE-2.0
8
+ #
9
+ # Unless required by applicable law or agreed to in writing, software
10
+ # distributed under the License is distributed on an "AS IS" BASIS,
11
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ # See the License for the specific language governing permissions and
13
+ # limitations under the License.
14
+ #
15
+
16
+ from __future__ import annotations
17
+
18
+ from abc import ABC, abstractmethod
19
+
20
+ __all__ = [
21
+ "GeminiNextGenAPIClientAdapter",
22
+ "AsyncGeminiNextGenAPIClientAdapter"
23
+ ]
24
+
25
+ class BaseGeminiNextGenAPIClientAdapter(ABC):
26
+ @abstractmethod
27
+ def is_vertex_ai(self) -> bool:
28
+ ...
29
+
30
+ @abstractmethod
31
+ def get_project(self) -> str | None:
32
+ ...
33
+
34
+ @abstractmethod
35
+ def get_location(self) -> str | None:
36
+ ...
37
+
38
+
39
+ class AsyncGeminiNextGenAPIClientAdapter(BaseGeminiNextGenAPIClientAdapter):
40
+ @abstractmethod
41
+ async def async_get_auth_headers(self) -> dict[str, str] | None:
42
+ ...
43
+
44
+
45
+ class GeminiNextGenAPIClientAdapter(BaseGeminiNextGenAPIClientAdapter):
46
+ @abstractmethod
47
+ def get_auth_headers(self) -> dict[str, str] | None:
48
+ ...
@@ -21,6 +21,7 @@ from .tool import Tool as Tool
21
21
  from .turn import Turn as Turn
22
22
  from .model import Model as Model
23
23
  from .usage import Usage as Usage
24
+ from .content import Content as Content
24
25
  from .function import Function as Function
25
26
  from .annotation import Annotation as Annotation
26
27
  from .tool_param import ToolParam as ToolParam
@@ -31,10 +32,12 @@ from .model_param import ModelParam as ModelParam
31
32
  from .tool_choice import ToolChoice as ToolChoice
32
33
  from .usage_param import UsageParam as UsageParam
33
34
  from .content_stop import ContentStop as ContentStop
35
+ from .image_config import ImageConfig as ImageConfig
34
36
  from .text_content import TextContent as TextContent
35
37
  from .allowed_tools import AllowedTools as AllowedTools
36
38
  from .audio_content import AudioContent as AudioContent
37
39
  from .content_delta import ContentDelta as ContentDelta
40
+ from .content_param import ContentParam as ContentParam
38
41
  from .content_start import ContentStart as ContentStart
39
42
  from .image_content import ImageContent as ImageContent
40
43
  from .speech_config import SpeechConfig as SpeechConfig
@@ -52,6 +55,7 @@ from .generation_config import GenerationConfig as GenerationConfig
52
55
  from .interaction_event import InteractionEvent as InteractionEvent
53
56
  from .tool_choice_param import ToolChoiceParam as ToolChoiceParam
54
57
  from .document_mime_type import DocumentMimeType as DocumentMimeType
58
+ from .image_config_param import ImageConfigParam as ImageConfigParam
55
59
  from .text_content_param import TextContentParam as TextContentParam
56
60
  from .tool_choice_config import ToolChoiceConfig as ToolChoiceConfig
57
61
  from .url_context_result import URLContextResult as URLContextResult
@@ -73,6 +77,7 @@ from .interaction_get_params import InteractionGetParams as InteractionGetParams
73
77
  from .function_result_content import FunctionResultContent as FunctionResultContent
74
78
  from .generation_config_param import GenerationConfigParam as GenerationConfigParam
75
79
  from .document_mime_type_param import DocumentMimeTypeParam as DocumentMimeTypeParam
80
+ from .file_search_call_content import FileSearchCallContent as FileSearchCallContent
76
81
  from .tool_choice_config_param import ToolChoiceConfigParam as ToolChoiceConfigParam
77
82
  from .url_context_call_content import URLContextCallContent as URLContextCallContent
78
83
  from .url_context_result_param import URLContextResultParam as URLContextResultParam
@@ -93,6 +98,7 @@ from .mcp_server_tool_call_content import MCPServerToolCallContent as MCPServerT
93
98
  from .code_execution_call_arguments import CodeExecutionCallArguments as CodeExecutionCallArguments
94
99
  from .code_execution_result_content import CodeExecutionResultContent as CodeExecutionResultContent
95
100
  from .function_result_content_param import FunctionResultContentParam as FunctionResultContentParam
101
+ from .file_search_call_content_param import FileSearchCallContentParam as FileSearchCallContentParam
96
102
  from .mcp_server_tool_result_content import MCPServerToolResultContent as MCPServerToolResultContent
97
103
  from .url_context_call_content_param import URLContextCallContentParam as URLContextCallContentParam
98
104
  from .deep_research_agent_config_param import DeepResearchAgentConfigParam as DeepResearchAgentConfigParam
@@ -30,8 +30,10 @@ class AudioContent(BaseModel):
30
30
  type: Literal["audio"]
31
31
 
32
32
  data: Optional[str] = None
33
+ """The audio content."""
33
34
 
34
35
  mime_type: Optional[AudioMimeType] = None
35
36
  """The mime type of the audio."""
36
37
 
37
38
  uri: Optional[str] = None
39
+ """The URI of the audio."""
@@ -34,11 +34,13 @@ class AudioContentParam(TypedDict, total=False):
34
34
  type: Required[Literal["audio"]]
35
35
 
36
36
  data: Annotated[Union[str, Base64FileInput], PropertyInfo(format="base64")]
37
+ """The audio content."""
37
38
 
38
39
  mime_type: AudioMimeTypeParam
39
40
  """The mime type of the audio."""
40
41
 
41
42
  uri: str
43
+ """The URI of the audio."""
42
44
 
43
45
 
44
46
  set_pydantic_config(AudioContentParam, {"arbitrary_types_allowed": True})
@@ -0,0 +1,65 @@
1
+ # Copyright 2025 Google LLC
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License");
4
+ # you may not use this file except in compliance with the License.
5
+ # You may obtain a copy of the License at
6
+ #
7
+ # http://www.apache.org/licenses/LICENSE-2.0
8
+ #
9
+ # Unless required by applicable law or agreed to in writing, software
10
+ # distributed under the License is distributed on an "AS IS" BASIS,
11
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ # See the License for the specific language governing permissions and
13
+ # limitations under the License.
14
+ #
15
+
16
+ # File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
17
+
18
+ from typing import Union
19
+ from typing_extensions import Annotated, TypeAlias
20
+
21
+ from .._utils import PropertyInfo
22
+ from .text_content import TextContent
23
+ from .audio_content import AudioContent
24
+ from .image_content import ImageContent
25
+ from .video_content import VideoContent
26
+ from .thought_content import ThoughtContent
27
+ from .document_content import DocumentContent
28
+ from .function_call_content import FunctionCallContent
29
+ from .function_result_content import FunctionResultContent
30
+ from .file_search_call_content import FileSearchCallContent
31
+ from .url_context_call_content import URLContextCallContent
32
+ from .file_search_result_content import FileSearchResultContent
33
+ from .google_search_call_content import GoogleSearchCallContent
34
+ from .url_context_result_content import URLContextResultContent
35
+ from .code_execution_call_content import CodeExecutionCallContent
36
+ from .google_search_result_content import GoogleSearchResultContent
37
+ from .mcp_server_tool_call_content import MCPServerToolCallContent
38
+ from .code_execution_result_content import CodeExecutionResultContent
39
+ from .mcp_server_tool_result_content import MCPServerToolResultContent
40
+
41
+ __all__ = ["Content"]
42
+
43
+ Content: TypeAlias = Annotated[
44
+ Union[
45
+ TextContent,
46
+ ImageContent,
47
+ AudioContent,
48
+ DocumentContent,
49
+ VideoContent,
50
+ ThoughtContent,
51
+ FunctionCallContent,
52
+ FunctionResultContent,
53
+ CodeExecutionCallContent,
54
+ CodeExecutionResultContent,
55
+ URLContextCallContent,
56
+ URLContextResultContent,
57
+ GoogleSearchCallContent,
58
+ GoogleSearchResultContent,
59
+ MCPServerToolCallContent,
60
+ MCPServerToolResultContent,
61
+ FileSearchCallContent,
62
+ FileSearchResultContent,
63
+ ],
64
+ PropertyInfo(discriminator="type"),
65
+ ]
@@ -60,6 +60,7 @@ __all__ = [
60
60
  "DeltaMCPServerToolResultDeltaResult",
61
61
  "DeltaMCPServerToolResultDeltaResultItems",
62
62
  "DeltaMCPServerToolResultDeltaResultItemsItem",
63
+ "DeltaFileSearchCallDelta",
63
64
  "DeltaFileSearchResultDelta",
64
65
  "DeltaFileSearchResultDeltaResult",
65
66
  ]
@@ -284,6 +285,13 @@ class DeltaMCPServerToolResultDelta(BaseModel):
284
285
  server_name: Optional[str] = None
285
286
 
286
287
 
288
+ class DeltaFileSearchCallDelta(BaseModel):
289
+ type: Literal["file_search_call"]
290
+
291
+ id: Optional[str] = None
292
+ """A unique ID for this specific tool call."""
293
+
294
+
287
295
  class DeltaFileSearchResultDeltaResult(BaseModel):
288
296
  """The result of the File Search."""
289
297
 
@@ -322,6 +330,7 @@ Delta: TypeAlias = Annotated[
322
330
  DeltaGoogleSearchResultDelta,
323
331
  DeltaMCPServerToolCallDelta,
324
332
  DeltaMCPServerToolResultDelta,
333
+ DeltaFileSearchCallDelta,
325
334
  DeltaFileSearchResultDelta,
326
335
  ],
327
336
  PropertyInfo(discriminator="type"),
@@ -333,8 +342,7 @@ class ContentDelta(BaseModel):
333
342
 
334
343
  event_id: Optional[str] = None
335
344
  """
336
- The event_id token to be used to resume the interaction stream, from
337
- this event.
345
+ The event_id token to be used to resume the interaction stream, from this event.
338
346
  """
339
347
 
340
348
  event_type: Optional[Literal["content.delta"]] = None
@@ -0,0 +1,63 @@
1
+ # Copyright 2025 Google LLC
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License");
4
+ # you may not use this file except in compliance with the License.
5
+ # You may obtain a copy of the License at
6
+ #
7
+ # http://www.apache.org/licenses/LICENSE-2.0
8
+ #
9
+ # Unless required by applicable law or agreed to in writing, software
10
+ # distributed under the License is distributed on an "AS IS" BASIS,
11
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ # See the License for the specific language governing permissions and
13
+ # limitations under the License.
14
+ #
15
+
16
+ # File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
17
+
18
+ from __future__ import annotations
19
+
20
+ from typing import Union
21
+ from typing_extensions import TypeAlias
22
+
23
+ from .text_content_param import TextContentParam
24
+ from .audio_content_param import AudioContentParam
25
+ from .image_content_param import ImageContentParam
26
+ from .video_content_param import VideoContentParam
27
+ from .thought_content_param import ThoughtContentParam
28
+ from .document_content_param import DocumentContentParam
29
+ from .function_call_content_param import FunctionCallContentParam
30
+ from .function_result_content_param import FunctionResultContentParam
31
+ from .file_search_call_content_param import FileSearchCallContentParam
32
+ from .url_context_call_content_param import URLContextCallContentParam
33
+ from .file_search_result_content_param import FileSearchResultContentParam
34
+ from .google_search_call_content_param import GoogleSearchCallContentParam
35
+ from .url_context_result_content_param import URLContextResultContentParam
36
+ from .code_execution_call_content_param import CodeExecutionCallContentParam
37
+ from .google_search_result_content_param import GoogleSearchResultContentParam
38
+ from .mcp_server_tool_call_content_param import MCPServerToolCallContentParam
39
+ from .code_execution_result_content_param import CodeExecutionResultContentParam
40
+ from .mcp_server_tool_result_content_param import MCPServerToolResultContentParam
41
+
42
+ __all__ = ["ContentParam"]
43
+
44
+ ContentParam: TypeAlias = Union[
45
+ TextContentParam,
46
+ ImageContentParam,
47
+ AudioContentParam,
48
+ DocumentContentParam,
49
+ VideoContentParam,
50
+ ThoughtContentParam,
51
+ FunctionCallContentParam,
52
+ FunctionResultContentParam,
53
+ CodeExecutionCallContentParam,
54
+ CodeExecutionResultContentParam,
55
+ URLContextCallContentParam,
56
+ URLContextResultContentParam,
57
+ GoogleSearchCallContentParam,
58
+ GoogleSearchResultContentParam,
59
+ MCPServerToolCallContentParam,
60
+ MCPServerToolResultContentParam,
61
+ FileSearchCallContentParam,
62
+ FileSearchResultContentParam,
63
+ ]
@@ -15,53 +15,13 @@
15
15
 
16
16
  # File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
17
17
 
18
- from typing import Union, Optional
19
- from typing_extensions import Literal, Annotated, TypeAlias
18
+ from typing import Optional
19
+ from typing_extensions import Literal
20
20
 
21
- from .._utils import PropertyInfo
21
+ from .content import Content
22
22
  from .._models import BaseModel
23
- from .text_content import TextContent
24
- from .audio_content import AudioContent
25
- from .image_content import ImageContent
26
- from .video_content import VideoContent
27
- from .thought_content import ThoughtContent
28
- from .document_content import DocumentContent
29
- from .function_call_content import FunctionCallContent
30
- from .function_result_content import FunctionResultContent
31
- from .url_context_call_content import URLContextCallContent
32
- from .file_search_result_content import FileSearchResultContent
33
- from .google_search_call_content import GoogleSearchCallContent
34
- from .url_context_result_content import URLContextResultContent
35
- from .code_execution_call_content import CodeExecutionCallContent
36
- from .google_search_result_content import GoogleSearchResultContent
37
- from .mcp_server_tool_call_content import MCPServerToolCallContent
38
- from .code_execution_result_content import CodeExecutionResultContent
39
- from .mcp_server_tool_result_content import MCPServerToolResultContent
40
23
 
41
- __all__ = ["ContentStart", "Content"]
42
-
43
- Content: TypeAlias = Annotated[
44
- Union[
45
- TextContent,
46
- ImageContent,
47
- AudioContent,
48
- DocumentContent,
49
- VideoContent,
50
- ThoughtContent,
51
- FunctionCallContent,
52
- FunctionResultContent,
53
- CodeExecutionCallContent,
54
- CodeExecutionResultContent,
55
- URLContextCallContent,
56
- URLContextResultContent,
57
- GoogleSearchCallContent,
58
- GoogleSearchResultContent,
59
- MCPServerToolCallContent,
60
- MCPServerToolResultContent,
61
- FileSearchResultContent,
62
- ],
63
- PropertyInfo(discriminator="type"),
64
- ]
24
+ __all__ = ["ContentStart"]
65
25
 
66
26
 
67
27
  class ContentStart(BaseModel):
@@ -70,8 +30,7 @@ class ContentStart(BaseModel):
70
30
 
71
31
  event_id: Optional[str] = None
72
32
  """
73
- The event_id token to be used to resume the interaction stream, from
74
- this event.
33
+ The event_id token to be used to resume the interaction stream, from this event.
75
34
  """
76
35
 
77
36
  event_type: Optional[Literal["content.start"]] = None
@@ -26,8 +26,7 @@ __all__ = ["ContentStop"]
26
26
  class ContentStop(BaseModel):
27
27
  event_id: Optional[str] = None
28
28
  """
29
- The event_id token to be used to resume the interaction stream, from
30
- this event.
29
+ The event_id token to be used to resume the interaction stream, from this event.
31
30
  """
32
31
 
33
32
  event_type: Optional[Literal["content.stop"]] = None