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
google/genai/client.py CHANGED
@@ -16,7 +16,7 @@
16
16
  import asyncio
17
17
  import os
18
18
  from types import TracebackType
19
- from typing import Optional, Union, cast
19
+ from typing import Optional, Union
20
20
 
21
21
  import google.auth
22
22
  import pydantic
@@ -43,13 +43,65 @@ from ._api_client import has_aiohttp
43
43
 
44
44
  from . import _common
45
45
 
46
- from ._interactions import AsyncGeminiNextGenAPIClient, DEFAULT_MAX_RETRIES, DefaultAioHttpClient, GeminiNextGenAPIClient
47
- from ._interactions._models import FinalRequestOptions
48
- from ._interactions._types import Headers
49
- from ._interactions._utils import is_given
46
+ from ._interactions import AsyncGeminiNextGenAPIClient, DEFAULT_MAX_RETRIES, GeminiNextGenAPIClient
47
+ from . import _interactions
48
+
50
49
  from ._interactions.resources import AsyncInteractionsResource as AsyncNextGenInteractionsResource, InteractionsResource as NextGenInteractionsResource
51
50
  _interactions_experimental_warned = False
52
51
 
52
+ class AsyncGeminiNextGenAPIClientAdapter(_interactions.AsyncGeminiNextGenAPIClientAdapter):
53
+ """Adapter for the Gemini NextGen API Client."""
54
+ def __init__(self, api_client: BaseApiClient):
55
+ self._api_client = api_client
56
+
57
+ def is_vertex_ai(self) -> bool:
58
+ return self._api_client.vertexai or False
59
+
60
+ def get_project(self) -> str | None:
61
+ return self._api_client.project
62
+
63
+ def get_location(self) -> str | None:
64
+ return self._api_client.location
65
+
66
+ async def async_get_auth_headers(self) -> dict[str, str]:
67
+ if self._api_client.api_key:
68
+ return {"x-goog-api-key": self._api_client.api_key}
69
+ access_token = await self._api_client._async_access_token()
70
+ headers = {
71
+ "Authorization": f"Bearer {access_token}",
72
+ }
73
+ if creds := self._api_client._credentials:
74
+ if creds.quota_project_id:
75
+ headers["x-goog-user-project"] = creds.quota_project_id
76
+ return headers
77
+
78
+
79
+ class GeminiNextGenAPIClientAdapter(_interactions.GeminiNextGenAPIClientAdapter):
80
+ """Adapter for the Gemini NextGen API Client."""
81
+ def __init__(self, api_client: BaseApiClient):
82
+ self._api_client = api_client
83
+
84
+ def is_vertex_ai(self) -> bool:
85
+ return self._api_client.vertexai or False
86
+
87
+ def get_project(self) -> str | None:
88
+ return self._api_client.project
89
+
90
+ def get_location(self) -> str | None:
91
+ return self._api_client.location
92
+
93
+ def get_auth_headers(self) -> dict[str, str]:
94
+ if self._api_client.api_key:
95
+ return {"x-goog-api-key": self._api_client.api_key}
96
+ access_token = self._api_client._access_token()
97
+ headers = {
98
+ "Authorization": f"Bearer {access_token}",
99
+ }
100
+ if creds := self._api_client._credentials:
101
+ if creds.quota_project_id:
102
+ headers["x-goog-user-project"] = creds.quota_project_id
103
+ return headers
104
+
53
105
 
54
106
  class AsyncClient:
55
107
  """Client for making asynchronous (non-blocking) requests."""
@@ -122,6 +174,7 @@ class AsyncClient:
122
174
  # uSDk expects ms, nextgen uses a httpx Timeout -> expects seconds.
123
175
  timeout=http_opts.timeout / 1000 if http_opts.timeout else None,
124
176
  max_retries=max_retries,
177
+ client_adapter=AsyncGeminiNextGenAPIClientAdapter(self._api_client)
125
178
  )
126
179
 
127
180
  client = self._nextgen_client_instance
@@ -130,30 +183,6 @@ class AsyncClient:
130
183
  client._vertex_project = self._api_client.project
131
184
  client._vertex_location = self._api_client.location
132
185
 
133
- async def prepare_options(options: FinalRequestOptions) -> FinalRequestOptions:
134
- headers = {}
135
- if is_given(options.headers):
136
- headers = {**options.headers}
137
-
138
- headers['Authorization'] = f'Bearer {await self._api_client._async_access_token()}'
139
- if (
140
- self._api_client._credentials
141
- and self._api_client._credentials.quota_project_id
142
- ):
143
- headers['x-goog-user-project'] = (
144
- self._api_client._credentials.quota_project_id
145
- )
146
- options.headers = headers
147
-
148
- return options
149
-
150
- if self._api_client.project or self._api_client.location:
151
- client._prepare_options = prepare_options # type: ignore[method-assign]
152
-
153
- def validate_headers(headers: Headers, custom_headers: Headers) -> None:
154
- return
155
-
156
- client._validate_headers = validate_headers # type: ignore[method-assign]
157
186
  return self._nextgen_client_instance
158
187
 
159
188
  @property
@@ -279,6 +308,7 @@ class DebugConfig(pydantic.BaseModel):
279
308
  )
280
309
 
281
310
 
311
+
282
312
  class Client:
283
313
  """Client for making synchronous requests.
284
314
 
@@ -492,39 +522,15 @@ class Client:
492
522
  # uSDk expects ms, nextgen uses a httpx Timeout -> expects seconds.
493
523
  timeout=http_opts.timeout / 1000 if http_opts.timeout else None,
494
524
  max_retries=max_retries,
525
+ client_adapter=GeminiNextGenAPIClientAdapter(self._api_client),
495
526
  )
496
527
 
497
528
  client = self._nextgen_client_instance
498
- if self.vertexai:
529
+ if self._api_client.vertexai:
499
530
  client._is_vertex = True
500
531
  client._vertex_project = self._api_client.project
501
532
  client._vertex_location = self._api_client.location
502
533
 
503
- def prepare_options(options: FinalRequestOptions) -> FinalRequestOptions:
504
- headers = {}
505
- if is_given(options.headers):
506
- headers = {**options.headers}
507
- options.headers = headers
508
-
509
- headers['Authorization'] = f'Bearer {self._api_client._access_token()}'
510
- if (
511
- self._api_client._credentials
512
- and self._api_client._credentials.quota_project_id
513
- ):
514
- headers['x-goog-user-project'] = (
515
- self._api_client._credentials.quota_project_id
516
- )
517
-
518
- return options
519
-
520
- if self._api_client.project or self._api_client.location:
521
- client._prepare_options = prepare_options # type: ignore[method-assign]
522
-
523
- def validate_headers(headers: Headers, custom_headers: Headers) -> None:
524
- return
525
-
526
- client._validate_headers = validate_headers # type: ignore[method-assign]
527
-
528
534
  return self._nextgen_client_instance
529
535
 
530
536
  @property
google/genai/files.py CHANGED
@@ -22,6 +22,9 @@ import os
22
22
  from typing import Any, Optional, Union
23
23
  from urllib.parse import urlencode
24
24
 
25
+ import google.auth
26
+
27
+ from . import _api_client
25
28
  from . import _api_module
26
29
  from . import _common
27
30
  from . import _extra_utils
@@ -149,6 +152,33 @@ def _ListFilesResponse_from_mldev(
149
152
  return to_object
150
153
 
151
154
 
155
+ def _RegisterFilesParameters_to_mldev(
156
+ from_object: Union[dict[str, Any], object],
157
+ parent_object: Optional[dict[str, Any]] = None,
158
+ ) -> dict[str, Any]:
159
+ to_object: dict[str, Any] = {}
160
+ if getv(from_object, ['uris']) is not None:
161
+ setv(to_object, ['uris'], getv(from_object, ['uris']))
162
+
163
+ return to_object
164
+
165
+
166
+ def _RegisterFilesResponse_from_mldev(
167
+ from_object: Union[dict[str, Any], object],
168
+ parent_object: Optional[dict[str, Any]] = None,
169
+ ) -> dict[str, Any]:
170
+ to_object: dict[str, Any] = {}
171
+ if getv(from_object, ['sdkHttpResponse']) is not None:
172
+ setv(
173
+ to_object, ['sdk_http_response'], getv(from_object, ['sdkHttpResponse'])
174
+ )
175
+
176
+ if getv(from_object, ['files']) is not None:
177
+ setv(to_object, ['files'], [item for item in getv(from_object, ['files'])])
178
+
179
+ return to_object
180
+
181
+
152
182
  class Files(_api_module.BaseModule):
153
183
 
154
184
  def _list(
@@ -402,6 +432,69 @@ class Files(_api_module.BaseModule):
402
432
  self._api_client._verify_response(return_value)
403
433
  return return_value
404
434
 
435
+ def _register_files(
436
+ self,
437
+ *,
438
+ uris: list[str],
439
+ config: Optional[types.RegisterFilesConfigOrDict] = None,
440
+ ) -> types.RegisterFilesResponse:
441
+ parameter_model = types._RegisterFilesParameters(
442
+ uris=uris,
443
+ config=config,
444
+ )
445
+
446
+ request_url_dict: Optional[dict[str, str]]
447
+ if self._api_client.vertexai:
448
+ raise ValueError(
449
+ 'This method is only supported in the Gemini Developer client.'
450
+ )
451
+ else:
452
+ request_dict = _RegisterFilesParameters_to_mldev(parameter_model)
453
+ request_url_dict = request_dict.get('_url')
454
+ if request_url_dict:
455
+ path = 'files:register'.format_map(request_url_dict)
456
+ else:
457
+ path = 'files:register'
458
+
459
+ query_params = request_dict.get('_query')
460
+ if query_params:
461
+ path = f'{path}?{urlencode(query_params)}'
462
+ # TODO: remove the hack that pops config.
463
+ request_dict.pop('config', None)
464
+
465
+ http_options: Optional[types.HttpOptions] = None
466
+ if (
467
+ parameter_model.config is not None
468
+ and parameter_model.config.http_options is not None
469
+ ):
470
+ http_options = parameter_model.config.http_options
471
+
472
+ request_dict = _common.convert_to_dict(request_dict)
473
+ request_dict = _common.encode_unserializable_types(request_dict)
474
+
475
+ response = self._api_client.request(
476
+ 'post', path, request_dict, http_options
477
+ )
478
+
479
+ if config is not None and getattr(
480
+ config, 'should_return_http_response', None
481
+ ):
482
+ return_value = types.RegisterFilesResponse(sdk_http_response=response)
483
+ self._api_client._verify_response(return_value)
484
+ return return_value
485
+
486
+ response_dict = {} if not response.body else json.loads(response.body)
487
+
488
+ if not self._api_client.vertexai:
489
+ response_dict = _RegisterFilesResponse_from_mldev(response_dict)
490
+
491
+ return_value = types.RegisterFilesResponse._from_response(
492
+ response=response_dict, kwargs=parameter_model.model_dump()
493
+ )
494
+
495
+ self._api_client._verify_response(return_value)
496
+ return return_value
497
+
405
498
  def upload(
406
499
  self,
407
500
  *,
@@ -559,6 +652,39 @@ class Files(_api_module.BaseModule):
559
652
 
560
653
  return data
561
654
 
655
+ def register_files(
656
+ self,
657
+ *,
658
+ auth: google.auth.credentials.Credentials,
659
+ uris: list[str],
660
+ config: Optional[types.RegisterFilesConfigOrDict] = None,
661
+ ) -> types.RegisterFilesResponse:
662
+ """Registers gcs files with the file service."""
663
+ if not isinstance(auth, google.auth.credentials.Credentials):
664
+ raise ValueError(
665
+ 'auth must be a google.auth.credentials.Credentials object.'
666
+ )
667
+ if config is None:
668
+ config = types.RegisterFilesConfig()
669
+ else:
670
+ config = types.RegisterFilesConfig.model_validate(config)
671
+ config = config.model_copy(deep=True)
672
+
673
+ http_options = config.http_options or types.HttpOptions()
674
+ headers = http_options.headers or {}
675
+ headers = {k.lower(): v for k, v in headers.items()}
676
+
677
+ token = _api_client.get_token_from_credentials(self._api_client, auth)
678
+ headers['authorization'] = f'Bearer {token}'
679
+
680
+ if auth.quota_project_id:
681
+ headers['x-goog-user-project'] = auth.quota_project_id
682
+
683
+ http_options.headers = headers
684
+ config.http_options = http_options
685
+
686
+ return self._register_files(uris=uris, config=config)
687
+
562
688
  def list(
563
689
  self, *, config: Optional[types.ListFilesConfigOrDict] = None
564
690
  ) -> Pager[types.File]:
@@ -845,6 +971,69 @@ class AsyncFiles(_api_module.BaseModule):
845
971
  self._api_client._verify_response(return_value)
846
972
  return return_value
847
973
 
974
+ async def _register_files(
975
+ self,
976
+ *,
977
+ uris: list[str],
978
+ config: Optional[types.RegisterFilesConfigOrDict] = None,
979
+ ) -> types.RegisterFilesResponse:
980
+ parameter_model = types._RegisterFilesParameters(
981
+ uris=uris,
982
+ config=config,
983
+ )
984
+
985
+ request_url_dict: Optional[dict[str, str]]
986
+ if self._api_client.vertexai:
987
+ raise ValueError(
988
+ 'This method is only supported in the Gemini Developer client.'
989
+ )
990
+ else:
991
+ request_dict = _RegisterFilesParameters_to_mldev(parameter_model)
992
+ request_url_dict = request_dict.get('_url')
993
+ if request_url_dict:
994
+ path = 'files:register'.format_map(request_url_dict)
995
+ else:
996
+ path = 'files:register'
997
+
998
+ query_params = request_dict.get('_query')
999
+ if query_params:
1000
+ path = f'{path}?{urlencode(query_params)}'
1001
+ # TODO: remove the hack that pops config.
1002
+ request_dict.pop('config', None)
1003
+
1004
+ http_options: Optional[types.HttpOptions] = None
1005
+ if (
1006
+ parameter_model.config is not None
1007
+ and parameter_model.config.http_options is not None
1008
+ ):
1009
+ http_options = parameter_model.config.http_options
1010
+
1011
+ request_dict = _common.convert_to_dict(request_dict)
1012
+ request_dict = _common.encode_unserializable_types(request_dict)
1013
+
1014
+ response = await self._api_client.async_request(
1015
+ 'post', path, request_dict, http_options
1016
+ )
1017
+
1018
+ if config is not None and getattr(
1019
+ config, 'should_return_http_response', None
1020
+ ):
1021
+ return_value = types.RegisterFilesResponse(sdk_http_response=response)
1022
+ self._api_client._verify_response(return_value)
1023
+ return return_value
1024
+
1025
+ response_dict = {} if not response.body else json.loads(response.body)
1026
+
1027
+ if not self._api_client.vertexai:
1028
+ response_dict = _RegisterFilesResponse_from_mldev(response_dict)
1029
+
1030
+ return_value = types.RegisterFilesResponse._from_response(
1031
+ response=response_dict, kwargs=parameter_model.model_dump()
1032
+ )
1033
+
1034
+ self._api_client._verify_response(return_value)
1035
+ return return_value
1036
+
848
1037
  async def upload(
849
1038
  self,
850
1039
  *,
@@ -992,6 +1181,41 @@ class AsyncFiles(_api_module.BaseModule):
992
1181
 
993
1182
  return data
994
1183
 
1184
+ async def register_files(
1185
+ self,
1186
+ *,
1187
+ auth: google.auth.credentials.Credentials,
1188
+ uris: list[str],
1189
+ config: Optional[types.RegisterFilesConfigOrDict] = None,
1190
+ ) -> types.RegisterFilesResponse:
1191
+ """Registers gcs files with the file service."""
1192
+ if not isinstance(auth, google.auth.credentials.Credentials):
1193
+ raise ValueError(
1194
+ 'auth must be a google.auth.credentials.Credentials object.'
1195
+ )
1196
+ if config is None:
1197
+ config = types.RegisterFilesConfig()
1198
+ else:
1199
+ config = types.RegisterFilesConfig.model_validate(config)
1200
+ config = config.model_copy(deep=True)
1201
+
1202
+ http_options = config.http_options or types.HttpOptions()
1203
+ headers = http_options.headers or {}
1204
+ headers = {k.lower(): v for k, v in headers.items()}
1205
+
1206
+ token = await _api_client.async_get_token_from_credentials(
1207
+ self._api_client, auth
1208
+ )
1209
+ headers['authorization'] = f'Bearer {token}'
1210
+
1211
+ if auth.quota_project_id:
1212
+ headers['x-goog-user-project'] = auth.quota_project_id
1213
+
1214
+ http_options.headers = headers
1215
+ config.http_options = http_options
1216
+
1217
+ return await self._register_files(uris=uris, config=config)
1218
+
995
1219
  async def list(
996
1220
  self, *, config: Optional[types.ListFilesConfigOrDict] = None
997
1221
  ) -> AsyncPager[types.File]:
google/genai/live.py CHANGED
@@ -1036,7 +1036,7 @@ class AsyncLive(_api_module.BaseModule):
1036
1036
  if requests is None:
1037
1037
  raise ValueError('The requests module is required to refresh google-auth credentials. Please install with `pip install google-auth[requests]`')
1038
1038
  auth_req = requests.Request() # type: ignore
1039
- creds.refresh(auth_req)
1039
+ creds.refresh(auth_req) # type: ignore[no-untyped-call]
1040
1040
  bearer_token = creds.token
1041
1041
 
1042
1042
  original_headers = self._api_client._http_options.headers
google/genai/models.py CHANGED
@@ -891,9 +891,6 @@ def _FunctionCallingConfig_to_mldev(
891
891
  parent_object: Optional[dict[str, Any]] = None,
892
892
  ) -> dict[str, Any]:
893
893
  to_object: dict[str, Any] = {}
894
- if getv(from_object, ['mode']) is not None:
895
- setv(to_object, ['mode'], getv(from_object, ['mode']))
896
-
897
894
  if getv(from_object, ['allowed_function_names']) is not None:
898
895
  setv(
899
896
  to_object,
@@ -901,6 +898,9 @@ def _FunctionCallingConfig_to_mldev(
901
898
  getv(from_object, ['allowed_function_names']),
902
899
  )
903
900
 
901
+ if getv(from_object, ['mode']) is not None:
902
+ setv(to_object, ['mode'], getv(from_object, ['mode']))
903
+
904
904
  if getv(from_object, ['stream_function_call_arguments']) is not None:
905
905
  raise ValueError(
906
906
  'stream_function_call_arguments parameter is not supported in Gemini'
@@ -915,9 +915,6 @@ def _FunctionDeclaration_to_vertex(
915
915
  parent_object: Optional[dict[str, Any]] = None,
916
916
  ) -> dict[str, Any]:
917
917
  to_object: dict[str, Any] = {}
918
- if getv(from_object, ['behavior']) is not None:
919
- raise ValueError('behavior parameter is not supported in Vertex AI.')
920
-
921
918
  if getv(from_object, ['description']) is not None:
922
919
  setv(to_object, ['description'], getv(from_object, ['description']))
923
920
 
@@ -944,6 +941,9 @@ def _FunctionDeclaration_to_vertex(
944
941
  getv(from_object, ['response_json_schema']),
945
942
  )
946
943
 
944
+ if getv(from_object, ['behavior']) is not None:
945
+ raise ValueError('behavior parameter is not supported in Vertex AI.')
946
+
947
947
  return to_object
948
948
 
949
949
 
@@ -2549,6 +2549,11 @@ def _ImageConfig_to_mldev(
2549
2549
  if getv(from_object, ['image_size']) is not None:
2550
2550
  setv(to_object, ['imageSize'], getv(from_object, ['image_size']))
2551
2551
 
2552
+ if getv(from_object, ['person_generation']) is not None:
2553
+ raise ValueError(
2554
+ 'person_generation parameter is not supported in Gemini API.'
2555
+ )
2556
+
2552
2557
  if getv(from_object, ['output_mime_type']) is not None:
2553
2558
  raise ValueError(
2554
2559
  'output_mime_type parameter is not supported in Gemini API.'
@@ -2573,6 +2578,13 @@ def _ImageConfig_to_vertex(
2573
2578
  if getv(from_object, ['image_size']) is not None:
2574
2579
  setv(to_object, ['imageSize'], getv(from_object, ['image_size']))
2575
2580
 
2581
+ if getv(from_object, ['person_generation']) is not None:
2582
+ setv(
2583
+ to_object,
2584
+ ['personGeneration'],
2585
+ getv(from_object, ['person_generation']),
2586
+ )
2587
+
2576
2588
  if getv(from_object, ['output_mime_type']) is not None:
2577
2589
  setv(
2578
2590
  to_object,
@@ -3424,6 +3436,11 @@ def _ToolConfig_to_mldev(
3424
3436
  parent_object: Optional[dict[str, Any]] = None,
3425
3437
  ) -> dict[str, Any]:
3426
3438
  to_object: dict[str, Any] = {}
3439
+ if getv(from_object, ['retrieval_config']) is not None:
3440
+ setv(
3441
+ to_object, ['retrievalConfig'], getv(from_object, ['retrieval_config'])
3442
+ )
3443
+
3427
3444
  if getv(from_object, ['function_calling_config']) is not None:
3428
3445
  setv(
3429
3446
  to_object,
@@ -3433,11 +3450,6 @@ def _ToolConfig_to_mldev(
3433
3450
  ),
3434
3451
  )
3435
3452
 
3436
- if getv(from_object, ['retrieval_config']) is not None:
3437
- setv(
3438
- to_object, ['retrievalConfig'], getv(from_object, ['retrieval_config'])
3439
- )
3440
-
3441
3453
  return to_object
3442
3454
 
3443
3455
 
@@ -3446,23 +3458,9 @@ def _Tool_to_mldev(
3446
3458
  parent_object: Optional[dict[str, Any]] = None,
3447
3459
  ) -> dict[str, Any]:
3448
3460
  to_object: dict[str, Any] = {}
3449
- if getv(from_object, ['function_declarations']) is not None:
3450
- setv(
3451
- to_object,
3452
- ['functionDeclarations'],
3453
- [item for item in getv(from_object, ['function_declarations'])],
3454
- )
3455
-
3456
3461
  if getv(from_object, ['retrieval']) is not None:
3457
3462
  raise ValueError('retrieval parameter is not supported in Gemini API.')
3458
3463
 
3459
- if getv(from_object, ['google_search_retrieval']) is not None:
3460
- setv(
3461
- to_object,
3462
- ['googleSearchRetrieval'],
3463
- getv(from_object, ['google_search_retrieval']),
3464
- )
3465
-
3466
3464
  if getv(from_object, ['computer_use']) is not None:
3467
3465
  setv(to_object, ['computerUse'], getv(from_object, ['computer_use']))
3468
3466
 
@@ -3477,6 +3475,13 @@ def _Tool_to_mldev(
3477
3475
  'enterprise_web_search parameter is not supported in Gemini API.'
3478
3476
  )
3479
3477
 
3478
+ if getv(from_object, ['function_declarations']) is not None:
3479
+ setv(
3480
+ to_object,
3481
+ ['functionDeclarations'],
3482
+ [item for item in getv(from_object, ['function_declarations'])],
3483
+ )
3484
+
3480
3485
  if getv(from_object, ['google_maps']) is not None:
3481
3486
  setv(
3482
3487
  to_object,
@@ -3491,6 +3496,13 @@ def _Tool_to_mldev(
3491
3496
  _GoogleSearch_to_mldev(getv(from_object, ['google_search']), to_object),
3492
3497
  )
3493
3498
 
3499
+ if getv(from_object, ['google_search_retrieval']) is not None:
3500
+ setv(
3501
+ to_object,
3502
+ ['googleSearchRetrieval'],
3503
+ getv(from_object, ['google_search_retrieval']),
3504
+ )
3505
+
3494
3506
  if getv(from_object, ['url_context']) is not None:
3495
3507
  setv(to_object, ['urlContext'], getv(from_object, ['url_context']))
3496
3508
 
@@ -3502,26 +3514,9 @@ def _Tool_to_vertex(
3502
3514
  parent_object: Optional[dict[str, Any]] = None,
3503
3515
  ) -> dict[str, Any]:
3504
3516
  to_object: dict[str, Any] = {}
3505
- if getv(from_object, ['function_declarations']) is not None:
3506
- setv(
3507
- to_object,
3508
- ['functionDeclarations'],
3509
- [
3510
- _FunctionDeclaration_to_vertex(item, to_object)
3511
- for item in getv(from_object, ['function_declarations'])
3512
- ],
3513
- )
3514
-
3515
3517
  if getv(from_object, ['retrieval']) is not None:
3516
3518
  setv(to_object, ['retrieval'], getv(from_object, ['retrieval']))
3517
3519
 
3518
- if getv(from_object, ['google_search_retrieval']) is not None:
3519
- setv(
3520
- to_object,
3521
- ['googleSearchRetrieval'],
3522
- getv(from_object, ['google_search_retrieval']),
3523
- )
3524
-
3525
3520
  if getv(from_object, ['computer_use']) is not None:
3526
3521
  setv(to_object, ['computerUse'], getv(from_object, ['computer_use']))
3527
3522
 
@@ -3538,12 +3533,29 @@ def _Tool_to_vertex(
3538
3533
  getv(from_object, ['enterprise_web_search']),
3539
3534
  )
3540
3535
 
3536
+ if getv(from_object, ['function_declarations']) is not None:
3537
+ setv(
3538
+ to_object,
3539
+ ['functionDeclarations'],
3540
+ [
3541
+ _FunctionDeclaration_to_vertex(item, to_object)
3542
+ for item in getv(from_object, ['function_declarations'])
3543
+ ],
3544
+ )
3545
+
3541
3546
  if getv(from_object, ['google_maps']) is not None:
3542
3547
  setv(to_object, ['googleMaps'], getv(from_object, ['google_maps']))
3543
3548
 
3544
3549
  if getv(from_object, ['google_search']) is not None:
3545
3550
  setv(to_object, ['googleSearch'], getv(from_object, ['google_search']))
3546
3551
 
3552
+ if getv(from_object, ['google_search_retrieval']) is not None:
3553
+ setv(
3554
+ to_object,
3555
+ ['googleSearchRetrieval'],
3556
+ getv(from_object, ['google_search_retrieval']),
3557
+ )
3558
+
3547
3559
  if getv(from_object, ['url_context']) is not None:
3548
3560
  setv(to_object, ['urlContext'], getv(from_object, ['url_context']))
3549
3561
 
@@ -4427,7 +4439,7 @@ class Models(_api_module.BaseModule):
4427
4439
  image = product_recontext_response.generated_images[0].image
4428
4440
 
4429
4441
  virtual_try_on_response = client.models.recontext_image(
4430
- model="virtual-try-on-preview-08-04",
4442
+ model="virtual-try-on-001",
4431
4443
  source=types.RecontextImageSource(
4432
4444
  person_image=types.Image.from_file(IMAGE1_FILE_PATH),
4433
4445
  product_images=[types.ProductImage.from_file(IMAGE2_FILE_PATH)],
@@ -6271,7 +6283,7 @@ class AsyncModels(_api_module.BaseModule):
6271
6283
  image = product_recontext_response.generated_images[0].image
6272
6284
 
6273
6285
  virtual_try_on_response = client.models.recontext_image(
6274
- model="virtual-try-on-preview-08-04",
6286
+ model="virtual-try-on-001",
6275
6287
  source=types.RecontextImageSource(
6276
6288
  person_image=types.Image.from_file(IMAGE1_FILE_PATH),
6277
6289
  product_images=[types.ProductImage.from_file(IMAGE2_FILE_PATH)],
@@ -0,0 +1,21 @@
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
+
17
+ """Tests for the Google GenAI SDK."""
18
+
19
+
20
+ import pytest
21
+ pytest.register_assert_rewrite('genai.replay_api_client')
@@ -0,0 +1,21 @@
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
+
17
+ """AFC helper function unit tests.
18
+
19
+ For AFC end to end test, please write test cases in
20
+ test_generate_content_tools.py module
21
+ """