kernel 0.48.0__tar.gz → 0.50.0__tar.gz

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 (273) hide show
  1. kernel-0.50.0/.release-please-manifest.json +3 -0
  2. {kernel-0.48.0 → kernel-0.50.0}/CHANGELOG.md +29 -0
  3. {kernel-0.48.0 → kernel-0.50.0}/PKG-INFO +1 -1
  4. {kernel-0.48.0 → kernel-0.50.0}/api.md +2 -0
  5. {kernel-0.48.0 → kernel-0.50.0}/pyproject.toml +1 -1
  6. {kernel-0.48.0 → kernel-0.50.0}/src/kernel/_files.py +53 -3
  7. {kernel-0.48.0 → kernel-0.50.0}/src/kernel/_utils/__init__.py +0 -1
  8. {kernel-0.48.0 → kernel-0.50.0}/src/kernel/_utils/_utils.py +3 -17
  9. {kernel-0.48.0 → kernel-0.50.0}/src/kernel/_version.py +1 -1
  10. {kernel-0.48.0 → kernel-0.50.0}/src/kernel/resources/browsers/browsers.py +149 -6
  11. {kernel-0.48.0 → kernel-0.50.0}/src/kernel/resources/browsers/fs/fs.py +10 -8
  12. {kernel-0.48.0 → kernel-0.50.0}/src/kernel/resources/browsers/replays.py +4 -2
  13. {kernel-0.48.0 → kernel-0.50.0}/src/kernel/resources/deployments.py +8 -5
  14. {kernel-0.48.0 → kernel-0.50.0}/src/kernel/resources/extensions.py +8 -5
  15. {kernel-0.48.0 → kernel-0.50.0}/src/kernel/resources/projects/projects.py +4 -4
  16. {kernel-0.48.0 → kernel-0.50.0}/src/kernel/types/__init__.py +2 -0
  17. {kernel-0.48.0 → kernel-0.50.0}/src/kernel/types/auth/connection_follow_response.py +6 -0
  18. {kernel-0.48.0 → kernel-0.50.0}/src/kernel/types/auth/managed_auth.py +6 -0
  19. kernel-0.50.0/src/kernel/types/browser_curl_params.py +28 -0
  20. kernel-0.50.0/src/kernel/types/browser_curl_response.py +23 -0
  21. {kernel-0.48.0 → kernel-0.50.0}/src/kernel/types/browser_list_params.py +1 -1
  22. {kernel-0.48.0 → kernel-0.50.0}/src/kernel/types/browsers/replay_start_params.py +4 -1
  23. {kernel-0.48.0 → kernel-0.50.0}/tests/api_resources/test_browsers.py +121 -0
  24. {kernel-0.48.0 → kernel-0.50.0}/tests/test_extract_files.py +9 -0
  25. kernel-0.50.0/tests/test_files.py +148 -0
  26. kernel-0.48.0/.release-please-manifest.json +0 -3
  27. kernel-0.48.0/tests/test_deepcopy.py +0 -58
  28. kernel-0.48.0/tests/test_files.py +0 -51
  29. {kernel-0.48.0 → kernel-0.50.0}/.gitignore +0 -0
  30. {kernel-0.48.0 → kernel-0.50.0}/CONTRIBUTING.md +0 -0
  31. {kernel-0.48.0 → kernel-0.50.0}/LICENSE +0 -0
  32. {kernel-0.48.0 → kernel-0.50.0}/README.md +0 -0
  33. {kernel-0.48.0 → kernel-0.50.0}/SECURITY.md +0 -0
  34. {kernel-0.48.0 → kernel-0.50.0}/bin/check-release-environment +0 -0
  35. {kernel-0.48.0 → kernel-0.50.0}/bin/publish-pypi +0 -0
  36. {kernel-0.48.0 → kernel-0.50.0}/examples/.keep +0 -0
  37. {kernel-0.48.0 → kernel-0.50.0}/noxfile.py +0 -0
  38. {kernel-0.48.0 → kernel-0.50.0}/release-please-config.json +0 -0
  39. {kernel-0.48.0 → kernel-0.50.0}/requirements-dev.lock +0 -0
  40. {kernel-0.48.0 → kernel-0.50.0}/requirements.lock +0 -0
  41. {kernel-0.48.0 → kernel-0.50.0}/src/kernel/__init__.py +0 -0
  42. {kernel-0.48.0 → kernel-0.50.0}/src/kernel/_base_client.py +0 -0
  43. {kernel-0.48.0 → kernel-0.50.0}/src/kernel/_client.py +0 -0
  44. {kernel-0.48.0 → kernel-0.50.0}/src/kernel/_compat.py +0 -0
  45. {kernel-0.48.0 → kernel-0.50.0}/src/kernel/_constants.py +0 -0
  46. {kernel-0.48.0 → kernel-0.50.0}/src/kernel/_exceptions.py +0 -0
  47. {kernel-0.48.0 → kernel-0.50.0}/src/kernel/_models.py +0 -0
  48. {kernel-0.48.0 → kernel-0.50.0}/src/kernel/_qs.py +0 -0
  49. {kernel-0.48.0 → kernel-0.50.0}/src/kernel/_resource.py +0 -0
  50. {kernel-0.48.0 → kernel-0.50.0}/src/kernel/_response.py +0 -0
  51. {kernel-0.48.0 → kernel-0.50.0}/src/kernel/_streaming.py +0 -0
  52. {kernel-0.48.0 → kernel-0.50.0}/src/kernel/_types.py +0 -0
  53. {kernel-0.48.0 → kernel-0.50.0}/src/kernel/_utils/_compat.py +0 -0
  54. {kernel-0.48.0 → kernel-0.50.0}/src/kernel/_utils/_datetime_parse.py +0 -0
  55. {kernel-0.48.0 → kernel-0.50.0}/src/kernel/_utils/_json.py +0 -0
  56. {kernel-0.48.0 → kernel-0.50.0}/src/kernel/_utils/_logs.py +0 -0
  57. {kernel-0.48.0 → kernel-0.50.0}/src/kernel/_utils/_path.py +0 -0
  58. {kernel-0.48.0 → kernel-0.50.0}/src/kernel/_utils/_proxy.py +0 -0
  59. {kernel-0.48.0 → kernel-0.50.0}/src/kernel/_utils/_reflection.py +0 -0
  60. {kernel-0.48.0 → kernel-0.50.0}/src/kernel/_utils/_resources_proxy.py +0 -0
  61. {kernel-0.48.0 → kernel-0.50.0}/src/kernel/_utils/_streams.py +0 -0
  62. {kernel-0.48.0 → kernel-0.50.0}/src/kernel/_utils/_sync.py +0 -0
  63. {kernel-0.48.0 → kernel-0.50.0}/src/kernel/_utils/_transform.py +0 -0
  64. {kernel-0.48.0 → kernel-0.50.0}/src/kernel/_utils/_typing.py +0 -0
  65. {kernel-0.48.0 → kernel-0.50.0}/src/kernel/app_framework.py +0 -0
  66. {kernel-0.48.0 → kernel-0.50.0}/src/kernel/lib/.keep +0 -0
  67. {kernel-0.48.0 → kernel-0.50.0}/src/kernel/pagination.py +0 -0
  68. {kernel-0.48.0 → kernel-0.50.0}/src/kernel/py.typed +0 -0
  69. {kernel-0.48.0 → kernel-0.50.0}/src/kernel/resources/__init__.py +0 -0
  70. {kernel-0.48.0 → kernel-0.50.0}/src/kernel/resources/apps.py +0 -0
  71. {kernel-0.48.0 → kernel-0.50.0}/src/kernel/resources/auth/__init__.py +0 -0
  72. {kernel-0.48.0 → kernel-0.50.0}/src/kernel/resources/auth/auth.py +0 -0
  73. {kernel-0.48.0 → kernel-0.50.0}/src/kernel/resources/auth/connections.py +0 -0
  74. {kernel-0.48.0 → kernel-0.50.0}/src/kernel/resources/browser_pools.py +0 -0
  75. {kernel-0.48.0 → kernel-0.50.0}/src/kernel/resources/browsers/__init__.py +0 -0
  76. {kernel-0.48.0 → kernel-0.50.0}/src/kernel/resources/browsers/computer.py +0 -0
  77. {kernel-0.48.0 → kernel-0.50.0}/src/kernel/resources/browsers/fs/__init__.py +0 -0
  78. {kernel-0.48.0 → kernel-0.50.0}/src/kernel/resources/browsers/fs/watch.py +0 -0
  79. {kernel-0.48.0 → kernel-0.50.0}/src/kernel/resources/browsers/logs.py +0 -0
  80. {kernel-0.48.0 → kernel-0.50.0}/src/kernel/resources/browsers/playwright.py +0 -0
  81. {kernel-0.48.0 → kernel-0.50.0}/src/kernel/resources/browsers/process.py +0 -0
  82. {kernel-0.48.0 → kernel-0.50.0}/src/kernel/resources/credential_providers.py +0 -0
  83. {kernel-0.48.0 → kernel-0.50.0}/src/kernel/resources/credentials.py +0 -0
  84. {kernel-0.48.0 → kernel-0.50.0}/src/kernel/resources/invocations.py +0 -0
  85. {kernel-0.48.0 → kernel-0.50.0}/src/kernel/resources/profiles.py +0 -0
  86. {kernel-0.48.0 → kernel-0.50.0}/src/kernel/resources/projects/__init__.py +0 -0
  87. {kernel-0.48.0 → kernel-0.50.0}/src/kernel/resources/projects/limits.py +0 -0
  88. {kernel-0.48.0 → kernel-0.50.0}/src/kernel/resources/proxies.py +0 -0
  89. {kernel-0.48.0 → kernel-0.50.0}/src/kernel/types/app_list_params.py +0 -0
  90. {kernel-0.48.0 → kernel-0.50.0}/src/kernel/types/app_list_response.py +0 -0
  91. {kernel-0.48.0 → kernel-0.50.0}/src/kernel/types/auth/__init__.py +0 -0
  92. {kernel-0.48.0 → kernel-0.50.0}/src/kernel/types/auth/connection_create_params.py +0 -0
  93. {kernel-0.48.0 → kernel-0.50.0}/src/kernel/types/auth/connection_list_params.py +0 -0
  94. {kernel-0.48.0 → kernel-0.50.0}/src/kernel/types/auth/connection_login_params.py +0 -0
  95. {kernel-0.48.0 → kernel-0.50.0}/src/kernel/types/auth/connection_submit_params.py +0 -0
  96. {kernel-0.48.0 → kernel-0.50.0}/src/kernel/types/auth/connection_update_params.py +0 -0
  97. {kernel-0.48.0 → kernel-0.50.0}/src/kernel/types/auth/login_response.py +0 -0
  98. {kernel-0.48.0 → kernel-0.50.0}/src/kernel/types/auth/submit_fields_response.py +0 -0
  99. {kernel-0.48.0 → kernel-0.50.0}/src/kernel/types/browser_create_params.py +0 -0
  100. {kernel-0.48.0 → kernel-0.50.0}/src/kernel/types/browser_create_response.py +0 -0
  101. {kernel-0.48.0 → kernel-0.50.0}/src/kernel/types/browser_delete_params.py +0 -0
  102. {kernel-0.48.0 → kernel-0.50.0}/src/kernel/types/browser_list_response.py +0 -0
  103. {kernel-0.48.0 → kernel-0.50.0}/src/kernel/types/browser_load_extensions_params.py +0 -0
  104. {kernel-0.48.0 → kernel-0.50.0}/src/kernel/types/browser_persistence.py +0 -0
  105. {kernel-0.48.0 → kernel-0.50.0}/src/kernel/types/browser_persistence_param.py +0 -0
  106. {kernel-0.48.0 → kernel-0.50.0}/src/kernel/types/browser_pool.py +0 -0
  107. {kernel-0.48.0 → kernel-0.50.0}/src/kernel/types/browser_pool_acquire_params.py +0 -0
  108. {kernel-0.48.0 → kernel-0.50.0}/src/kernel/types/browser_pool_acquire_response.py +0 -0
  109. {kernel-0.48.0 → kernel-0.50.0}/src/kernel/types/browser_pool_create_params.py +0 -0
  110. {kernel-0.48.0 → kernel-0.50.0}/src/kernel/types/browser_pool_delete_params.py +0 -0
  111. {kernel-0.48.0 → kernel-0.50.0}/src/kernel/types/browser_pool_list_response.py +0 -0
  112. {kernel-0.48.0 → kernel-0.50.0}/src/kernel/types/browser_pool_ref.py +0 -0
  113. {kernel-0.48.0 → kernel-0.50.0}/src/kernel/types/browser_pool_release_params.py +0 -0
  114. {kernel-0.48.0 → kernel-0.50.0}/src/kernel/types/browser_pool_update_params.py +0 -0
  115. {kernel-0.48.0 → kernel-0.50.0}/src/kernel/types/browser_retrieve_params.py +0 -0
  116. {kernel-0.48.0 → kernel-0.50.0}/src/kernel/types/browser_retrieve_response.py +0 -0
  117. {kernel-0.48.0 → kernel-0.50.0}/src/kernel/types/browser_update_params.py +0 -0
  118. {kernel-0.48.0 → kernel-0.50.0}/src/kernel/types/browser_update_response.py +0 -0
  119. {kernel-0.48.0 → kernel-0.50.0}/src/kernel/types/browser_usage.py +0 -0
  120. {kernel-0.48.0 → kernel-0.50.0}/src/kernel/types/browsers/__init__.py +0 -0
  121. {kernel-0.48.0 → kernel-0.50.0}/src/kernel/types/browsers/computer_batch_params.py +0 -0
  122. {kernel-0.48.0 → kernel-0.50.0}/src/kernel/types/browsers/computer_capture_screenshot_params.py +0 -0
  123. {kernel-0.48.0 → kernel-0.50.0}/src/kernel/types/browsers/computer_click_mouse_params.py +0 -0
  124. {kernel-0.48.0 → kernel-0.50.0}/src/kernel/types/browsers/computer_drag_mouse_params.py +0 -0
  125. {kernel-0.48.0 → kernel-0.50.0}/src/kernel/types/browsers/computer_get_mouse_position_response.py +0 -0
  126. {kernel-0.48.0 → kernel-0.50.0}/src/kernel/types/browsers/computer_move_mouse_params.py +0 -0
  127. {kernel-0.48.0 → kernel-0.50.0}/src/kernel/types/browsers/computer_press_key_params.py +0 -0
  128. {kernel-0.48.0 → kernel-0.50.0}/src/kernel/types/browsers/computer_read_clipboard_response.py +0 -0
  129. {kernel-0.48.0 → kernel-0.50.0}/src/kernel/types/browsers/computer_scroll_params.py +0 -0
  130. {kernel-0.48.0 → kernel-0.50.0}/src/kernel/types/browsers/computer_set_cursor_visibility_params.py +0 -0
  131. {kernel-0.48.0 → kernel-0.50.0}/src/kernel/types/browsers/computer_set_cursor_visibility_response.py +0 -0
  132. {kernel-0.48.0 → kernel-0.50.0}/src/kernel/types/browsers/computer_type_text_params.py +0 -0
  133. {kernel-0.48.0 → kernel-0.50.0}/src/kernel/types/browsers/computer_write_clipboard_params.py +0 -0
  134. {kernel-0.48.0 → kernel-0.50.0}/src/kernel/types/browsers/f_create_directory_params.py +0 -0
  135. {kernel-0.48.0 → kernel-0.50.0}/src/kernel/types/browsers/f_delete_directory_params.py +0 -0
  136. {kernel-0.48.0 → kernel-0.50.0}/src/kernel/types/browsers/f_delete_file_params.py +0 -0
  137. {kernel-0.48.0 → kernel-0.50.0}/src/kernel/types/browsers/f_download_dir_zip_params.py +0 -0
  138. {kernel-0.48.0 → kernel-0.50.0}/src/kernel/types/browsers/f_file_info_params.py +0 -0
  139. {kernel-0.48.0 → kernel-0.50.0}/src/kernel/types/browsers/f_file_info_response.py +0 -0
  140. {kernel-0.48.0 → kernel-0.50.0}/src/kernel/types/browsers/f_list_files_params.py +0 -0
  141. {kernel-0.48.0 → kernel-0.50.0}/src/kernel/types/browsers/f_list_files_response.py +0 -0
  142. {kernel-0.48.0 → kernel-0.50.0}/src/kernel/types/browsers/f_move_params.py +0 -0
  143. {kernel-0.48.0 → kernel-0.50.0}/src/kernel/types/browsers/f_read_file_params.py +0 -0
  144. {kernel-0.48.0 → kernel-0.50.0}/src/kernel/types/browsers/f_set_file_permissions_params.py +0 -0
  145. {kernel-0.48.0 → kernel-0.50.0}/src/kernel/types/browsers/f_upload_params.py +0 -0
  146. {kernel-0.48.0 → kernel-0.50.0}/src/kernel/types/browsers/f_upload_zip_params.py +0 -0
  147. {kernel-0.48.0 → kernel-0.50.0}/src/kernel/types/browsers/f_write_file_params.py +0 -0
  148. {kernel-0.48.0 → kernel-0.50.0}/src/kernel/types/browsers/fs/__init__.py +0 -0
  149. {kernel-0.48.0 → kernel-0.50.0}/src/kernel/types/browsers/fs/watch_events_response.py +0 -0
  150. {kernel-0.48.0 → kernel-0.50.0}/src/kernel/types/browsers/fs/watch_start_params.py +0 -0
  151. {kernel-0.48.0 → kernel-0.50.0}/src/kernel/types/browsers/fs/watch_start_response.py +0 -0
  152. {kernel-0.48.0 → kernel-0.50.0}/src/kernel/types/browsers/log_stream_params.py +0 -0
  153. {kernel-0.48.0 → kernel-0.50.0}/src/kernel/types/browsers/playwright_execute_params.py +0 -0
  154. {kernel-0.48.0 → kernel-0.50.0}/src/kernel/types/browsers/playwright_execute_response.py +0 -0
  155. {kernel-0.48.0 → kernel-0.50.0}/src/kernel/types/browsers/process_exec_params.py +0 -0
  156. {kernel-0.48.0 → kernel-0.50.0}/src/kernel/types/browsers/process_exec_response.py +0 -0
  157. {kernel-0.48.0 → kernel-0.50.0}/src/kernel/types/browsers/process_kill_params.py +0 -0
  158. {kernel-0.48.0 → kernel-0.50.0}/src/kernel/types/browsers/process_kill_response.py +0 -0
  159. {kernel-0.48.0 → kernel-0.50.0}/src/kernel/types/browsers/process_resize_params.py +0 -0
  160. {kernel-0.48.0 → kernel-0.50.0}/src/kernel/types/browsers/process_resize_response.py +0 -0
  161. {kernel-0.48.0 → kernel-0.50.0}/src/kernel/types/browsers/process_spawn_params.py +0 -0
  162. {kernel-0.48.0 → kernel-0.50.0}/src/kernel/types/browsers/process_spawn_response.py +0 -0
  163. {kernel-0.48.0 → kernel-0.50.0}/src/kernel/types/browsers/process_status_response.py +0 -0
  164. {kernel-0.48.0 → kernel-0.50.0}/src/kernel/types/browsers/process_stdin_params.py +0 -0
  165. {kernel-0.48.0 → kernel-0.50.0}/src/kernel/types/browsers/process_stdin_response.py +0 -0
  166. {kernel-0.48.0 → kernel-0.50.0}/src/kernel/types/browsers/process_stdout_stream_response.py +0 -0
  167. {kernel-0.48.0 → kernel-0.50.0}/src/kernel/types/browsers/replay_list_response.py +0 -0
  168. {kernel-0.48.0 → kernel-0.50.0}/src/kernel/types/browsers/replay_start_response.py +0 -0
  169. {kernel-0.48.0 → kernel-0.50.0}/src/kernel/types/credential.py +0 -0
  170. {kernel-0.48.0 → kernel-0.50.0}/src/kernel/types/credential_create_params.py +0 -0
  171. {kernel-0.48.0 → kernel-0.50.0}/src/kernel/types/credential_list_params.py +0 -0
  172. {kernel-0.48.0 → kernel-0.50.0}/src/kernel/types/credential_provider.py +0 -0
  173. {kernel-0.48.0 → kernel-0.50.0}/src/kernel/types/credential_provider_create_params.py +0 -0
  174. {kernel-0.48.0 → kernel-0.50.0}/src/kernel/types/credential_provider_item.py +0 -0
  175. {kernel-0.48.0 → kernel-0.50.0}/src/kernel/types/credential_provider_list_items_response.py +0 -0
  176. {kernel-0.48.0 → kernel-0.50.0}/src/kernel/types/credential_provider_list_response.py +0 -0
  177. {kernel-0.48.0 → kernel-0.50.0}/src/kernel/types/credential_provider_test_result.py +0 -0
  178. {kernel-0.48.0 → kernel-0.50.0}/src/kernel/types/credential_provider_update_params.py +0 -0
  179. {kernel-0.48.0 → kernel-0.50.0}/src/kernel/types/credential_totp_code_response.py +0 -0
  180. {kernel-0.48.0 → kernel-0.50.0}/src/kernel/types/credential_update_params.py +0 -0
  181. {kernel-0.48.0 → kernel-0.50.0}/src/kernel/types/deployment_create_params.py +0 -0
  182. {kernel-0.48.0 → kernel-0.50.0}/src/kernel/types/deployment_create_response.py +0 -0
  183. {kernel-0.48.0 → kernel-0.50.0}/src/kernel/types/deployment_follow_params.py +0 -0
  184. {kernel-0.48.0 → kernel-0.50.0}/src/kernel/types/deployment_follow_response.py +0 -0
  185. {kernel-0.48.0 → kernel-0.50.0}/src/kernel/types/deployment_list_params.py +0 -0
  186. {kernel-0.48.0 → kernel-0.50.0}/src/kernel/types/deployment_list_response.py +0 -0
  187. {kernel-0.48.0 → kernel-0.50.0}/src/kernel/types/deployment_retrieve_response.py +0 -0
  188. {kernel-0.48.0 → kernel-0.50.0}/src/kernel/types/deployment_state_event.py +0 -0
  189. {kernel-0.48.0 → kernel-0.50.0}/src/kernel/types/extension_download_from_chrome_store_params.py +0 -0
  190. {kernel-0.48.0 → kernel-0.50.0}/src/kernel/types/extension_list_response.py +0 -0
  191. {kernel-0.48.0 → kernel-0.50.0}/src/kernel/types/extension_upload_params.py +0 -0
  192. {kernel-0.48.0 → kernel-0.50.0}/src/kernel/types/extension_upload_response.py +0 -0
  193. {kernel-0.48.0 → kernel-0.50.0}/src/kernel/types/invocation_create_params.py +0 -0
  194. {kernel-0.48.0 → kernel-0.50.0}/src/kernel/types/invocation_create_response.py +0 -0
  195. {kernel-0.48.0 → kernel-0.50.0}/src/kernel/types/invocation_follow_params.py +0 -0
  196. {kernel-0.48.0 → kernel-0.50.0}/src/kernel/types/invocation_follow_response.py +0 -0
  197. {kernel-0.48.0 → kernel-0.50.0}/src/kernel/types/invocation_list_browsers_response.py +0 -0
  198. {kernel-0.48.0 → kernel-0.50.0}/src/kernel/types/invocation_list_params.py +0 -0
  199. {kernel-0.48.0 → kernel-0.50.0}/src/kernel/types/invocation_list_response.py +0 -0
  200. {kernel-0.48.0 → kernel-0.50.0}/src/kernel/types/invocation_retrieve_response.py +0 -0
  201. {kernel-0.48.0 → kernel-0.50.0}/src/kernel/types/invocation_state_event.py +0 -0
  202. {kernel-0.48.0 → kernel-0.50.0}/src/kernel/types/invocation_update_params.py +0 -0
  203. {kernel-0.48.0 → kernel-0.50.0}/src/kernel/types/invocation_update_response.py +0 -0
  204. {kernel-0.48.0 → kernel-0.50.0}/src/kernel/types/profile.py +0 -0
  205. {kernel-0.48.0 → kernel-0.50.0}/src/kernel/types/profile_create_params.py +0 -0
  206. {kernel-0.48.0 → kernel-0.50.0}/src/kernel/types/profile_list_params.py +0 -0
  207. {kernel-0.48.0 → kernel-0.50.0}/src/kernel/types/project.py +0 -0
  208. {kernel-0.48.0 → kernel-0.50.0}/src/kernel/types/project_create_params.py +0 -0
  209. {kernel-0.48.0 → kernel-0.50.0}/src/kernel/types/project_list_params.py +0 -0
  210. {kernel-0.48.0 → kernel-0.50.0}/src/kernel/types/project_update_params.py +0 -0
  211. {kernel-0.48.0 → kernel-0.50.0}/src/kernel/types/projects/__init__.py +0 -0
  212. {kernel-0.48.0 → kernel-0.50.0}/src/kernel/types/projects/limit_update_params.py +0 -0
  213. {kernel-0.48.0 → kernel-0.50.0}/src/kernel/types/projects/project_limits.py +0 -0
  214. {kernel-0.48.0 → kernel-0.50.0}/src/kernel/types/proxy_check_params.py +0 -0
  215. {kernel-0.48.0 → kernel-0.50.0}/src/kernel/types/proxy_check_response.py +0 -0
  216. {kernel-0.48.0 → kernel-0.50.0}/src/kernel/types/proxy_create_params.py +0 -0
  217. {kernel-0.48.0 → kernel-0.50.0}/src/kernel/types/proxy_create_response.py +0 -0
  218. {kernel-0.48.0 → kernel-0.50.0}/src/kernel/types/proxy_list_response.py +0 -0
  219. {kernel-0.48.0 → kernel-0.50.0}/src/kernel/types/proxy_retrieve_response.py +0 -0
  220. {kernel-0.48.0 → kernel-0.50.0}/src/kernel/types/shared/__init__.py +0 -0
  221. {kernel-0.48.0 → kernel-0.50.0}/src/kernel/types/shared/app_action.py +0 -0
  222. {kernel-0.48.0 → kernel-0.50.0}/src/kernel/types/shared/browser_extension.py +0 -0
  223. {kernel-0.48.0 → kernel-0.50.0}/src/kernel/types/shared/browser_profile.py +0 -0
  224. {kernel-0.48.0 → kernel-0.50.0}/src/kernel/types/shared/browser_viewport.py +0 -0
  225. {kernel-0.48.0 → kernel-0.50.0}/src/kernel/types/shared/error_detail.py +0 -0
  226. {kernel-0.48.0 → kernel-0.50.0}/src/kernel/types/shared/error_event.py +0 -0
  227. {kernel-0.48.0 → kernel-0.50.0}/src/kernel/types/shared/error_model.py +0 -0
  228. {kernel-0.48.0 → kernel-0.50.0}/src/kernel/types/shared/heartbeat_event.py +0 -0
  229. {kernel-0.48.0 → kernel-0.50.0}/src/kernel/types/shared/log_event.py +0 -0
  230. {kernel-0.48.0 → kernel-0.50.0}/src/kernel/types/shared_params/__init__.py +0 -0
  231. {kernel-0.48.0 → kernel-0.50.0}/src/kernel/types/shared_params/browser_extension.py +0 -0
  232. {kernel-0.48.0 → kernel-0.50.0}/src/kernel/types/shared_params/browser_profile.py +0 -0
  233. {kernel-0.48.0 → kernel-0.50.0}/src/kernel/types/shared_params/browser_viewport.py +0 -0
  234. {kernel-0.48.0 → kernel-0.50.0}/tests/__init__.py +0 -0
  235. {kernel-0.48.0 → kernel-0.50.0}/tests/api_resources/__init__.py +0 -0
  236. {kernel-0.48.0 → kernel-0.50.0}/tests/api_resources/auth/__init__.py +0 -0
  237. {kernel-0.48.0 → kernel-0.50.0}/tests/api_resources/auth/test_connections.py +0 -0
  238. {kernel-0.48.0 → kernel-0.50.0}/tests/api_resources/browsers/__init__.py +0 -0
  239. {kernel-0.48.0 → kernel-0.50.0}/tests/api_resources/browsers/fs/__init__.py +0 -0
  240. {kernel-0.48.0 → kernel-0.50.0}/tests/api_resources/browsers/fs/test_watch.py +0 -0
  241. {kernel-0.48.0 → kernel-0.50.0}/tests/api_resources/browsers/test_computer.py +0 -0
  242. {kernel-0.48.0 → kernel-0.50.0}/tests/api_resources/browsers/test_fs.py +0 -0
  243. {kernel-0.48.0 → kernel-0.50.0}/tests/api_resources/browsers/test_logs.py +0 -0
  244. {kernel-0.48.0 → kernel-0.50.0}/tests/api_resources/browsers/test_playwright.py +0 -0
  245. {kernel-0.48.0 → kernel-0.50.0}/tests/api_resources/browsers/test_process.py +0 -0
  246. {kernel-0.48.0 → kernel-0.50.0}/tests/api_resources/browsers/test_replays.py +0 -0
  247. {kernel-0.48.0 → kernel-0.50.0}/tests/api_resources/projects/__init__.py +0 -0
  248. {kernel-0.48.0 → kernel-0.50.0}/tests/api_resources/projects/test_limits.py +0 -0
  249. {kernel-0.48.0 → kernel-0.50.0}/tests/api_resources/test_apps.py +0 -0
  250. {kernel-0.48.0 → kernel-0.50.0}/tests/api_resources/test_browser_pools.py +0 -0
  251. {kernel-0.48.0 → kernel-0.50.0}/tests/api_resources/test_credential_providers.py +0 -0
  252. {kernel-0.48.0 → kernel-0.50.0}/tests/api_resources/test_credentials.py +0 -0
  253. {kernel-0.48.0 → kernel-0.50.0}/tests/api_resources/test_deployments.py +0 -0
  254. {kernel-0.48.0 → kernel-0.50.0}/tests/api_resources/test_extensions.py +0 -0
  255. {kernel-0.48.0 → kernel-0.50.0}/tests/api_resources/test_invocations.py +0 -0
  256. {kernel-0.48.0 → kernel-0.50.0}/tests/api_resources/test_profiles.py +0 -0
  257. {kernel-0.48.0 → kernel-0.50.0}/tests/api_resources/test_projects.py +0 -0
  258. {kernel-0.48.0 → kernel-0.50.0}/tests/api_resources/test_proxies.py +0 -0
  259. {kernel-0.48.0 → kernel-0.50.0}/tests/conftest.py +0 -0
  260. {kernel-0.48.0 → kernel-0.50.0}/tests/sample_file.txt +0 -0
  261. {kernel-0.48.0 → kernel-0.50.0}/tests/test_client.py +0 -0
  262. {kernel-0.48.0 → kernel-0.50.0}/tests/test_models.py +0 -0
  263. {kernel-0.48.0 → kernel-0.50.0}/tests/test_qs.py +0 -0
  264. {kernel-0.48.0 → kernel-0.50.0}/tests/test_required_args.py +0 -0
  265. {kernel-0.48.0 → kernel-0.50.0}/tests/test_response.py +0 -0
  266. {kernel-0.48.0 → kernel-0.50.0}/tests/test_streaming.py +0 -0
  267. {kernel-0.48.0 → kernel-0.50.0}/tests/test_transform.py +0 -0
  268. {kernel-0.48.0 → kernel-0.50.0}/tests/test_utils/test_datetime_parse.py +0 -0
  269. {kernel-0.48.0 → kernel-0.50.0}/tests/test_utils/test_json.py +0 -0
  270. {kernel-0.48.0 → kernel-0.50.0}/tests/test_utils/test_path.py +0 -0
  271. {kernel-0.48.0 → kernel-0.50.0}/tests/test_utils/test_proxy.py +0 -0
  272. {kernel-0.48.0 → kernel-0.50.0}/tests/test_utils/test_typing.py +0 -0
  273. {kernel-0.48.0 → kernel-0.50.0}/tests/utils.py +0 -0
@@ -0,0 +1,3 @@
1
+ {
2
+ ".": "0.50.0"
3
+ }
@@ -1,5 +1,34 @@
1
1
  # Changelog
2
2
 
3
+ ## 0.50.0 (2026-04-20)
4
+
5
+ Full Changelog: [v0.49.0...v0.50.0](https://github.com/kernel/kernel-python-sdk/compare/v0.49.0...v0.50.0)
6
+
7
+ ### Features
8
+
9
+ * add POST /browsers/{id}/curl and /curl/raw endpoints ([e91bc38](https://github.com/kernel/kernel-python-sdk/commit/e91bc387e5ef74c1b02f62e19e9ae31867296af4))
10
+ * remove paid plan gating from project endpoints ([284c2d4](https://github.com/kernel/kernel-python-sdk/commit/284c2d434be9d098efbaf33b14b416acd4c78e18))
11
+
12
+
13
+ ### Bug Fixes
14
+
15
+ * ensure file data are only sent as 1 parameter ([e566aa5](https://github.com/kernel/kernel-python-sdk/commit/e566aa50a9022d5b284c6334b3704df2a96643cc))
16
+ * include MFA and sign-in options in CUA SSO-only step response ([ea9576b](https://github.com/kernel/kernel-python-sdk/commit/ea9576b87a17b903f880ab8d14379b8ca5fe53d5))
17
+
18
+
19
+ ### Performance Improvements
20
+
21
+ * **client:** optimize file structure copying in multipart requests ([d46c711](https://github.com/kernel/kernel-python-sdk/commit/d46c711588904a9e249a0e852a790c3431d12aa1))
22
+
23
+ ## 0.49.0 (2026-04-10)
24
+
25
+ Full Changelog: [v0.48.0...v0.49.0](https://github.com/kernel/kernel-python-sdk/compare/v0.48.0...v0.49.0)
26
+
27
+ ### Features
28
+
29
+ * Neil/kernel 1180 fuzzy matching for browser pools ([4089baf](https://github.com/kernel/kernel-python-sdk/commit/4089bafcec6fe6029b0b3730767e7428e2ab6e07))
30
+ * Raise replay framerate limit from 20 to 60 fps ([707b339](https://github.com/kernel/kernel-python-sdk/commit/707b3398f435ebaf1a801e6310e2c827b1766e82))
31
+
3
32
  ## 0.48.0 (2026-04-10)
4
33
 
5
34
  Full Changelog: [v0.47.0...v0.48.0](https://github.com/kernel/kernel-python-sdk/compare/v0.47.0...v0.48.0)
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: kernel
3
- Version: 0.48.0
3
+ Version: 0.50.0
4
4
  Summary: The official Python library for the kernel API
5
5
  Project-URL: Homepage, https://github.com/kernel/kernel-python-sdk
6
6
  Project-URL: Repository, https://github.com/kernel/kernel-python-sdk
@@ -88,6 +88,7 @@ from kernel.types import (
88
88
  BrowserRetrieveResponse,
89
89
  BrowserUpdateResponse,
90
90
  BrowserListResponse,
91
+ BrowserCurlResponse,
91
92
  )
92
93
  ```
93
94
 
@@ -98,6 +99,7 @@ Methods:
98
99
  - <code title="patch /browsers/{id}">client.browsers.<a href="./src/kernel/resources/browsers/browsers.py">update</a>(id, \*\*<a href="src/kernel/types/browser_update_params.py">params</a>) -> <a href="./src/kernel/types/browser_update_response.py">BrowserUpdateResponse</a></code>
99
100
  - <code title="get /browsers">client.browsers.<a href="./src/kernel/resources/browsers/browsers.py">list</a>(\*\*<a href="src/kernel/types/browser_list_params.py">params</a>) -> <a href="./src/kernel/types/browser_list_response.py">SyncOffsetPagination[BrowserListResponse]</a></code>
100
101
  - <code title="delete /browsers">client.browsers.<a href="./src/kernel/resources/browsers/browsers.py">delete</a>(\*\*<a href="src/kernel/types/browser_delete_params.py">params</a>) -> None</code>
102
+ - <code title="post /browsers/{id}/curl">client.browsers.<a href="./src/kernel/resources/browsers/browsers.py">curl</a>(id, \*\*<a href="src/kernel/types/browser_curl_params.py">params</a>) -> <a href="./src/kernel/types/browser_curl_response.py">BrowserCurlResponse</a></code>
101
103
  - <code title="delete /browsers/{id}">client.browsers.<a href="./src/kernel/resources/browsers/browsers.py">delete_by_id</a>(id) -> None</code>
102
104
  - <code title="post /browsers/{id}/extensions">client.browsers.<a href="./src/kernel/resources/browsers/browsers.py">load_extensions</a>(id, \*\*<a href="src/kernel/types/browser_load_extensions_params.py">params</a>) -> None</code>
103
105
 
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "kernel"
3
- version = "0.48.0"
3
+ version = "0.50.0"
4
4
  description = "The official Python library for the kernel API"
5
5
  dynamic = ["readme"]
6
6
  license = "Apache-2.0"
@@ -3,8 +3,8 @@ from __future__ import annotations
3
3
  import io
4
4
  import os
5
5
  import pathlib
6
- from typing import overload
7
- from typing_extensions import TypeGuard
6
+ from typing import Sequence, cast, overload
7
+ from typing_extensions import TypeVar, TypeGuard
8
8
 
9
9
  import anyio
10
10
 
@@ -17,7 +17,9 @@ from ._types import (
17
17
  HttpxFileContent,
18
18
  HttpxRequestFiles,
19
19
  )
20
- from ._utils import is_tuple_t, is_mapping_t, is_sequence_t
20
+ from ._utils import is_list, is_mapping, is_tuple_t, is_mapping_t, is_sequence_t
21
+
22
+ _T = TypeVar("_T")
21
23
 
22
24
 
23
25
  def is_base64_file_input(obj: object) -> TypeGuard[Base64FileInput]:
@@ -121,3 +123,51 @@ async def async_read_file_content(file: FileContent) -> HttpxFileContent:
121
123
  return await anyio.Path(file).read_bytes()
122
124
 
123
125
  return file
126
+
127
+
128
+ def deepcopy_with_paths(item: _T, paths: Sequence[Sequence[str]]) -> _T:
129
+ """Copy only the containers along the given paths.
130
+
131
+ Used to guard against mutation by extract_files without copying the entire structure.
132
+ Only dicts and lists that lie on a path are copied; everything else
133
+ is returned by reference.
134
+
135
+ For example, given paths=[["foo", "files", "file"]] and the structure:
136
+ {
137
+ "foo": {
138
+ "bar": {"baz": {}},
139
+ "files": {"file": <content>}
140
+ }
141
+ }
142
+ The root dict, "foo", and "files" are copied (they lie on the path).
143
+ "bar" and "baz" are returned by reference (off the path).
144
+ """
145
+ return _deepcopy_with_paths(item, paths, 0)
146
+
147
+
148
+ def _deepcopy_with_paths(item: _T, paths: Sequence[Sequence[str]], index: int) -> _T:
149
+ if not paths:
150
+ return item
151
+ if is_mapping(item):
152
+ key_to_paths: dict[str, list[Sequence[str]]] = {}
153
+ for path in paths:
154
+ if index < len(path):
155
+ key_to_paths.setdefault(path[index], []).append(path)
156
+
157
+ # if no path continues through this mapping, it won't be mutated and copying it is redundant
158
+ if not key_to_paths:
159
+ return item
160
+
161
+ result = dict(item)
162
+ for key, subpaths in key_to_paths.items():
163
+ if key in result:
164
+ result[key] = _deepcopy_with_paths(result[key], subpaths, index + 1)
165
+ return cast(_T, result)
166
+ if is_list(item):
167
+ array_paths = [path for path in paths if index < len(path) and path[index] == "<array>"]
168
+
169
+ # if no path expects a list here, nothing will be mutated inside it - return by reference
170
+ if not array_paths:
171
+ return cast(_T, item)
172
+ return cast(_T, [_deepcopy_with_paths(entry, array_paths, index + 1) for entry in item])
173
+ return item
@@ -24,7 +24,6 @@ from ._utils import (
24
24
  coerce_integer as coerce_integer,
25
25
  file_from_path as file_from_path,
26
26
  strip_not_given as strip_not_given,
27
- deepcopy_minimal as deepcopy_minimal,
28
27
  get_async_library as get_async_library,
29
28
  maybe_coerce_float as maybe_coerce_float,
30
29
  get_required_header as get_required_header,
@@ -86,8 +86,9 @@ def _extract_items(
86
86
  index += 1
87
87
  if is_dict(obj):
88
88
  try:
89
- # We are at the last entry in the path so we must remove the field
90
- if (len(path)) == index:
89
+ # Remove the field if there are no more dict keys in the path,
90
+ # only "<array>" traversal markers or end.
91
+ if all(p == "<array>" for p in path[index:]):
91
92
  item = obj.pop(key)
92
93
  else:
93
94
  item = obj[key]
@@ -176,21 +177,6 @@ def is_iterable(obj: object) -> TypeGuard[Iterable[object]]:
176
177
  return isinstance(obj, Iterable)
177
178
 
178
179
 
179
- def deepcopy_minimal(item: _T) -> _T:
180
- """Minimal reimplementation of copy.deepcopy() that will only copy certain object types:
181
-
182
- - mappings, e.g. `dict`
183
- - list
184
-
185
- This is done for performance reasons.
186
- """
187
- if is_mapping(item):
188
- return cast(_T, {k: deepcopy_minimal(v) for k, v in item.items()})
189
- if is_list(item):
190
- return cast(_T, [deepcopy_minimal(entry) for entry in item])
191
- return item
192
-
193
-
194
180
  # copied from https://github.com/Rapptz/RoboDanny
195
181
  def human_join(seq: Sequence[str], *, delim: str = ", ", final: str = "or") -> str:
196
182
  size = len(seq)
@@ -1,4 +1,4 @@
1
1
  # File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
2
2
 
3
3
  __title__ = "kernel"
4
- __version__ = "0.48.0" # x-release-please-version
4
+ __version__ = "0.50.0" # x-release-please-version
@@ -3,7 +3,7 @@
3
3
  from __future__ import annotations
4
4
 
5
5
  import typing_extensions
6
- from typing import Mapping, Iterable, Optional, cast
6
+ from typing import Dict, Mapping, Iterable, Optional, cast
7
7
  from typing_extensions import Literal
8
8
 
9
9
  import httpx
@@ -25,6 +25,7 @@ from .fs.fs import (
25
25
  AsyncFsResourceWithStreamingResponse,
26
26
  )
27
27
  from ...types import (
28
+ browser_curl_params,
28
29
  browser_list_params,
29
30
  browser_create_params,
30
31
  browser_delete_params,
@@ -48,8 +49,9 @@ from .replays import (
48
49
  ReplaysResourceWithStreamingResponse,
49
50
  AsyncReplaysResourceWithStreamingResponse,
50
51
  )
52
+ from ..._files import deepcopy_with_paths
51
53
  from ..._types import Body, Omit, Query, Headers, NoneType, NotGiven, omit, not_given
52
- from ..._utils import extract_files, path_template, maybe_transform, deepcopy_minimal, async_maybe_transform
54
+ from ..._utils import extract_files, path_template, maybe_transform, async_maybe_transform
53
55
  from .computer import (
54
56
  ComputerResource,
55
57
  AsyncComputerResource,
@@ -76,6 +78,7 @@ from ..._response import (
76
78
  )
77
79
  from ...pagination import SyncOffsetPagination, AsyncOffsetPagination
78
80
  from ..._base_client import AsyncPaginator, make_request_options
81
+ from ...types.browser_curl_response import BrowserCurlResponse
79
82
  from ...types.browser_list_response import BrowserListResponse
80
83
  from ...types.browser_create_response import BrowserCreateResponse
81
84
  from ...types.browser_update_response import BrowserUpdateResponse
@@ -367,7 +370,7 @@ class BrowsersResource(SyncAPIResource):
367
370
 
368
371
  offset: Number of results to skip. Defaults to 0.
369
372
 
370
- query: Search browsers by session ID, profile ID, or proxy ID.
373
+ query: Search browsers by session ID, profile ID, proxy ID, or pool name.
371
374
 
372
375
  status: Filter sessions by status. "active" returns only active sessions (default),
373
376
  "deleted" returns only soft-deleted sessions, "all" returns both.
@@ -443,6 +446,70 @@ class BrowsersResource(SyncAPIResource):
443
446
  cast_to=NoneType,
444
447
  )
445
448
 
449
+ def curl(
450
+ self,
451
+ id: str,
452
+ *,
453
+ url: str,
454
+ body: str | Omit = omit,
455
+ headers: Dict[str, str] | Omit = omit,
456
+ method: Literal["GET", "HEAD", "POST", "PUT", "PATCH", "DELETE", "OPTIONS"] | Omit = omit,
457
+ response_encoding: Literal["utf8", "base64"] | Omit = omit,
458
+ timeout_ms: int | Omit = omit,
459
+ # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
460
+ # The extra values given here take precedence over values defined on the client or passed to this method.
461
+ extra_headers: Headers | None = None,
462
+ extra_query: Query | None = None,
463
+ extra_body: Body | None = None,
464
+ timeout: float | httpx.Timeout | None | NotGiven = not_given,
465
+ ) -> BrowserCurlResponse:
466
+ """
467
+ Sends an HTTP request through Chrome's HTTP request stack, inheriting the
468
+ browser's TLS fingerprint, cookies, proxy configuration, and headers. Returns a
469
+ structured JSON response with status, headers, body, and timing.
470
+
471
+ Args:
472
+ url: Target URL (must be http or https).
473
+
474
+ body: Request body (for POST/PUT/PATCH).
475
+
476
+ headers: Custom headers merged with browser defaults.
477
+
478
+ method: HTTP method.
479
+
480
+ response_encoding: Encoding for the response body. Use base64 for binary content.
481
+
482
+ timeout_ms: Request timeout in milliseconds.
483
+
484
+ extra_headers: Send extra headers
485
+
486
+ extra_query: Add additional query parameters to the request
487
+
488
+ extra_body: Add additional JSON properties to the request
489
+
490
+ timeout: Override the client-level default timeout for this request, in seconds
491
+ """
492
+ if not id:
493
+ raise ValueError(f"Expected a non-empty value for `id` but received {id!r}")
494
+ return self._post(
495
+ path_template("/browsers/{id}/curl", id=id),
496
+ body=maybe_transform(
497
+ {
498
+ "url": url,
499
+ "body": body,
500
+ "headers": headers,
501
+ "method": method,
502
+ "response_encoding": response_encoding,
503
+ "timeout_ms": timeout_ms,
504
+ },
505
+ browser_curl_params.BrowserCurlParams,
506
+ ),
507
+ options=make_request_options(
508
+ extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
509
+ ),
510
+ cast_to=BrowserCurlResponse,
511
+ )
512
+
446
513
  def delete_by_id(
447
514
  self,
448
515
  id: str,
@@ -507,7 +574,7 @@ class BrowsersResource(SyncAPIResource):
507
574
  if not id:
508
575
  raise ValueError(f"Expected a non-empty value for `id` but received {id!r}")
509
576
  extra_headers = {"Accept": "*/*", **(extra_headers or {})}
510
- body = deepcopy_minimal({"extensions": extensions})
577
+ body = deepcopy_with_paths({"extensions": extensions}, [["extensions", "<array>", "zip_file"]])
511
578
  files = extract_files(cast(Mapping[str, object], body), paths=[["extensions", "<array>", "zip_file"]])
512
579
  # It should be noted that the actual Content-Type header that will be
513
580
  # sent to the server will contain a `boundary` parameter, e.g.
@@ -803,7 +870,7 @@ class AsyncBrowsersResource(AsyncAPIResource):
803
870
 
804
871
  offset: Number of results to skip. Defaults to 0.
805
872
 
806
- query: Search browsers by session ID, profile ID, or proxy ID.
873
+ query: Search browsers by session ID, profile ID, proxy ID, or pool name.
807
874
 
808
875
  status: Filter sessions by status. "active" returns only active sessions (default),
809
876
  "deleted" returns only soft-deleted sessions, "all" returns both.
@@ -881,6 +948,70 @@ class AsyncBrowsersResource(AsyncAPIResource):
881
948
  cast_to=NoneType,
882
949
  )
883
950
 
951
+ async def curl(
952
+ self,
953
+ id: str,
954
+ *,
955
+ url: str,
956
+ body: str | Omit = omit,
957
+ headers: Dict[str, str] | Omit = omit,
958
+ method: Literal["GET", "HEAD", "POST", "PUT", "PATCH", "DELETE", "OPTIONS"] | Omit = omit,
959
+ response_encoding: Literal["utf8", "base64"] | Omit = omit,
960
+ timeout_ms: int | Omit = omit,
961
+ # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
962
+ # The extra values given here take precedence over values defined on the client or passed to this method.
963
+ extra_headers: Headers | None = None,
964
+ extra_query: Query | None = None,
965
+ extra_body: Body | None = None,
966
+ timeout: float | httpx.Timeout | None | NotGiven = not_given,
967
+ ) -> BrowserCurlResponse:
968
+ """
969
+ Sends an HTTP request through Chrome's HTTP request stack, inheriting the
970
+ browser's TLS fingerprint, cookies, proxy configuration, and headers. Returns a
971
+ structured JSON response with status, headers, body, and timing.
972
+
973
+ Args:
974
+ url: Target URL (must be http or https).
975
+
976
+ body: Request body (for POST/PUT/PATCH).
977
+
978
+ headers: Custom headers merged with browser defaults.
979
+
980
+ method: HTTP method.
981
+
982
+ response_encoding: Encoding for the response body. Use base64 for binary content.
983
+
984
+ timeout_ms: Request timeout in milliseconds.
985
+
986
+ extra_headers: Send extra headers
987
+
988
+ extra_query: Add additional query parameters to the request
989
+
990
+ extra_body: Add additional JSON properties to the request
991
+
992
+ timeout: Override the client-level default timeout for this request, in seconds
993
+ """
994
+ if not id:
995
+ raise ValueError(f"Expected a non-empty value for `id` but received {id!r}")
996
+ return await self._post(
997
+ path_template("/browsers/{id}/curl", id=id),
998
+ body=await async_maybe_transform(
999
+ {
1000
+ "url": url,
1001
+ "body": body,
1002
+ "headers": headers,
1003
+ "method": method,
1004
+ "response_encoding": response_encoding,
1005
+ "timeout_ms": timeout_ms,
1006
+ },
1007
+ browser_curl_params.BrowserCurlParams,
1008
+ ),
1009
+ options=make_request_options(
1010
+ extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
1011
+ ),
1012
+ cast_to=BrowserCurlResponse,
1013
+ )
1014
+
884
1015
  async def delete_by_id(
885
1016
  self,
886
1017
  id: str,
@@ -945,7 +1076,7 @@ class AsyncBrowsersResource(AsyncAPIResource):
945
1076
  if not id:
946
1077
  raise ValueError(f"Expected a non-empty value for `id` but received {id!r}")
947
1078
  extra_headers = {"Accept": "*/*", **(extra_headers or {})}
948
- body = deepcopy_minimal({"extensions": extensions})
1079
+ body = deepcopy_with_paths({"extensions": extensions}, [["extensions", "<array>", "zip_file"]])
949
1080
  files = extract_files(cast(Mapping[str, object], body), paths=[["extensions", "<array>", "zip_file"]])
950
1081
  # It should be noted that the actual Content-Type header that will be
951
1082
  # sent to the server will contain a `boundary` parameter, e.g.
@@ -983,6 +1114,9 @@ class BrowsersResourceWithRawResponse:
983
1114
  browsers.delete, # pyright: ignore[reportDeprecated],
984
1115
  )
985
1116
  )
1117
+ self.curl = to_raw_response_wrapper(
1118
+ browsers.curl,
1119
+ )
986
1120
  self.delete_by_id = to_raw_response_wrapper(
987
1121
  browsers.delete_by_id,
988
1122
  )
@@ -1041,6 +1175,9 @@ class AsyncBrowsersResourceWithRawResponse:
1041
1175
  browsers.delete, # pyright: ignore[reportDeprecated],
1042
1176
  )
1043
1177
  )
1178
+ self.curl = async_to_raw_response_wrapper(
1179
+ browsers.curl,
1180
+ )
1044
1181
  self.delete_by_id = async_to_raw_response_wrapper(
1045
1182
  browsers.delete_by_id,
1046
1183
  )
@@ -1099,6 +1236,9 @@ class BrowsersResourceWithStreamingResponse:
1099
1236
  browsers.delete, # pyright: ignore[reportDeprecated],
1100
1237
  )
1101
1238
  )
1239
+ self.curl = to_streamed_response_wrapper(
1240
+ browsers.curl,
1241
+ )
1102
1242
  self.delete_by_id = to_streamed_response_wrapper(
1103
1243
  browsers.delete_by_id,
1104
1244
  )
@@ -1157,6 +1297,9 @@ class AsyncBrowsersResourceWithStreamingResponse:
1157
1297
  browsers.delete, # pyright: ignore[reportDeprecated],
1158
1298
  )
1159
1299
  )
1300
+ self.curl = async_to_streamed_response_wrapper(
1301
+ browsers.curl,
1302
+ )
1160
1303
  self.delete_by_id = async_to_streamed_response_wrapper(
1161
1304
  browsers.delete_by_id,
1162
1305
  )
@@ -15,7 +15,7 @@ from .watch import (
15
15
  WatchResourceWithStreamingResponse,
16
16
  AsyncWatchResourceWithStreamingResponse,
17
17
  )
18
- from ...._files import read_file_content, async_read_file_content
18
+ from ...._files import read_file_content, deepcopy_with_paths, async_read_file_content
19
19
  from ...._types import (
20
20
  Body,
21
21
  Omit,
@@ -30,7 +30,7 @@ from ...._types import (
30
30
  omit,
31
31
  not_given,
32
32
  )
33
- from ...._utils import extract_files, path_template, maybe_transform, deepcopy_minimal, async_maybe_transform
33
+ from ...._utils import extract_files, path_template, maybe_transform, async_maybe_transform
34
34
  from ...._compat import cached_property
35
35
  from ...._resource import SyncAPIResource, AsyncAPIResource
36
36
  from ...._response import (
@@ -509,7 +509,7 @@ class FsResource(SyncAPIResource):
509
509
  if not id:
510
510
  raise ValueError(f"Expected a non-empty value for `id` but received {id!r}")
511
511
  extra_headers = {"Accept": "*/*", **(extra_headers or {})}
512
- body = deepcopy_minimal({"files": files})
512
+ body = deepcopy_with_paths({"files": files}, [["files", "<array>", "file"]])
513
513
  extracted_files = extract_files(cast(Mapping[str, object], body), paths=[["files", "<array>", "file"]])
514
514
  # It should be noted that the actual Content-Type header that will be
515
515
  # sent to the server will contain a `boundary` parameter, e.g.
@@ -555,11 +555,12 @@ class FsResource(SyncAPIResource):
555
555
  if not id:
556
556
  raise ValueError(f"Expected a non-empty value for `id` but received {id!r}")
557
557
  extra_headers = {"Accept": "*/*", **(extra_headers or {})}
558
- body = deepcopy_minimal(
558
+ body = deepcopy_with_paths(
559
559
  {
560
560
  "dest_path": dest_path,
561
561
  "zip_file": zip_file,
562
- }
562
+ },
563
+ [["zip_file"]],
563
564
  )
564
565
  files = extract_files(cast(Mapping[str, object], body), paths=[["zip_file"]])
565
566
  # It should be noted that the actual Content-Type header that will be
@@ -1071,7 +1072,7 @@ class AsyncFsResource(AsyncAPIResource):
1071
1072
  if not id:
1072
1073
  raise ValueError(f"Expected a non-empty value for `id` but received {id!r}")
1073
1074
  extra_headers = {"Accept": "*/*", **(extra_headers or {})}
1074
- body = deepcopy_minimal({"files": files})
1075
+ body = deepcopy_with_paths({"files": files}, [["files", "<array>", "file"]])
1075
1076
  extracted_files = extract_files(cast(Mapping[str, object], body), paths=[["files", "<array>", "file"]])
1076
1077
  # It should be noted that the actual Content-Type header that will be
1077
1078
  # sent to the server will contain a `boundary` parameter, e.g.
@@ -1117,11 +1118,12 @@ class AsyncFsResource(AsyncAPIResource):
1117
1118
  if not id:
1118
1119
  raise ValueError(f"Expected a non-empty value for `id` but received {id!r}")
1119
1120
  extra_headers = {"Accept": "*/*", **(extra_headers or {})}
1120
- body = deepcopy_minimal(
1121
+ body = deepcopy_with_paths(
1121
1122
  {
1122
1123
  "dest_path": dest_path,
1123
1124
  "zip_file": zip_file,
1124
- }
1125
+ },
1126
+ [["zip_file"]],
1125
1127
  )
1126
1128
  files = extract_files(cast(Mapping[str, object], body), paths=[["zip_file"]])
1127
1129
  # It should be noted that the actual Content-Type header that will be
@@ -139,7 +139,8 @@ class ReplaysResource(SyncAPIResource):
139
139
  Start recording the browser session and return a replay ID.
140
140
 
141
141
  Args:
142
- framerate: Recording framerate in fps.
142
+ framerate: Recording framerate in fps. Values above 20 require GPU to be enabled on the
143
+ browser session.
143
144
 
144
145
  max_duration_in_seconds: Maximum recording duration in seconds.
145
146
 
@@ -315,7 +316,8 @@ class AsyncReplaysResource(AsyncAPIResource):
315
316
  Start recording the browser session and return a replay ID.
316
317
 
317
318
  Args:
318
- framerate: Recording framerate in fps.
319
+ framerate: Recording framerate in fps. Values above 20 require GPU to be enabled on the
320
+ browser session.
319
321
 
320
322
  max_duration_in_seconds: Maximum recording duration in seconds.
321
323
 
@@ -8,8 +8,9 @@ from typing_extensions import Literal
8
8
  import httpx
9
9
 
10
10
  from ..types import deployment_list_params, deployment_create_params, deployment_follow_params
11
+ from .._files import deepcopy_with_paths
11
12
  from .._types import Body, Omit, Query, Headers, NoneType, NotGiven, FileTypes, omit, not_given
12
- from .._utils import extract_files, path_template, maybe_transform, deepcopy_minimal, async_maybe_transform
13
+ from .._utils import extract_files, path_template, maybe_transform, async_maybe_transform
13
14
  from .._compat import cached_property
14
15
  from .._resource import SyncAPIResource, AsyncAPIResource
15
16
  from .._response import (
@@ -95,7 +96,7 @@ class DeploymentsResource(SyncAPIResource):
95
96
 
96
97
  timeout: Override the client-level default timeout for this request, in seconds
97
98
  """
98
- body = deepcopy_minimal(
99
+ body = deepcopy_with_paths(
99
100
  {
100
101
  "entrypoint_rel_path": entrypoint_rel_path,
101
102
  "env_vars": env_vars,
@@ -104,7 +105,8 @@ class DeploymentsResource(SyncAPIResource):
104
105
  "region": region,
105
106
  "source": source,
106
107
  "version": version,
107
- }
108
+ },
109
+ [["file"]],
108
110
  )
109
111
  files = extract_files(cast(Mapping[str, object], body), paths=[["file"]])
110
112
  # It should be noted that the actual Content-Type header that will be
@@ -360,7 +362,7 @@ class AsyncDeploymentsResource(AsyncAPIResource):
360
362
 
361
363
  timeout: Override the client-level default timeout for this request, in seconds
362
364
  """
363
- body = deepcopy_minimal(
365
+ body = deepcopy_with_paths(
364
366
  {
365
367
  "entrypoint_rel_path": entrypoint_rel_path,
366
368
  "env_vars": env_vars,
@@ -369,7 +371,8 @@ class AsyncDeploymentsResource(AsyncAPIResource):
369
371
  "region": region,
370
372
  "source": source,
371
373
  "version": version,
372
- }
374
+ },
375
+ [["file"]],
373
376
  )
374
377
  files = extract_files(cast(Mapping[str, object], body), paths=[["file"]])
375
378
  # It should be noted that the actual Content-Type header that will be
@@ -8,8 +8,9 @@ from typing_extensions import Literal
8
8
  import httpx
9
9
 
10
10
  from ..types import extension_upload_params, extension_download_from_chrome_store_params
11
+ from .._files import deepcopy_with_paths
11
12
  from .._types import Body, Omit, Query, Headers, NoneType, NotGiven, FileTypes, omit, not_given
12
- from .._utils import extract_files, path_template, maybe_transform, deepcopy_minimal, async_maybe_transform
13
+ from .._utils import extract_files, path_template, maybe_transform, async_maybe_transform
13
14
  from .._compat import cached_property
14
15
  from .._resource import SyncAPIResource, AsyncAPIResource
15
16
  from .._response import (
@@ -220,11 +221,12 @@ class ExtensionsResource(SyncAPIResource):
220
221
 
221
222
  timeout: Override the client-level default timeout for this request, in seconds
222
223
  """
223
- body = deepcopy_minimal(
224
+ body = deepcopy_with_paths(
224
225
  {
225
226
  "file": file,
226
227
  "name": name,
227
- }
228
+ },
229
+ [["file"]],
228
230
  )
229
231
  files = extract_files(cast(Mapping[str, object], body), paths=[["file"]])
230
232
  # It should be noted that the actual Content-Type header that will be
@@ -429,11 +431,12 @@ class AsyncExtensionsResource(AsyncAPIResource):
429
431
 
430
432
  timeout: Override the client-level default timeout for this request, in seconds
431
433
  """
432
- body = deepcopy_minimal(
434
+ body = deepcopy_with_paths(
433
435
  {
434
436
  "file": file,
435
437
  "name": name,
436
- }
438
+ },
439
+ [["file"]],
437
440
  )
438
441
  files = extract_files(cast(Mapping[str, object], body), paths=[["file"]])
439
442
  # It should be noted that the actual Content-Type header that will be
@@ -72,8 +72,8 @@ class ProjectsResource(SyncAPIResource):
72
72
  ) -> Project:
73
73
  """Create a new project within the authenticated organization.
74
74
 
75
- Requires a paid plan
76
- and the projects feature flag.
75
+ Requires the
76
+ projects feature flag.
77
77
 
78
78
  Args:
79
79
  name: Project name (1-255 characters)
@@ -297,8 +297,8 @@ class AsyncProjectsResource(AsyncAPIResource):
297
297
  ) -> Project:
298
298
  """Create a new project within the authenticated organization.
299
299
 
300
- Requires a paid plan
301
- and the projects feature flag.
300
+ Requires the
301
+ projects feature flag.
302
302
 
303
303
  Args:
304
304
  name: Project name (1-255 characters)
@@ -22,6 +22,7 @@ from .app_list_params import AppListParams as AppListParams
22
22
  from .browser_pool_ref import BrowserPoolRef as BrowserPoolRef
23
23
  from .app_list_response import AppListResponse as AppListResponse
24
24
  from .proxy_check_params import ProxyCheckParams as ProxyCheckParams
25
+ from .browser_curl_params import BrowserCurlParams as BrowserCurlParams
25
26
  from .browser_list_params import BrowserListParams as BrowserListParams
26
27
  from .browser_persistence import BrowserPersistence as BrowserPersistence
27
28
  from .credential_provider import CredentialProvider as CredentialProvider
@@ -31,6 +32,7 @@ from .proxy_create_params import ProxyCreateParams as ProxyCreateParams
31
32
  from .proxy_list_response import ProxyListResponse as ProxyListResponse
32
33
  from .proxy_check_response import ProxyCheckResponse as ProxyCheckResponse
33
34
  from .browser_create_params import BrowserCreateParams as BrowserCreateParams
35
+ from .browser_curl_response import BrowserCurlResponse as BrowserCurlResponse
34
36
  from .browser_delete_params import BrowserDeleteParams as BrowserDeleteParams
35
37
  from .browser_list_response import BrowserListResponse as BrowserListResponse
36
38
  from .browser_update_params import BrowserUpdateParams as BrowserUpdateParams