google-genai 1.53.0__py3-none-any.whl → 1.55.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 (324) hide show
  1. google/genai/__init__.py +1 -0
  2. google/genai/_api_client.py +6 -6
  3. google/genai/_interactions/__init__.py +117 -0
  4. google/genai/_interactions/_base_client.py +2019 -0
  5. google/genai/_interactions/_client.py +511 -0
  6. google/genai/_interactions/_compat.py +234 -0
  7. google/genai/_interactions/_constants.py +29 -0
  8. google/genai/_interactions/_exceptions.py +122 -0
  9. google/genai/_interactions/_files.py +139 -0
  10. google/genai/_interactions/_models.py +873 -0
  11. google/genai/_interactions/_qs.py +165 -0
  12. google/genai/_interactions/_resource.py +58 -0
  13. google/genai/_interactions/_response.py +847 -0
  14. google/genai/_interactions/_streaming.py +354 -0
  15. google/genai/_interactions/_types.py +276 -0
  16. google/genai/_interactions/_utils/__init__.py +79 -0
  17. google/genai/_interactions/_utils/_compat.py +61 -0
  18. google/genai/_interactions/_utils/_datetime_parse.py +151 -0
  19. google/genai/_interactions/_utils/_logs.py +40 -0
  20. google/genai/_interactions/_utils/_proxy.py +80 -0
  21. google/genai/_interactions/_utils/_reflection.py +57 -0
  22. google/genai/_interactions/_utils/_resources_proxy.py +39 -0
  23. google/genai/_interactions/_utils/_streams.py +27 -0
  24. google/genai/_interactions/_utils/_sync.py +73 -0
  25. google/genai/_interactions/_utils/_transform.py +472 -0
  26. google/genai/_interactions/_utils/_typing.py +172 -0
  27. google/genai/_interactions/_utils/_utils.py +437 -0
  28. google/genai/_interactions/_version.py +18 -0
  29. google/genai/_interactions/resources/__init__.py +34 -0
  30. google/genai/_interactions/resources/interactions.py +1350 -0
  31. google/genai/_interactions/types/__init__.py +107 -0
  32. google/genai/_interactions/types/allowed_tools.py +33 -0
  33. google/genai/_interactions/types/allowed_tools_param.py +35 -0
  34. google/genai/_interactions/types/annotation.py +42 -0
  35. google/genai/_interactions/types/annotation_param.py +42 -0
  36. google/genai/_interactions/types/audio_content.py +38 -0
  37. google/genai/_interactions/types/audio_content_param.py +45 -0
  38. google/genai/_interactions/types/audio_mime_type.py +25 -0
  39. google/genai/_interactions/types/audio_mime_type_param.py +27 -0
  40. google/genai/_interactions/types/code_execution_call_arguments.py +33 -0
  41. google/genai/_interactions/types/code_execution_call_arguments_param.py +32 -0
  42. google/genai/_interactions/types/code_execution_call_content.py +37 -0
  43. google/genai/_interactions/types/code_execution_call_content_param.py +37 -0
  44. google/genai/_interactions/types/code_execution_result_content.py +42 -0
  45. google/genai/_interactions/types/code_execution_result_content_param.py +41 -0
  46. google/genai/_interactions/types/content_delta.py +358 -0
  47. google/genai/_interactions/types/content_start.py +79 -0
  48. google/genai/_interactions/types/content_stop.py +35 -0
  49. google/genai/_interactions/types/deep_research_agent_config.py +33 -0
  50. google/genai/_interactions/types/deep_research_agent_config_param.py +32 -0
  51. google/genai/_interactions/types/document_content.py +36 -0
  52. google/genai/_interactions/types/document_content_param.py +43 -0
  53. google/genai/_interactions/types/dynamic_agent_config.py +44 -0
  54. google/genai/_interactions/types/dynamic_agent_config_param.py +33 -0
  55. google/genai/_interactions/types/error_event.py +46 -0
  56. google/genai/_interactions/types/file_search_result_content.py +46 -0
  57. google/genai/_interactions/types/file_search_result_content_param.py +46 -0
  58. google/genai/_interactions/types/function.py +38 -0
  59. google/genai/_interactions/types/function_call_content.py +39 -0
  60. google/genai/_interactions/types/function_call_content_param.py +39 -0
  61. google/genai/_interactions/types/function_param.py +37 -0
  62. google/genai/_interactions/types/function_result_content.py +52 -0
  63. google/genai/_interactions/types/function_result_content_param.py +54 -0
  64. google/genai/_interactions/types/generation_config.py +57 -0
  65. google/genai/_interactions/types/generation_config_param.py +59 -0
  66. google/genai/_interactions/types/google_search_call_arguments.py +29 -0
  67. google/genai/_interactions/types/google_search_call_arguments_param.py +31 -0
  68. google/genai/_interactions/types/google_search_call_content.py +37 -0
  69. google/genai/_interactions/types/google_search_call_content_param.py +37 -0
  70. google/genai/_interactions/types/google_search_result.py +35 -0
  71. google/genai/_interactions/types/google_search_result_content.py +43 -0
  72. google/genai/_interactions/types/google_search_result_content_param.py +44 -0
  73. google/genai/_interactions/types/google_search_result_param.py +35 -0
  74. google/genai/_interactions/types/image_content.py +41 -0
  75. google/genai/_interactions/types/image_content_param.py +48 -0
  76. google/genai/_interactions/types/image_mime_type.py +23 -0
  77. google/genai/_interactions/types/image_mime_type_param.py +25 -0
  78. google/genai/_interactions/types/interaction.py +165 -0
  79. google/genai/_interactions/types/interaction_create_params.py +212 -0
  80. google/genai/_interactions/types/interaction_event.py +37 -0
  81. google/genai/_interactions/types/interaction_get_params.py +46 -0
  82. google/genai/_interactions/types/interaction_sse_event.py +32 -0
  83. google/genai/_interactions/types/interaction_status_update.py +37 -0
  84. google/genai/_interactions/types/mcp_server_tool_call_content.py +42 -0
  85. google/genai/_interactions/types/mcp_server_tool_call_content_param.py +42 -0
  86. google/genai/_interactions/types/mcp_server_tool_result_content.py +52 -0
  87. google/genai/_interactions/types/mcp_server_tool_result_content_param.py +54 -0
  88. google/genai/_interactions/types/model.py +36 -0
  89. google/genai/_interactions/types/model_param.py +38 -0
  90. google/genai/_interactions/types/speech_config.py +35 -0
  91. google/genai/_interactions/types/speech_config_param.py +35 -0
  92. google/genai/_interactions/types/text_content.py +37 -0
  93. google/genai/_interactions/types/text_content_param.py +38 -0
  94. google/genai/_interactions/types/thinking_level.py +22 -0
  95. google/genai/_interactions/types/thought_content.py +41 -0
  96. google/genai/_interactions/types/thought_content_param.py +47 -0
  97. google/genai/_interactions/types/tool.py +100 -0
  98. google/genai/_interactions/types/tool_choice.py +26 -0
  99. google/genai/_interactions/types/tool_choice_config.py +28 -0
  100. google/genai/_interactions/types/tool_choice_config_param.py +29 -0
  101. google/genai/_interactions/types/tool_choice_param.py +28 -0
  102. google/genai/_interactions/types/tool_choice_type.py +22 -0
  103. google/genai/_interactions/types/tool_param.py +97 -0
  104. google/genai/_interactions/types/turn.py +76 -0
  105. google/genai/_interactions/types/turn_param.py +73 -0
  106. google/genai/_interactions/types/url_context_call_arguments.py +29 -0
  107. google/genai/_interactions/types/url_context_call_arguments_param.py +31 -0
  108. google/genai/_interactions/types/url_context_call_content.py +37 -0
  109. google/genai/_interactions/types/url_context_call_content_param.py +37 -0
  110. google/genai/_interactions/types/url_context_result.py +33 -0
  111. google/genai/_interactions/types/url_context_result_content.py +43 -0
  112. google/genai/_interactions/types/url_context_result_content_param.py +44 -0
  113. google/genai/_interactions/types/url_context_result_param.py +32 -0
  114. google/genai/_interactions/types/usage.py +106 -0
  115. google/genai/_interactions/types/usage_param.py +106 -0
  116. google/genai/_interactions/types/video_content.py +41 -0
  117. google/genai/_interactions/types/video_content_param.py +48 -0
  118. google/genai/_interactions/types/video_mime_type.py +36 -0
  119. google/genai/_interactions/types/video_mime_type_param.py +38 -0
  120. google/genai/_live_converters.py +34 -3
  121. google/genai/_tokens_converters.py +5 -0
  122. google/genai/batches.py +62 -55
  123. google/genai/client.py +223 -0
  124. google/genai/errors.py +16 -1
  125. google/genai/file_search_stores.py +60 -60
  126. google/genai/files.py +56 -56
  127. google/genai/interactions.py +17 -0
  128. google/genai/live.py +4 -3
  129. google/genai/models.py +15 -3
  130. google/genai/tests/__init__.py +21 -0
  131. google/genai/tests/afc/__init__.py +21 -0
  132. google/genai/tests/afc/test_convert_if_exist_pydantic_model.py +309 -0
  133. google/genai/tests/afc/test_convert_number_values_for_function_call_args.py +63 -0
  134. google/genai/tests/afc/test_find_afc_incompatible_tool_indexes.py +240 -0
  135. google/genai/tests/afc/test_generate_content_stream_afc.py +530 -0
  136. google/genai/tests/afc/test_generate_content_stream_afc_thoughts.py +77 -0
  137. google/genai/tests/afc/test_get_function_map.py +176 -0
  138. google/genai/tests/afc/test_get_function_response_parts.py +277 -0
  139. google/genai/tests/afc/test_get_max_remote_calls_for_afc.py +130 -0
  140. google/genai/tests/afc/test_invoke_function_from_dict_args.py +241 -0
  141. google/genai/tests/afc/test_raise_error_for_afc_incompatible_config.py +159 -0
  142. google/genai/tests/afc/test_should_append_afc_history.py +53 -0
  143. google/genai/tests/afc/test_should_disable_afc.py +214 -0
  144. google/genai/tests/batches/__init__.py +17 -0
  145. google/genai/tests/batches/test_cancel.py +77 -0
  146. google/genai/tests/batches/test_create.py +78 -0
  147. google/genai/tests/batches/test_create_with_bigquery.py +113 -0
  148. google/genai/tests/batches/test_create_with_file.py +82 -0
  149. google/genai/tests/batches/test_create_with_gcs.py +125 -0
  150. google/genai/tests/batches/test_create_with_inlined_requests.py +255 -0
  151. google/genai/tests/batches/test_delete.py +86 -0
  152. google/genai/tests/batches/test_embedding.py +157 -0
  153. google/genai/tests/batches/test_get.py +78 -0
  154. google/genai/tests/batches/test_list.py +79 -0
  155. google/genai/tests/caches/__init__.py +17 -0
  156. google/genai/tests/caches/constants.py +29 -0
  157. google/genai/tests/caches/test_create.py +210 -0
  158. google/genai/tests/caches/test_create_custom_url.py +105 -0
  159. google/genai/tests/caches/test_delete.py +54 -0
  160. google/genai/tests/caches/test_delete_custom_url.py +52 -0
  161. google/genai/tests/caches/test_get.py +94 -0
  162. google/genai/tests/caches/test_get_custom_url.py +52 -0
  163. google/genai/tests/caches/test_list.py +68 -0
  164. google/genai/tests/caches/test_update.py +70 -0
  165. google/genai/tests/caches/test_update_custom_url.py +58 -0
  166. google/genai/tests/chats/__init__.py +1 -0
  167. google/genai/tests/chats/test_get_history.py +597 -0
  168. google/genai/tests/chats/test_send_message.py +844 -0
  169. google/genai/tests/chats/test_validate_response.py +90 -0
  170. google/genai/tests/client/__init__.py +17 -0
  171. google/genai/tests/client/test_async_stream.py +427 -0
  172. google/genai/tests/client/test_client_close.py +197 -0
  173. google/genai/tests/client/test_client_initialization.py +1687 -0
  174. google/genai/tests/client/test_client_requests.py +355 -0
  175. google/genai/tests/client/test_custom_client.py +77 -0
  176. google/genai/tests/client/test_http_options.py +178 -0
  177. google/genai/tests/client/test_replay_client_equality.py +168 -0
  178. google/genai/tests/client/test_retries.py +846 -0
  179. google/genai/tests/client/test_upload_errors.py +136 -0
  180. google/genai/tests/common/__init__.py +17 -0
  181. google/genai/tests/common/test_common.py +954 -0
  182. google/genai/tests/conftest.py +162 -0
  183. google/genai/tests/documents/__init__.py +17 -0
  184. google/genai/tests/documents/test_delete.py +51 -0
  185. google/genai/tests/documents/test_get.py +85 -0
  186. google/genai/tests/documents/test_list.py +72 -0
  187. google/genai/tests/errors/__init__.py +1 -0
  188. google/genai/tests/errors/test_api_error.py +417 -0
  189. google/genai/tests/file_search_stores/__init__.py +17 -0
  190. google/genai/tests/file_search_stores/test_create.py +66 -0
  191. google/genai/tests/file_search_stores/test_delete.py +64 -0
  192. google/genai/tests/file_search_stores/test_get.py +94 -0
  193. google/genai/tests/file_search_stores/test_import_file.py +112 -0
  194. google/genai/tests/file_search_stores/test_list.py +57 -0
  195. google/genai/tests/file_search_stores/test_upload_to_file_search_store.py +141 -0
  196. google/genai/tests/files/__init__.py +17 -0
  197. google/genai/tests/files/test_delete.py +46 -0
  198. google/genai/tests/files/test_download.py +85 -0
  199. google/genai/tests/files/test_get.py +46 -0
  200. google/genai/tests/files/test_list.py +72 -0
  201. google/genai/tests/files/test_upload.py +255 -0
  202. google/genai/tests/imports/test_no_optional_imports.py +28 -0
  203. google/genai/tests/interactions/__init__.py +0 -0
  204. google/genai/tests/interactions/test_integration.py +80 -0
  205. google/genai/tests/live/__init__.py +16 -0
  206. google/genai/tests/live/test_live.py +2177 -0
  207. google/genai/tests/live/test_live_music.py +362 -0
  208. google/genai/tests/live/test_live_response.py +163 -0
  209. google/genai/tests/live/test_send_client_content.py +147 -0
  210. google/genai/tests/live/test_send_realtime_input.py +268 -0
  211. google/genai/tests/live/test_send_tool_response.py +222 -0
  212. google/genai/tests/local_tokenizer/__init__.py +17 -0
  213. google/genai/tests/local_tokenizer/test_local_tokenizer.py +343 -0
  214. google/genai/tests/local_tokenizer/test_local_tokenizer_loader.py +235 -0
  215. google/genai/tests/mcp/__init__.py +17 -0
  216. google/genai/tests/mcp/test_has_mcp_tool_usage.py +89 -0
  217. google/genai/tests/mcp/test_mcp_to_gemini_tools.py +191 -0
  218. google/genai/tests/mcp/test_parse_config_for_mcp_sessions.py +201 -0
  219. google/genai/tests/mcp/test_parse_config_for_mcp_usage.py +130 -0
  220. google/genai/tests/mcp/test_set_mcp_usage_header.py +72 -0
  221. google/genai/tests/models/__init__.py +17 -0
  222. google/genai/tests/models/constants.py +8 -0
  223. google/genai/tests/models/test_compute_tokens.py +120 -0
  224. google/genai/tests/models/test_count_tokens.py +159 -0
  225. google/genai/tests/models/test_delete.py +107 -0
  226. google/genai/tests/models/test_edit_image.py +264 -0
  227. google/genai/tests/models/test_embed_content.py +94 -0
  228. google/genai/tests/models/test_function_call_streaming.py +442 -0
  229. google/genai/tests/models/test_generate_content.py +2502 -0
  230. google/genai/tests/models/test_generate_content_cached_content.py +132 -0
  231. google/genai/tests/models/test_generate_content_config_zero_value.py +103 -0
  232. google/genai/tests/models/test_generate_content_from_apikey.py +44 -0
  233. google/genai/tests/models/test_generate_content_http_options.py +40 -0
  234. google/genai/tests/models/test_generate_content_image_generation.py +143 -0
  235. google/genai/tests/models/test_generate_content_mcp.py +343 -0
  236. google/genai/tests/models/test_generate_content_media_resolution.py +97 -0
  237. google/genai/tests/models/test_generate_content_model.py +139 -0
  238. google/genai/tests/models/test_generate_content_part.py +821 -0
  239. google/genai/tests/models/test_generate_content_thought.py +76 -0
  240. google/genai/tests/models/test_generate_content_tools.py +1761 -0
  241. google/genai/tests/models/test_generate_images.py +191 -0
  242. google/genai/tests/models/test_generate_videos.py +759 -0
  243. google/genai/tests/models/test_get.py +104 -0
  244. google/genai/tests/models/test_list.py +233 -0
  245. google/genai/tests/models/test_recontext_image.py +189 -0
  246. google/genai/tests/models/test_segment_image.py +148 -0
  247. google/genai/tests/models/test_update.py +95 -0
  248. google/genai/tests/models/test_upscale_image.py +157 -0
  249. google/genai/tests/operations/__init__.py +17 -0
  250. google/genai/tests/operations/test_get.py +38 -0
  251. google/genai/tests/public_samples/__init__.py +17 -0
  252. google/genai/tests/public_samples/test_gemini_text_only.py +34 -0
  253. google/genai/tests/pytest_helper.py +229 -0
  254. google/genai/tests/shared/__init__.py +16 -0
  255. google/genai/tests/shared/batches/__init__.py +14 -0
  256. google/genai/tests/shared/batches/test_create_delete.py +57 -0
  257. google/genai/tests/shared/batches/test_create_get_cancel.py +56 -0
  258. google/genai/tests/shared/batches/test_list.py +40 -0
  259. google/genai/tests/shared/caches/__init__.py +14 -0
  260. google/genai/tests/shared/caches/test_create_get_delete.py +67 -0
  261. google/genai/tests/shared/caches/test_create_update_get.py +71 -0
  262. google/genai/tests/shared/caches/test_list.py +40 -0
  263. google/genai/tests/shared/chats/__init__.py +14 -0
  264. google/genai/tests/shared/chats/test_send_message.py +48 -0
  265. google/genai/tests/shared/chats/test_send_message_stream.py +50 -0
  266. google/genai/tests/shared/files/__init__.py +14 -0
  267. google/genai/tests/shared/files/test_list.py +41 -0
  268. google/genai/tests/shared/files/test_upload_get_delete.py +54 -0
  269. google/genai/tests/shared/models/__init__.py +14 -0
  270. google/genai/tests/shared/models/test_compute_tokens.py +41 -0
  271. google/genai/tests/shared/models/test_count_tokens.py +40 -0
  272. google/genai/tests/shared/models/test_edit_image.py +67 -0
  273. google/genai/tests/shared/models/test_embed.py +40 -0
  274. google/genai/tests/shared/models/test_generate_content.py +39 -0
  275. google/genai/tests/shared/models/test_generate_content_stream.py +54 -0
  276. google/genai/tests/shared/models/test_generate_images.py +40 -0
  277. google/genai/tests/shared/models/test_generate_videos.py +38 -0
  278. google/genai/tests/shared/models/test_list.py +37 -0
  279. google/genai/tests/shared/models/test_recontext_image.py +55 -0
  280. google/genai/tests/shared/models/test_segment_image.py +52 -0
  281. google/genai/tests/shared/models/test_upscale_image.py +52 -0
  282. google/genai/tests/shared/tunings/__init__.py +16 -0
  283. google/genai/tests/shared/tunings/test_create.py +46 -0
  284. google/genai/tests/shared/tunings/test_create_get_cancel.py +56 -0
  285. google/genai/tests/shared/tunings/test_list.py +39 -0
  286. google/genai/tests/tokens/__init__.py +16 -0
  287. google/genai/tests/tokens/test_create.py +154 -0
  288. google/genai/tests/transformers/__init__.py +17 -0
  289. google/genai/tests/transformers/test_blobs.py +71 -0
  290. google/genai/tests/transformers/test_bytes.py +15 -0
  291. google/genai/tests/transformers/test_duck_type.py +96 -0
  292. google/genai/tests/transformers/test_function_responses.py +72 -0
  293. google/genai/tests/transformers/test_schema.py +653 -0
  294. google/genai/tests/transformers/test_t_batch.py +286 -0
  295. google/genai/tests/transformers/test_t_content.py +160 -0
  296. google/genai/tests/transformers/test_t_contents.py +398 -0
  297. google/genai/tests/transformers/test_t_part.py +85 -0
  298. google/genai/tests/transformers/test_t_parts.py +87 -0
  299. google/genai/tests/transformers/test_t_tool.py +157 -0
  300. google/genai/tests/transformers/test_t_tools.py +195 -0
  301. google/genai/tests/tunings/__init__.py +16 -0
  302. google/genai/tests/tunings/test_cancel.py +39 -0
  303. google/genai/tests/tunings/test_end_to_end.py +106 -0
  304. google/genai/tests/tunings/test_get.py +67 -0
  305. google/genai/tests/tunings/test_list.py +75 -0
  306. google/genai/tests/tunings/test_tune.py +268 -0
  307. google/genai/tests/types/__init__.py +16 -0
  308. google/genai/tests/types/test_bytes_internal.py +271 -0
  309. google/genai/tests/types/test_bytes_type.py +152 -0
  310. google/genai/tests/types/test_future.py +101 -0
  311. google/genai/tests/types/test_optional_types.py +36 -0
  312. google/genai/tests/types/test_part_type.py +616 -0
  313. google/genai/tests/types/test_schema_from_json_schema.py +417 -0
  314. google/genai/tests/types/test_schema_json_schema.py +468 -0
  315. google/genai/tests/types/test_types.py +2903 -0
  316. google/genai/tunings.py +57 -57
  317. google/genai/types.py +229 -121
  318. google/genai/version.py +1 -1
  319. {google_genai-1.53.0.dist-info → google_genai-1.55.0.dist-info}/METADATA +4 -2
  320. google_genai-1.55.0.dist-info/RECORD +345 -0
  321. google_genai-1.53.0.dist-info/RECORD +0 -41
  322. {google_genai-1.53.0.dist-info → google_genai-1.55.0.dist-info}/WHEEL +0 -0
  323. {google_genai-1.53.0.dist-info → google_genai-1.55.0.dist-info}/licenses/LICENSE +0 -0
  324. {google_genai-1.53.0.dist-info → google_genai-1.55.0.dist-info}/top_level.txt +0 -0
@@ -0,0 +1,95 @@
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
+ import pytest
18
+ from ... import errors
19
+ from ... import types
20
+ from .. import pytest_helper
21
+
22
+ test_http_options = {'headers': {'test': 'headers'}}
23
+
24
+ test_table: list[pytest_helper.TestTableItem] = [
25
+ pytest_helper.TestTableItem(
26
+ name='test_vertex_tuned_models_update',
27
+ parameters=types._UpdateModelParameters(
28
+ model='models/2171259487439028224',
29
+ config={
30
+ 'description': (
31
+ 'My SupervisedTuningJob'
32
+ ),
33
+ 'default_checkpoint_id': '8',
34
+ },
35
+ ),
36
+ exception_if_mldev='404',
37
+ ),
38
+ pytest_helper.TestTableItem(
39
+ name='test_vertex_tuned_models_update_with_http_options_in_method',
40
+ parameters=types._UpdateModelParameters(
41
+ model='models/2171259487439028224',
42
+ config={
43
+ 'description': (
44
+ 'My SupervisedTuningJob'
45
+ ),
46
+ 'default_checkpoint_id': '8',
47
+ 'http_options': test_http_options,
48
+ },
49
+ ),
50
+ exception_if_mldev='404',
51
+ ),
52
+ ]
53
+
54
+ pytestmark = pytest_helper.setup(
55
+ file=__file__,
56
+ globals_for_file=globals(),
57
+ test_method='models.update',
58
+ test_table=test_table,
59
+ )
60
+
61
+
62
+ @pytest.mark.asyncio
63
+ async def test_async_update_tuned_model(client):
64
+ if client._api_client.vertexai:
65
+ with pytest.raises(errors.ClientError) as e:
66
+ await client.aio.models.update(
67
+ model='tunedModels/generatenum5443-ekrw7ie9wis23zbeogbw6jq8',
68
+ config={
69
+ 'description': 'My tuned gemini model',
70
+ 'http_options': test_http_options,
71
+ },
72
+ )
73
+ assert '404' in str(e)
74
+
75
+
76
+ @pytest.mark.asyncio
77
+ async def test_async_update_model(client):
78
+ if client._api_client.vertexai:
79
+ response = await client.aio.models.update(
80
+ model='models/2171259487439028224',
81
+ config={
82
+ 'display_name': 'My tuned gemini model',
83
+ 'http_options': test_http_options,
84
+ },
85
+ )
86
+ else:
87
+ with pytest.raises(errors.ClientError) as e:
88
+ await client.aio.models.update(
89
+ model='models/2171259487439028224',
90
+ config={
91
+ 'display_name': 'My tuned gemini model',
92
+ 'http_options': test_http_options,
93
+ },
94
+ )
95
+ assert '404' in str(e)
@@ -0,0 +1,157 @@
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 upscale_image."""
18
+
19
+ import os
20
+
21
+ from pydantic import ValidationError
22
+ import pytest
23
+
24
+ from ... import types
25
+ from .. import pytest_helper
26
+
27
+ IMAGEN_MODEL_LATEST = 'imagen-4.0-upscale-preview'
28
+
29
+ IMAGE_FILE_PATH = os.path.abspath(
30
+ os.path.join(os.path.dirname(__file__), '../data/bridge1.png')
31
+ )
32
+
33
+ test_table: list[pytest_helper.TestTableItem] = [
34
+ pytest_helper.TestTableItem(
35
+ name='test_upscale_no_config',
36
+ exception_if_mldev='only supported in the Vertex AI client',
37
+ parameters=types.UpscaleImageParameters(
38
+ model=IMAGEN_MODEL_LATEST,
39
+ image=types.Image.from_file(location=IMAGE_FILE_PATH),
40
+ upscale_factor='x2',
41
+ ),
42
+ ),
43
+ pytest_helper.TestTableItem(
44
+ name='test_upscale',
45
+ exception_if_mldev='only supported in the Vertex AI client',
46
+ parameters=types.UpscaleImageParameters(
47
+ model=IMAGEN_MODEL_LATEST,
48
+ image=types.Image.from_file(location=IMAGE_FILE_PATH),
49
+ upscale_factor='x2',
50
+ config=types.UpscaleImageConfig(
51
+ include_rai_reason=True,
52
+ person_generation=types.PersonGeneration.ALLOW_ADULT,
53
+ safety_filter_level=types.SafetyFilterLevel.BLOCK_LOW_AND_ABOVE,
54
+ output_mime_type='image/jpeg',
55
+ output_compression_quality=80,
56
+ enhance_input_image=True,
57
+ image_preservation_factor=0.6,
58
+ labels={'imagen_label_key': 'upscale_image'}
59
+ ),
60
+ ),
61
+ ),
62
+ pytest_helper.TestTableItem(
63
+ name='test_upscale_gcs',
64
+ exception_if_mldev='only supported in the Vertex AI client',
65
+ parameters=types.UpscaleImageParameters(
66
+ model=IMAGEN_MODEL_LATEST,
67
+ image=types.Image.from_file(location=IMAGE_FILE_PATH),
68
+ upscale_factor='x2',
69
+ config=types.UpscaleImageConfig(
70
+ output_gcs_uri='gs://genai-sdk-tests/temp/images/',
71
+ ),
72
+ ),
73
+ ),
74
+ ]
75
+ pytestmark = pytest_helper.setup(
76
+ file=__file__,
77
+ globals_for_file=globals(),
78
+ test_method='models.upscale_image',
79
+ test_table=test_table,
80
+ )
81
+
82
+
83
+ def test_upscale_extra_config_parameters(client):
84
+ # MLDev currently does not support upscale_image, but the ValidationError
85
+ # occurs before the ValueError.
86
+ try:
87
+ # User is not allowed to set mode or number_of_images
88
+ client.models.upscale_image(
89
+ model=IMAGEN_MODEL_LATEST,
90
+ image=types.Image.from_file(location=IMAGE_FILE_PATH),
91
+ upscale_factor='x2',
92
+ config={
93
+ 'mode': 'upscale',
94
+ 'number_of_images': 1,
95
+ }
96
+ )
97
+ # Should never reach this.
98
+ assert False
99
+ except Exception as e:
100
+ assert isinstance(e, ValidationError)
101
+ assert 'Extra inputs are not permitted' in str(e)
102
+
103
+
104
+ @pytest.mark.asyncio
105
+ async def test_upscale_async(client):
106
+ with pytest_helper.exception_if_mldev(client, ValueError):
107
+ response = await client.aio.models.upscale_image(
108
+ model=IMAGEN_MODEL_LATEST,
109
+ image=types.Image.from_file(location=IMAGE_FILE_PATH),
110
+ upscale_factor='x2',
111
+ config=types.UpscaleImageConfig(
112
+ person_generation=types.PersonGeneration.ALLOW_ADULT,
113
+ safety_filter_level=types.SafetyFilterLevel.BLOCK_LOW_AND_ABOVE,
114
+ include_rai_reason=True,
115
+ output_mime_type='image/jpeg',
116
+ output_compression_quality=80,
117
+ enhance_input_image=True,
118
+ image_preservation_factor=0.6,
119
+ ),
120
+ )
121
+ assert response.generated_images[0].image.image_bytes
122
+
123
+
124
+ @pytest.mark.asyncio
125
+ async def test_upscale_gcs_async(client):
126
+ with pytest_helper.exception_if_mldev(client, ValueError):
127
+ response = await client.aio.models.upscale_image(
128
+ model=IMAGEN_MODEL_LATEST,
129
+ image=types.Image.from_file(location=IMAGE_FILE_PATH),
130
+ upscale_factor='x2',
131
+ config=types.UpscaleImageConfig(
132
+ output_gcs_uri='gs://genai-sdk-tests/temp/images/',
133
+ ),
134
+ )
135
+ assert response.generated_images[0].image.gcs_uri
136
+
137
+
138
+ @pytest.mark.asyncio
139
+ async def test_upscale_extra_config_parameters_async(client):
140
+ # MLDev currently does not support upscale_image, but the ValidationError
141
+ # occurs before the ValueError.
142
+ try:
143
+ # User is not allowed to set mode or number_of_images
144
+ await client.aio.models.upscale_image(
145
+ model=IMAGEN_MODEL_LATEST,
146
+ image=types.Image.from_file(location=IMAGE_FILE_PATH),
147
+ upscale_factor='x2',
148
+ config={
149
+ 'mode': 'upscale',
150
+ 'number_of_images': 1,
151
+ },
152
+ )
153
+ # Should never reach this.
154
+ assert False
155
+ except Exception as e:
156
+ assert isinstance(e, ValidationError)
157
+ assert 'Extra inputs are not permitted' in str(e)
@@ -0,0 +1,17 @@
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 operations.get."""
@@ -0,0 +1,38 @@
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 operations._get."""
18
+
19
+ from .. import pytest_helper
20
+ from ... import types
21
+
22
+
23
+ def test_project_operation_get(client):
24
+ test_operation_id = '3787416390563004416'
25
+ if client._api_client.vertexai:
26
+ operation = client.operations._get(
27
+ operation_id=test_operation_id
28
+ )
29
+ assert operation.name.endswith(test_operation_id)
30
+ assert operation.done
31
+ assert isinstance(operation, types.ProjectOperation)
32
+
33
+
34
+ pytestmark = pytest_helper.setup(
35
+ file=__file__,
36
+ globals_for_file=globals(),
37
+ test_method='operations._get',
38
+ )
@@ -0,0 +1,17 @@
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
+ """Public Samples and Tests for the Google GenAI SDK."""
@@ -0,0 +1,34 @@
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
+ """Test for the code sample for Gemini text-only request."""
18
+
19
+ from .. import pytest_helper
20
+
21
+ pytestmark = pytest_helper.setup(file=__file__)
22
+
23
+
24
+ def test_sample(client):
25
+ # [START generativeaionvertexai_gemini_text_only]
26
+ response = client.models.generate_content(
27
+ model="gemini-2.5-flash",
28
+ contents=(
29
+ "What's a good name for a flower shop that specializes in selling"
30
+ " bouquets of dried flowers?"
31
+ ),
32
+ )
33
+ print(response.text)
34
+ # [END generativeaionvertexai_gemini_text_only]
@@ -0,0 +1,229 @@
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
+ import contextlib
18
+ import json
19
+ import os
20
+ import pathlib
21
+ from typing import Any, Optional
22
+ from pydantic import BaseModel, Field, SerializeAsAny
23
+ import pytest
24
+ import re
25
+ from .. import _common
26
+ from .. import _replay_api_client
27
+ from .. import types
28
+ from .._api_client import HttpOptions
29
+
30
+ is_api_mode = "config.getoption('--mode') == 'api'"
31
+
32
+
33
+ class TestTableItem(types.TestTableItem):
34
+ # This is not a test suite class.
35
+ __test__ = False
36
+
37
+ # Overrides to support Pydantic models.
38
+ parameters: SerializeAsAny[BaseModel] = Field(
39
+ description="""The parameters to the test. Use pydantic models.""",
40
+ )
41
+
42
+
43
+ def base_test_function(
44
+ client,
45
+ use_vertex: bool,
46
+ replays_prefix: str,
47
+ test_method: str,
48
+ test_table_item: TestTableItem,
49
+ globals_for_file: dict[str, Any],
50
+ ):
51
+ replay_id = (
52
+ test_table_item.override_replay_id
53
+ if test_table_item.override_replay_id
54
+ else test_table_item.name
55
+ )
56
+ api_type = 'vertex' if use_vertex else 'mldev'
57
+ replay_id = f'{replays_prefix}/{replay_id}.{api_type}'
58
+ client._api_client.initialize_replay_session(replay_id)
59
+ # vars().copy() provides a shallow copy of the parameters.
60
+ parameters_dict = vars(test_table_item.parameters).copy()
61
+ try:
62
+ if '.' in test_method:
63
+ method_name_parts = test_method.split('.')
64
+ module_path_parts = method_name_parts[:-1]
65
+ method_name = method_name_parts[-1]
66
+ # Iterates the nested module starting from client
67
+ current_object = client
68
+ for part in module_path_parts:
69
+ current_object = getattr(current_object, part)
70
+ method = getattr(current_object, method_name)
71
+ method(**parameters_dict)
72
+ else:
73
+ custom_method = globals_for_file[test_method]
74
+ custom_method(client, test_table_item.parameters)
75
+ # Should not reach here if expecting an exception.
76
+ if test_table_item.exception_if_mldev and not client._api_client.vertexai:
77
+ assert False, 'Should have raised exception in MLDev.'
78
+ elif test_table_item.exception_if_vertex and client._api_client.vertexai:
79
+ assert False, 'Should have raised exception in Vertex.'
80
+ client._api_client.close()
81
+ except Exception as e:
82
+ if test_table_item.exception_if_mldev and not client._api_client.vertexai:
83
+ if test_table_item.exception_if_mldev not in str(e):
84
+ raise AssertionError(
85
+ f"'{test_table_item.exception_if_mldev}' not in '{str(e)}'"
86
+ ) from e
87
+ elif test_table_item.exception_if_vertex and client._api_client.vertexai:
88
+ if test_table_item.exception_if_vertex not in str(e):
89
+ raise AssertionError(
90
+ f"'{test_table_item.exception_if_vertex}' not in '{str(e)}'"
91
+ ) from e
92
+ else:
93
+ raise e
94
+
95
+
96
+ def create_test_for_table_item(
97
+ globals_for_file: dict[str, Any],
98
+ test_method: str,
99
+ test_table_item: TestTableItem,
100
+ ):
101
+ return lambda client, use_vertex, replays_prefix: base_test_function(
102
+ client,
103
+ use_vertex,
104
+ replays_prefix,
105
+ test_method,
106
+ test_table_item,
107
+ globals_for_file,
108
+ )
109
+
110
+
111
+ def create_test_for_table(
112
+ globals_for_file: dict[str, Any],
113
+ test_method: str,
114
+ test_table: list[TestTableItem],
115
+ ):
116
+ for test_table_item in test_table:
117
+ if test_table_item.has_union:
118
+ assert test_table_item.name.startswith('test_union_'), f"""
119
+ test: {test_table_item.name}
120
+ When has_union is true, it must be a test that explicitly test the
121
+ non-canonical type in the union.
122
+ For all other tests, use transformers to convert data to the canonical
123
+ type of the field so it can be tested in other languages.
124
+ If this test is truly about testing the non-canonical type of the union,
125
+ rename the test to start with 'test_union_'. E.g.
126
+ test_union_contents_is_string()"""
127
+ globals_for_file[test_table_item.name] = create_test_for_table_item(
128
+ globals_for_file, test_method, test_table_item
129
+ )
130
+
131
+
132
+ # Sets up the test framework.
133
+ # file: Always use __file__
134
+ # globals_for_file: Always use globals()
135
+ # test_table: The test table for the file.
136
+ # Use test table over individual tests whenever possible.
137
+ # Tests built with test_table will run in all other languages automatically.
138
+ # Otherwise, you will need to write tests in all other languages manually.
139
+ def setup(
140
+ *,
141
+ file: str,
142
+ globals_for_file: Optional[dict[str, Any]] = None,
143
+ test_method: Optional[str] = None,
144
+ test_table: Optional[list[TestTableItem]] = None,
145
+ http_options: Optional[HttpOptions] = None,
146
+ ):
147
+ """Generates parameterization for tests, run for both Vertex and MLDev."""
148
+ replays_directory = (
149
+ file.replace(os.path.dirname(__file__), 'tests')
150
+ .replace('.py', '')
151
+ .replace('/test_', '/')
152
+ )
153
+
154
+ is_tap_mode = False
155
+ if os.environ.get('UNITTEST_ON_FORGE', None) is not None:
156
+ is_tap_mode = True
157
+
158
+ if test_table:
159
+ create_test_for_table(globals_for_file, test_method, test_table)
160
+
161
+ if test_table and not is_tap_mode:
162
+ replays_root_directory = os.environ.get(
163
+ 'GOOGLE_GENAI_REPLAYS_DIRECTORY', None
164
+ )
165
+ if replays_root_directory is None:
166
+ raise ValueError(
167
+ 'GOOGLE_GENAI_REPLAYS_DIRECTORY environment variable is not set'
168
+ )
169
+ abs_replay_directory = os.path.join(
170
+ replays_root_directory, replays_directory
171
+ )
172
+ test_table_file_path = os.path.join(
173
+ abs_replay_directory, '_test_table.json'
174
+ )
175
+
176
+ pathlib.Path(abs_replay_directory).mkdir(parents=True, exist_ok=True)
177
+ assert isinstance(
178
+ test_table[0].parameters, BaseModel
179
+ ), f'{test_table_file_path} parameters must be a BaseModel.'
180
+ test_table_file = types.TestTableFile(
181
+ comment='Auto-generated. Do not edit.',
182
+ test_method=test_method,
183
+ parameter_names=list(test_table[0].parameters.model_fields.keys()),
184
+ test_table=test_table,
185
+ )
186
+ os.makedirs(os.path.dirname(test_table_file_path), exist_ok=True)
187
+
188
+ with open(test_table_file_path, 'w') as f:
189
+ f.write(
190
+ test_table_file.model_dump_json(exclude_none=True, by_alias=True, indent=2),
191
+ )
192
+
193
+ # Add fixture for requested client option.
194
+ return pytest.mark.parametrize(
195
+ 'use_vertex, replays_prefix, http_options',
196
+ [
197
+ (True, replays_directory, http_options),
198
+ (False, replays_directory, http_options),
199
+ ],
200
+ )
201
+
202
+
203
+ def exception_if_mldev(client, exception_type: type[Exception]):
204
+ if client._api_client.vertexai:
205
+ return contextlib.nullcontext()
206
+ else:
207
+ return pytest.raises(exception_type)
208
+
209
+
210
+ def exception_if_vertex(client, exception_type: type[Exception]):
211
+ if client._api_client.vertexai:
212
+ return pytest.raises(exception_type)
213
+ else:
214
+ return contextlib.nullcontext()
215
+
216
+
217
+ def snake_to_camel(snake_str: str) -> str:
218
+ """Converts a snake_case string to CamelCase."""
219
+ return re.sub(r'_([a-zA-Z])', lambda match: match.group(1).upper(), snake_str)
220
+
221
+
222
+ def camel_to_snake(camel_str: str) -> str:
223
+ """Converts a CamelCase string to snake_case."""
224
+ return re.sub(r'([A-Z])', r'_\1', camel_str).lower().lstrip('_')
225
+
226
+
227
+ def get_value_ignore_key_case(obj, key):
228
+ """Returns the value of the key in the object, converting to camelCase or snake_case if necessary."""
229
+ return obj.get(snake_to_camel(key), obj.get(camel_to_snake(key), None))
@@ -0,0 +1,16 @@
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
+
@@ -0,0 +1,14 @@
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
+ #
@@ -0,0 +1,57 @@
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
+ """Tests batches.create(), batches.delete()."""
17
+
18
+ from .... import types as genai_types
19
+ from ... import pytest_helper
20
+
21
+
22
+ def create_delete(client, parameters):
23
+ batch_job = client.batches.create(
24
+ model=parameters.model,
25
+ src=parameters.src,
26
+ config=parameters.config,
27
+ )
28
+ # if pending then don't delete to avoid error
29
+ batch_job = client.batches.get(name=batch_job.name)
30
+ if batch_job.state != genai_types.JobState.JOB_STATE_PENDING:
31
+ client.batches.delete(name=batch_job.name)
32
+
33
+
34
+ test_table: list[pytest_helper.TestTableItem] = [
35
+ pytest_helper.TestTableItem(
36
+ name="test_create_delete_mldev",
37
+ parameters=genai_types._CreateBatchJobParameters(
38
+ model="gemini-2.5-flash",
39
+ src=[{
40
+ "contents": [{
41
+ "parts": [{"text": "Why is the sky blue?"}],
42
+ "role": "user",
43
+ }]
44
+ }],
45
+ ),
46
+ exception_if_vertex="not supported in Vertex AI.",
47
+ ),
48
+ ]
49
+
50
+ pytestmark = pytest_helper.setup(
51
+ file=__file__,
52
+ globals_for_file=globals(),
53
+ test_method="create_delete",
54
+ test_table=test_table,
55
+ )
56
+
57
+ pytest_plugins = ("pytest_asyncio",)