kernel 0.50.0__tar.gz → 0.52.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 (277) hide show
  1. kernel-0.52.0/.release-please-manifest.json +3 -0
  2. {kernel-0.50.0 → kernel-0.52.0}/CHANGELOG.md +71 -0
  3. {kernel-0.50.0 → kernel-0.52.0}/PKG-INFO +1 -1
  4. kernel-0.52.0/examples/browser_routing.py +26 -0
  5. {kernel-0.50.0 → kernel-0.52.0}/pyproject.toml +1 -1
  6. {kernel-0.50.0 → kernel-0.52.0}/src/kernel/_client.py +111 -2
  7. {kernel-0.50.0 → kernel-0.52.0}/src/kernel/_qs.py +2 -6
  8. {kernel-0.50.0 → kernel-0.52.0}/src/kernel/_types.py +3 -0
  9. {kernel-0.50.0 → kernel-0.52.0}/src/kernel/_utils/_utils.py +34 -8
  10. {kernel-0.50.0 → kernel-0.52.0}/src/kernel/_version.py +1 -1
  11. kernel-0.52.0/src/kernel/lib/browser_routing/__init__.py +3 -0
  12. kernel-0.52.0/src/kernel/lib/browser_routing/raw_http.py +150 -0
  13. kernel-0.52.0/src/kernel/lib/browser_routing/routing.py +243 -0
  14. kernel-0.52.0/src/kernel/lib/browser_routing/util.py +58 -0
  15. {kernel-0.50.0 → kernel-0.52.0}/src/kernel/resources/browsers/browsers.py +124 -1
  16. {kernel-0.50.0 → kernel-0.52.0}/src/kernel/resources/profiles.py +4 -8
  17. {kernel-0.50.0 → kernel-0.52.0}/src/kernel/types/auth/managed_auth.py +27 -2
  18. kernel-0.52.0/tests/test_browser_routing.py +323 -0
  19. {kernel-0.50.0 → kernel-0.52.0}/tests/test_extract_files.py +23 -5
  20. {kernel-0.50.0 → kernel-0.52.0}/tests/test_files.py +1 -1
  21. kernel-0.50.0/.release-please-manifest.json +0 -3
  22. {kernel-0.50.0 → kernel-0.52.0}/.gitignore +0 -0
  23. {kernel-0.50.0 → kernel-0.52.0}/CONTRIBUTING.md +0 -0
  24. {kernel-0.50.0 → kernel-0.52.0}/LICENSE +0 -0
  25. {kernel-0.50.0 → kernel-0.52.0}/README.md +0 -0
  26. {kernel-0.50.0 → kernel-0.52.0}/SECURITY.md +0 -0
  27. {kernel-0.50.0 → kernel-0.52.0}/api.md +0 -0
  28. {kernel-0.50.0 → kernel-0.52.0}/bin/check-release-environment +0 -0
  29. {kernel-0.50.0 → kernel-0.52.0}/bin/publish-pypi +0 -0
  30. {kernel-0.50.0 → kernel-0.52.0}/examples/.keep +0 -0
  31. {kernel-0.50.0 → kernel-0.52.0}/noxfile.py +0 -0
  32. {kernel-0.50.0 → kernel-0.52.0}/release-please-config.json +0 -0
  33. {kernel-0.50.0 → kernel-0.52.0}/requirements-dev.lock +0 -0
  34. {kernel-0.50.0 → kernel-0.52.0}/requirements.lock +0 -0
  35. {kernel-0.50.0 → kernel-0.52.0}/src/kernel/__init__.py +0 -0
  36. {kernel-0.50.0 → kernel-0.52.0}/src/kernel/_base_client.py +0 -0
  37. {kernel-0.50.0 → kernel-0.52.0}/src/kernel/_compat.py +0 -0
  38. {kernel-0.50.0 → kernel-0.52.0}/src/kernel/_constants.py +0 -0
  39. {kernel-0.50.0 → kernel-0.52.0}/src/kernel/_exceptions.py +0 -0
  40. {kernel-0.50.0 → kernel-0.52.0}/src/kernel/_files.py +0 -0
  41. {kernel-0.50.0 → kernel-0.52.0}/src/kernel/_models.py +0 -0
  42. {kernel-0.50.0 → kernel-0.52.0}/src/kernel/_resource.py +0 -0
  43. {kernel-0.50.0 → kernel-0.52.0}/src/kernel/_response.py +0 -0
  44. {kernel-0.50.0 → kernel-0.52.0}/src/kernel/_streaming.py +0 -0
  45. {kernel-0.50.0 → kernel-0.52.0}/src/kernel/_utils/__init__.py +0 -0
  46. {kernel-0.50.0 → kernel-0.52.0}/src/kernel/_utils/_compat.py +0 -0
  47. {kernel-0.50.0 → kernel-0.52.0}/src/kernel/_utils/_datetime_parse.py +0 -0
  48. {kernel-0.50.0 → kernel-0.52.0}/src/kernel/_utils/_json.py +0 -0
  49. {kernel-0.50.0 → kernel-0.52.0}/src/kernel/_utils/_logs.py +0 -0
  50. {kernel-0.50.0 → kernel-0.52.0}/src/kernel/_utils/_path.py +0 -0
  51. {kernel-0.50.0 → kernel-0.52.0}/src/kernel/_utils/_proxy.py +0 -0
  52. {kernel-0.50.0 → kernel-0.52.0}/src/kernel/_utils/_reflection.py +0 -0
  53. {kernel-0.50.0 → kernel-0.52.0}/src/kernel/_utils/_resources_proxy.py +0 -0
  54. {kernel-0.50.0 → kernel-0.52.0}/src/kernel/_utils/_streams.py +0 -0
  55. {kernel-0.50.0 → kernel-0.52.0}/src/kernel/_utils/_sync.py +0 -0
  56. {kernel-0.50.0 → kernel-0.52.0}/src/kernel/_utils/_transform.py +0 -0
  57. {kernel-0.50.0 → kernel-0.52.0}/src/kernel/_utils/_typing.py +0 -0
  58. {kernel-0.50.0 → kernel-0.52.0}/src/kernel/app_framework.py +0 -0
  59. {kernel-0.50.0 → kernel-0.52.0}/src/kernel/lib/.keep +0 -0
  60. {kernel-0.50.0 → kernel-0.52.0}/src/kernel/pagination.py +0 -0
  61. {kernel-0.50.0 → kernel-0.52.0}/src/kernel/py.typed +0 -0
  62. {kernel-0.50.0 → kernel-0.52.0}/src/kernel/resources/__init__.py +0 -0
  63. {kernel-0.50.0 → kernel-0.52.0}/src/kernel/resources/apps.py +0 -0
  64. {kernel-0.50.0 → kernel-0.52.0}/src/kernel/resources/auth/__init__.py +0 -0
  65. {kernel-0.50.0 → kernel-0.52.0}/src/kernel/resources/auth/auth.py +0 -0
  66. {kernel-0.50.0 → kernel-0.52.0}/src/kernel/resources/auth/connections.py +0 -0
  67. {kernel-0.50.0 → kernel-0.52.0}/src/kernel/resources/browser_pools.py +0 -0
  68. {kernel-0.50.0 → kernel-0.52.0}/src/kernel/resources/browsers/__init__.py +0 -0
  69. {kernel-0.50.0 → kernel-0.52.0}/src/kernel/resources/browsers/computer.py +0 -0
  70. {kernel-0.50.0 → kernel-0.52.0}/src/kernel/resources/browsers/fs/__init__.py +0 -0
  71. {kernel-0.50.0 → kernel-0.52.0}/src/kernel/resources/browsers/fs/fs.py +0 -0
  72. {kernel-0.50.0 → kernel-0.52.0}/src/kernel/resources/browsers/fs/watch.py +0 -0
  73. {kernel-0.50.0 → kernel-0.52.0}/src/kernel/resources/browsers/logs.py +0 -0
  74. {kernel-0.50.0 → kernel-0.52.0}/src/kernel/resources/browsers/playwright.py +0 -0
  75. {kernel-0.50.0 → kernel-0.52.0}/src/kernel/resources/browsers/process.py +0 -0
  76. {kernel-0.50.0 → kernel-0.52.0}/src/kernel/resources/browsers/replays.py +0 -0
  77. {kernel-0.50.0 → kernel-0.52.0}/src/kernel/resources/credential_providers.py +0 -0
  78. {kernel-0.50.0 → kernel-0.52.0}/src/kernel/resources/credentials.py +0 -0
  79. {kernel-0.50.0 → kernel-0.52.0}/src/kernel/resources/deployments.py +0 -0
  80. {kernel-0.50.0 → kernel-0.52.0}/src/kernel/resources/extensions.py +0 -0
  81. {kernel-0.50.0 → kernel-0.52.0}/src/kernel/resources/invocations.py +0 -0
  82. {kernel-0.50.0 → kernel-0.52.0}/src/kernel/resources/projects/__init__.py +0 -0
  83. {kernel-0.50.0 → kernel-0.52.0}/src/kernel/resources/projects/limits.py +0 -0
  84. {kernel-0.50.0 → kernel-0.52.0}/src/kernel/resources/projects/projects.py +0 -0
  85. {kernel-0.50.0 → kernel-0.52.0}/src/kernel/resources/proxies.py +0 -0
  86. {kernel-0.50.0 → kernel-0.52.0}/src/kernel/types/__init__.py +0 -0
  87. {kernel-0.50.0 → kernel-0.52.0}/src/kernel/types/app_list_params.py +0 -0
  88. {kernel-0.50.0 → kernel-0.52.0}/src/kernel/types/app_list_response.py +0 -0
  89. {kernel-0.50.0 → kernel-0.52.0}/src/kernel/types/auth/__init__.py +0 -0
  90. {kernel-0.50.0 → kernel-0.52.0}/src/kernel/types/auth/connection_create_params.py +0 -0
  91. {kernel-0.50.0 → kernel-0.52.0}/src/kernel/types/auth/connection_follow_response.py +0 -0
  92. {kernel-0.50.0 → kernel-0.52.0}/src/kernel/types/auth/connection_list_params.py +0 -0
  93. {kernel-0.50.0 → kernel-0.52.0}/src/kernel/types/auth/connection_login_params.py +0 -0
  94. {kernel-0.50.0 → kernel-0.52.0}/src/kernel/types/auth/connection_submit_params.py +0 -0
  95. {kernel-0.50.0 → kernel-0.52.0}/src/kernel/types/auth/connection_update_params.py +0 -0
  96. {kernel-0.50.0 → kernel-0.52.0}/src/kernel/types/auth/login_response.py +0 -0
  97. {kernel-0.50.0 → kernel-0.52.0}/src/kernel/types/auth/submit_fields_response.py +0 -0
  98. {kernel-0.50.0 → kernel-0.52.0}/src/kernel/types/browser_create_params.py +0 -0
  99. {kernel-0.50.0 → kernel-0.52.0}/src/kernel/types/browser_create_response.py +0 -0
  100. {kernel-0.50.0 → kernel-0.52.0}/src/kernel/types/browser_curl_params.py +0 -0
  101. {kernel-0.50.0 → kernel-0.52.0}/src/kernel/types/browser_curl_response.py +0 -0
  102. {kernel-0.50.0 → kernel-0.52.0}/src/kernel/types/browser_delete_params.py +0 -0
  103. {kernel-0.50.0 → kernel-0.52.0}/src/kernel/types/browser_list_params.py +0 -0
  104. {kernel-0.50.0 → kernel-0.52.0}/src/kernel/types/browser_list_response.py +0 -0
  105. {kernel-0.50.0 → kernel-0.52.0}/src/kernel/types/browser_load_extensions_params.py +0 -0
  106. {kernel-0.50.0 → kernel-0.52.0}/src/kernel/types/browser_persistence.py +0 -0
  107. {kernel-0.50.0 → kernel-0.52.0}/src/kernel/types/browser_persistence_param.py +0 -0
  108. {kernel-0.50.0 → kernel-0.52.0}/src/kernel/types/browser_pool.py +0 -0
  109. {kernel-0.50.0 → kernel-0.52.0}/src/kernel/types/browser_pool_acquire_params.py +0 -0
  110. {kernel-0.50.0 → kernel-0.52.0}/src/kernel/types/browser_pool_acquire_response.py +0 -0
  111. {kernel-0.50.0 → kernel-0.52.0}/src/kernel/types/browser_pool_create_params.py +0 -0
  112. {kernel-0.50.0 → kernel-0.52.0}/src/kernel/types/browser_pool_delete_params.py +0 -0
  113. {kernel-0.50.0 → kernel-0.52.0}/src/kernel/types/browser_pool_list_response.py +0 -0
  114. {kernel-0.50.0 → kernel-0.52.0}/src/kernel/types/browser_pool_ref.py +0 -0
  115. {kernel-0.50.0 → kernel-0.52.0}/src/kernel/types/browser_pool_release_params.py +0 -0
  116. {kernel-0.50.0 → kernel-0.52.0}/src/kernel/types/browser_pool_update_params.py +0 -0
  117. {kernel-0.50.0 → kernel-0.52.0}/src/kernel/types/browser_retrieve_params.py +0 -0
  118. {kernel-0.50.0 → kernel-0.52.0}/src/kernel/types/browser_retrieve_response.py +0 -0
  119. {kernel-0.50.0 → kernel-0.52.0}/src/kernel/types/browser_update_params.py +0 -0
  120. {kernel-0.50.0 → kernel-0.52.0}/src/kernel/types/browser_update_response.py +0 -0
  121. {kernel-0.50.0 → kernel-0.52.0}/src/kernel/types/browser_usage.py +0 -0
  122. {kernel-0.50.0 → kernel-0.52.0}/src/kernel/types/browsers/__init__.py +0 -0
  123. {kernel-0.50.0 → kernel-0.52.0}/src/kernel/types/browsers/computer_batch_params.py +0 -0
  124. {kernel-0.50.0 → kernel-0.52.0}/src/kernel/types/browsers/computer_capture_screenshot_params.py +0 -0
  125. {kernel-0.50.0 → kernel-0.52.0}/src/kernel/types/browsers/computer_click_mouse_params.py +0 -0
  126. {kernel-0.50.0 → kernel-0.52.0}/src/kernel/types/browsers/computer_drag_mouse_params.py +0 -0
  127. {kernel-0.50.0 → kernel-0.52.0}/src/kernel/types/browsers/computer_get_mouse_position_response.py +0 -0
  128. {kernel-0.50.0 → kernel-0.52.0}/src/kernel/types/browsers/computer_move_mouse_params.py +0 -0
  129. {kernel-0.50.0 → kernel-0.52.0}/src/kernel/types/browsers/computer_press_key_params.py +0 -0
  130. {kernel-0.50.0 → kernel-0.52.0}/src/kernel/types/browsers/computer_read_clipboard_response.py +0 -0
  131. {kernel-0.50.0 → kernel-0.52.0}/src/kernel/types/browsers/computer_scroll_params.py +0 -0
  132. {kernel-0.50.0 → kernel-0.52.0}/src/kernel/types/browsers/computer_set_cursor_visibility_params.py +0 -0
  133. {kernel-0.50.0 → kernel-0.52.0}/src/kernel/types/browsers/computer_set_cursor_visibility_response.py +0 -0
  134. {kernel-0.50.0 → kernel-0.52.0}/src/kernel/types/browsers/computer_type_text_params.py +0 -0
  135. {kernel-0.50.0 → kernel-0.52.0}/src/kernel/types/browsers/computer_write_clipboard_params.py +0 -0
  136. {kernel-0.50.0 → kernel-0.52.0}/src/kernel/types/browsers/f_create_directory_params.py +0 -0
  137. {kernel-0.50.0 → kernel-0.52.0}/src/kernel/types/browsers/f_delete_directory_params.py +0 -0
  138. {kernel-0.50.0 → kernel-0.52.0}/src/kernel/types/browsers/f_delete_file_params.py +0 -0
  139. {kernel-0.50.0 → kernel-0.52.0}/src/kernel/types/browsers/f_download_dir_zip_params.py +0 -0
  140. {kernel-0.50.0 → kernel-0.52.0}/src/kernel/types/browsers/f_file_info_params.py +0 -0
  141. {kernel-0.50.0 → kernel-0.52.0}/src/kernel/types/browsers/f_file_info_response.py +0 -0
  142. {kernel-0.50.0 → kernel-0.52.0}/src/kernel/types/browsers/f_list_files_params.py +0 -0
  143. {kernel-0.50.0 → kernel-0.52.0}/src/kernel/types/browsers/f_list_files_response.py +0 -0
  144. {kernel-0.50.0 → kernel-0.52.0}/src/kernel/types/browsers/f_move_params.py +0 -0
  145. {kernel-0.50.0 → kernel-0.52.0}/src/kernel/types/browsers/f_read_file_params.py +0 -0
  146. {kernel-0.50.0 → kernel-0.52.0}/src/kernel/types/browsers/f_set_file_permissions_params.py +0 -0
  147. {kernel-0.50.0 → kernel-0.52.0}/src/kernel/types/browsers/f_upload_params.py +0 -0
  148. {kernel-0.50.0 → kernel-0.52.0}/src/kernel/types/browsers/f_upload_zip_params.py +0 -0
  149. {kernel-0.50.0 → kernel-0.52.0}/src/kernel/types/browsers/f_write_file_params.py +0 -0
  150. {kernel-0.50.0 → kernel-0.52.0}/src/kernel/types/browsers/fs/__init__.py +0 -0
  151. {kernel-0.50.0 → kernel-0.52.0}/src/kernel/types/browsers/fs/watch_events_response.py +0 -0
  152. {kernel-0.50.0 → kernel-0.52.0}/src/kernel/types/browsers/fs/watch_start_params.py +0 -0
  153. {kernel-0.50.0 → kernel-0.52.0}/src/kernel/types/browsers/fs/watch_start_response.py +0 -0
  154. {kernel-0.50.0 → kernel-0.52.0}/src/kernel/types/browsers/log_stream_params.py +0 -0
  155. {kernel-0.50.0 → kernel-0.52.0}/src/kernel/types/browsers/playwright_execute_params.py +0 -0
  156. {kernel-0.50.0 → kernel-0.52.0}/src/kernel/types/browsers/playwright_execute_response.py +0 -0
  157. {kernel-0.50.0 → kernel-0.52.0}/src/kernel/types/browsers/process_exec_params.py +0 -0
  158. {kernel-0.50.0 → kernel-0.52.0}/src/kernel/types/browsers/process_exec_response.py +0 -0
  159. {kernel-0.50.0 → kernel-0.52.0}/src/kernel/types/browsers/process_kill_params.py +0 -0
  160. {kernel-0.50.0 → kernel-0.52.0}/src/kernel/types/browsers/process_kill_response.py +0 -0
  161. {kernel-0.50.0 → kernel-0.52.0}/src/kernel/types/browsers/process_resize_params.py +0 -0
  162. {kernel-0.50.0 → kernel-0.52.0}/src/kernel/types/browsers/process_resize_response.py +0 -0
  163. {kernel-0.50.0 → kernel-0.52.0}/src/kernel/types/browsers/process_spawn_params.py +0 -0
  164. {kernel-0.50.0 → kernel-0.52.0}/src/kernel/types/browsers/process_spawn_response.py +0 -0
  165. {kernel-0.50.0 → kernel-0.52.0}/src/kernel/types/browsers/process_status_response.py +0 -0
  166. {kernel-0.50.0 → kernel-0.52.0}/src/kernel/types/browsers/process_stdin_params.py +0 -0
  167. {kernel-0.50.0 → kernel-0.52.0}/src/kernel/types/browsers/process_stdin_response.py +0 -0
  168. {kernel-0.50.0 → kernel-0.52.0}/src/kernel/types/browsers/process_stdout_stream_response.py +0 -0
  169. {kernel-0.50.0 → kernel-0.52.0}/src/kernel/types/browsers/replay_list_response.py +0 -0
  170. {kernel-0.50.0 → kernel-0.52.0}/src/kernel/types/browsers/replay_start_params.py +0 -0
  171. {kernel-0.50.0 → kernel-0.52.0}/src/kernel/types/browsers/replay_start_response.py +0 -0
  172. {kernel-0.50.0 → kernel-0.52.0}/src/kernel/types/credential.py +0 -0
  173. {kernel-0.50.0 → kernel-0.52.0}/src/kernel/types/credential_create_params.py +0 -0
  174. {kernel-0.50.0 → kernel-0.52.0}/src/kernel/types/credential_list_params.py +0 -0
  175. {kernel-0.50.0 → kernel-0.52.0}/src/kernel/types/credential_provider.py +0 -0
  176. {kernel-0.50.0 → kernel-0.52.0}/src/kernel/types/credential_provider_create_params.py +0 -0
  177. {kernel-0.50.0 → kernel-0.52.0}/src/kernel/types/credential_provider_item.py +0 -0
  178. {kernel-0.50.0 → kernel-0.52.0}/src/kernel/types/credential_provider_list_items_response.py +0 -0
  179. {kernel-0.50.0 → kernel-0.52.0}/src/kernel/types/credential_provider_list_response.py +0 -0
  180. {kernel-0.50.0 → kernel-0.52.0}/src/kernel/types/credential_provider_test_result.py +0 -0
  181. {kernel-0.50.0 → kernel-0.52.0}/src/kernel/types/credential_provider_update_params.py +0 -0
  182. {kernel-0.50.0 → kernel-0.52.0}/src/kernel/types/credential_totp_code_response.py +0 -0
  183. {kernel-0.50.0 → kernel-0.52.0}/src/kernel/types/credential_update_params.py +0 -0
  184. {kernel-0.50.0 → kernel-0.52.0}/src/kernel/types/deployment_create_params.py +0 -0
  185. {kernel-0.50.0 → kernel-0.52.0}/src/kernel/types/deployment_create_response.py +0 -0
  186. {kernel-0.50.0 → kernel-0.52.0}/src/kernel/types/deployment_follow_params.py +0 -0
  187. {kernel-0.50.0 → kernel-0.52.0}/src/kernel/types/deployment_follow_response.py +0 -0
  188. {kernel-0.50.0 → kernel-0.52.0}/src/kernel/types/deployment_list_params.py +0 -0
  189. {kernel-0.50.0 → kernel-0.52.0}/src/kernel/types/deployment_list_response.py +0 -0
  190. {kernel-0.50.0 → kernel-0.52.0}/src/kernel/types/deployment_retrieve_response.py +0 -0
  191. {kernel-0.50.0 → kernel-0.52.0}/src/kernel/types/deployment_state_event.py +0 -0
  192. {kernel-0.50.0 → kernel-0.52.0}/src/kernel/types/extension_download_from_chrome_store_params.py +0 -0
  193. {kernel-0.50.0 → kernel-0.52.0}/src/kernel/types/extension_list_response.py +0 -0
  194. {kernel-0.50.0 → kernel-0.52.0}/src/kernel/types/extension_upload_params.py +0 -0
  195. {kernel-0.50.0 → kernel-0.52.0}/src/kernel/types/extension_upload_response.py +0 -0
  196. {kernel-0.50.0 → kernel-0.52.0}/src/kernel/types/invocation_create_params.py +0 -0
  197. {kernel-0.50.0 → kernel-0.52.0}/src/kernel/types/invocation_create_response.py +0 -0
  198. {kernel-0.50.0 → kernel-0.52.0}/src/kernel/types/invocation_follow_params.py +0 -0
  199. {kernel-0.50.0 → kernel-0.52.0}/src/kernel/types/invocation_follow_response.py +0 -0
  200. {kernel-0.50.0 → kernel-0.52.0}/src/kernel/types/invocation_list_browsers_response.py +0 -0
  201. {kernel-0.50.0 → kernel-0.52.0}/src/kernel/types/invocation_list_params.py +0 -0
  202. {kernel-0.50.0 → kernel-0.52.0}/src/kernel/types/invocation_list_response.py +0 -0
  203. {kernel-0.50.0 → kernel-0.52.0}/src/kernel/types/invocation_retrieve_response.py +0 -0
  204. {kernel-0.50.0 → kernel-0.52.0}/src/kernel/types/invocation_state_event.py +0 -0
  205. {kernel-0.50.0 → kernel-0.52.0}/src/kernel/types/invocation_update_params.py +0 -0
  206. {kernel-0.50.0 → kernel-0.52.0}/src/kernel/types/invocation_update_response.py +0 -0
  207. {kernel-0.50.0 → kernel-0.52.0}/src/kernel/types/profile.py +0 -0
  208. {kernel-0.50.0 → kernel-0.52.0}/src/kernel/types/profile_create_params.py +0 -0
  209. {kernel-0.50.0 → kernel-0.52.0}/src/kernel/types/profile_list_params.py +0 -0
  210. {kernel-0.50.0 → kernel-0.52.0}/src/kernel/types/project.py +0 -0
  211. {kernel-0.50.0 → kernel-0.52.0}/src/kernel/types/project_create_params.py +0 -0
  212. {kernel-0.50.0 → kernel-0.52.0}/src/kernel/types/project_list_params.py +0 -0
  213. {kernel-0.50.0 → kernel-0.52.0}/src/kernel/types/project_update_params.py +0 -0
  214. {kernel-0.50.0 → kernel-0.52.0}/src/kernel/types/projects/__init__.py +0 -0
  215. {kernel-0.50.0 → kernel-0.52.0}/src/kernel/types/projects/limit_update_params.py +0 -0
  216. {kernel-0.50.0 → kernel-0.52.0}/src/kernel/types/projects/project_limits.py +0 -0
  217. {kernel-0.50.0 → kernel-0.52.0}/src/kernel/types/proxy_check_params.py +0 -0
  218. {kernel-0.50.0 → kernel-0.52.0}/src/kernel/types/proxy_check_response.py +0 -0
  219. {kernel-0.50.0 → kernel-0.52.0}/src/kernel/types/proxy_create_params.py +0 -0
  220. {kernel-0.50.0 → kernel-0.52.0}/src/kernel/types/proxy_create_response.py +0 -0
  221. {kernel-0.50.0 → kernel-0.52.0}/src/kernel/types/proxy_list_response.py +0 -0
  222. {kernel-0.50.0 → kernel-0.52.0}/src/kernel/types/proxy_retrieve_response.py +0 -0
  223. {kernel-0.50.0 → kernel-0.52.0}/src/kernel/types/shared/__init__.py +0 -0
  224. {kernel-0.50.0 → kernel-0.52.0}/src/kernel/types/shared/app_action.py +0 -0
  225. {kernel-0.50.0 → kernel-0.52.0}/src/kernel/types/shared/browser_extension.py +0 -0
  226. {kernel-0.50.0 → kernel-0.52.0}/src/kernel/types/shared/browser_profile.py +0 -0
  227. {kernel-0.50.0 → kernel-0.52.0}/src/kernel/types/shared/browser_viewport.py +0 -0
  228. {kernel-0.50.0 → kernel-0.52.0}/src/kernel/types/shared/error_detail.py +0 -0
  229. {kernel-0.50.0 → kernel-0.52.0}/src/kernel/types/shared/error_event.py +0 -0
  230. {kernel-0.50.0 → kernel-0.52.0}/src/kernel/types/shared/error_model.py +0 -0
  231. {kernel-0.50.0 → kernel-0.52.0}/src/kernel/types/shared/heartbeat_event.py +0 -0
  232. {kernel-0.50.0 → kernel-0.52.0}/src/kernel/types/shared/log_event.py +0 -0
  233. {kernel-0.50.0 → kernel-0.52.0}/src/kernel/types/shared_params/__init__.py +0 -0
  234. {kernel-0.50.0 → kernel-0.52.0}/src/kernel/types/shared_params/browser_extension.py +0 -0
  235. {kernel-0.50.0 → kernel-0.52.0}/src/kernel/types/shared_params/browser_profile.py +0 -0
  236. {kernel-0.50.0 → kernel-0.52.0}/src/kernel/types/shared_params/browser_viewport.py +0 -0
  237. {kernel-0.50.0 → kernel-0.52.0}/tests/__init__.py +0 -0
  238. {kernel-0.50.0 → kernel-0.52.0}/tests/api_resources/__init__.py +0 -0
  239. {kernel-0.50.0 → kernel-0.52.0}/tests/api_resources/auth/__init__.py +0 -0
  240. {kernel-0.50.0 → kernel-0.52.0}/tests/api_resources/auth/test_connections.py +0 -0
  241. {kernel-0.50.0 → kernel-0.52.0}/tests/api_resources/browsers/__init__.py +0 -0
  242. {kernel-0.50.0 → kernel-0.52.0}/tests/api_resources/browsers/fs/__init__.py +0 -0
  243. {kernel-0.50.0 → kernel-0.52.0}/tests/api_resources/browsers/fs/test_watch.py +0 -0
  244. {kernel-0.50.0 → kernel-0.52.0}/tests/api_resources/browsers/test_computer.py +0 -0
  245. {kernel-0.50.0 → kernel-0.52.0}/tests/api_resources/browsers/test_fs.py +0 -0
  246. {kernel-0.50.0 → kernel-0.52.0}/tests/api_resources/browsers/test_logs.py +0 -0
  247. {kernel-0.50.0 → kernel-0.52.0}/tests/api_resources/browsers/test_playwright.py +0 -0
  248. {kernel-0.50.0 → kernel-0.52.0}/tests/api_resources/browsers/test_process.py +0 -0
  249. {kernel-0.50.0 → kernel-0.52.0}/tests/api_resources/browsers/test_replays.py +0 -0
  250. {kernel-0.50.0 → kernel-0.52.0}/tests/api_resources/projects/__init__.py +0 -0
  251. {kernel-0.50.0 → kernel-0.52.0}/tests/api_resources/projects/test_limits.py +0 -0
  252. {kernel-0.50.0 → kernel-0.52.0}/tests/api_resources/test_apps.py +0 -0
  253. {kernel-0.50.0 → kernel-0.52.0}/tests/api_resources/test_browser_pools.py +0 -0
  254. {kernel-0.50.0 → kernel-0.52.0}/tests/api_resources/test_browsers.py +0 -0
  255. {kernel-0.50.0 → kernel-0.52.0}/tests/api_resources/test_credential_providers.py +0 -0
  256. {kernel-0.50.0 → kernel-0.52.0}/tests/api_resources/test_credentials.py +0 -0
  257. {kernel-0.50.0 → kernel-0.52.0}/tests/api_resources/test_deployments.py +0 -0
  258. {kernel-0.50.0 → kernel-0.52.0}/tests/api_resources/test_extensions.py +0 -0
  259. {kernel-0.50.0 → kernel-0.52.0}/tests/api_resources/test_invocations.py +0 -0
  260. {kernel-0.50.0 → kernel-0.52.0}/tests/api_resources/test_profiles.py +0 -0
  261. {kernel-0.50.0 → kernel-0.52.0}/tests/api_resources/test_projects.py +0 -0
  262. {kernel-0.50.0 → kernel-0.52.0}/tests/api_resources/test_proxies.py +0 -0
  263. {kernel-0.50.0 → kernel-0.52.0}/tests/conftest.py +0 -0
  264. {kernel-0.50.0 → kernel-0.52.0}/tests/sample_file.txt +0 -0
  265. {kernel-0.50.0 → kernel-0.52.0}/tests/test_client.py +0 -0
  266. {kernel-0.50.0 → kernel-0.52.0}/tests/test_models.py +0 -0
  267. {kernel-0.50.0 → kernel-0.52.0}/tests/test_qs.py +0 -0
  268. {kernel-0.50.0 → kernel-0.52.0}/tests/test_required_args.py +0 -0
  269. {kernel-0.50.0 → kernel-0.52.0}/tests/test_response.py +0 -0
  270. {kernel-0.50.0 → kernel-0.52.0}/tests/test_streaming.py +0 -0
  271. {kernel-0.50.0 → kernel-0.52.0}/tests/test_transform.py +0 -0
  272. {kernel-0.50.0 → kernel-0.52.0}/tests/test_utils/test_datetime_parse.py +0 -0
  273. {kernel-0.50.0 → kernel-0.52.0}/tests/test_utils/test_json.py +0 -0
  274. {kernel-0.50.0 → kernel-0.52.0}/tests/test_utils/test_path.py +0 -0
  275. {kernel-0.50.0 → kernel-0.52.0}/tests/test_utils/test_proxy.py +0 -0
  276. {kernel-0.50.0 → kernel-0.52.0}/tests/test_utils/test_typing.py +0 -0
  277. {kernel-0.50.0 → kernel-0.52.0}/tests/utils.py +0 -0
@@ -0,0 +1,3 @@
1
+ {
2
+ ".": "0.52.0"
3
+ }
@@ -1,5 +1,76 @@
1
1
  # Changelog
2
2
 
3
+ ## 0.52.0 (2026-04-29)
4
+
5
+ Full Changelog: [v0.51.0...v0.52.0](https://github.com/kernel/kernel-python-sdk/compare/v0.51.0...v0.52.0)
6
+
7
+ ### Features
8
+
9
+ * profile download: 409 for empty profile + surface API errors in dashboard ([fd0c20e](https://github.com/kernel/kernel-python-sdk/commit/fd0c20eb17f0a6df382672c34830a81fac9217d9))
10
+ * support setting headers via env ([37dda88](https://github.com/kernel/kernel-python-sdk/commit/37dda88a1f88fdf4bd8da615cbb6be1aadae3f41))
11
+
12
+
13
+ ### Bug Fixes
14
+
15
+ * use correct field name format for multipart file arrays ([663f0a8](https://github.com/kernel/kernel-python-sdk/commit/663f0a8a633fd5b0f5f8b65ed169c4d780251e1d))
16
+
17
+
18
+ ### Documentation
19
+
20
+ * annotate response with httpx.Response in browser routing example ([0dfa1fb](https://github.com/kernel/kernel-python-sdk/commit/0dfa1fb978da1c4fd474840ae8664f027e1feb39))
21
+ * print buffered body and mention httpx.Response semantics ([84cb2e3](https://github.com/kernel/kernel-python-sdk/commit/84cb2e38486f330635487ed049d692f7c9716a1f))
22
+ * show both raw streaming and buffered curl in routing example ([407e748](https://github.com/kernel/kernel-python-sdk/commit/407e74862f99db13320ea6c02a8752759d4de60a))
23
+ * simplify browser routing example ([58b0ee2](https://github.com/kernel/kernel-python-sdk/commit/58b0ee27cdac1f4021c6e333f8157318c838ec56))
24
+
25
+ ## 0.51.0 (2026-04-25)
26
+
27
+ Full Changelog: [v0.50.0...v0.51.0](https://github.com/kernel/kernel-python-sdk/compare/v0.50.0...v0.51.0)
28
+
29
+ ### Features
30
+
31
+ * add browser-scoped session client ([7ca6887](https://github.com/kernel/kernel-python-sdk/commit/7ca68877e7011bb83862b7cc810a20d8254ea7dd))
32
+ * Expire stuck IN_PROGRESS managed auth sessions via background worker ([7781a3b](https://github.com/kernel/kernel-python-sdk/commit/7781a3b4635ded02dea60adf85878f50f7b7fb27))
33
+ * Expose browser_session_id on managed auth connection ([0ccb507](https://github.com/kernel/kernel-python-sdk/commit/0ccb50744032b4c31e0575fa7b06fb20503c8f55))
34
+ * generate browser-scoped resource bindings ([53b17c8](https://github.com/kernel/kernel-python-sdk/commit/53b17c8241cc71261d1e96f5929cbd4f05b2064b))
35
+
36
+
37
+ ### Bug Fixes
38
+
39
+ * address python browser routing ci follow-ups ([9690923](https://github.com/kernel/kernel-python-sdk/commit/9690923666cfe07de76267eee050d7743a8bad6f))
40
+ * evict deleted browser routes ([a873a18](https://github.com/kernel/kernel-python-sdk/commit/a873a18eba3f36937dc177ab981372e395722f8b))
41
+ * finish python browser routing cleanup ([694907a](https://github.com/kernel/kernel-python-sdk/commit/694907ab3419477e7058b85a7365ac4cce941105))
42
+ * normalize browser route cache session IDs ([f4c247b](https://github.com/kernel/kernel-python-sdk/commit/f4c247b425680b54d0ce3c7738fb82313bca7918))
43
+ * normalize python browser request string bodies ([3ce80e7](https://github.com/kernel/kernel-python-sdk/commit/3ce80e767d373b638ba1c2959bf18bf999629db0))
44
+ * quiet generator-script pyright noise ([0bdf85e](https://github.com/kernel/kernel-python-sdk/commit/0bdf85e0c38d4813056b61599273e88c7a64713a))
45
+ * reserve internal browser request query params ([b2c7aac](https://github.com/kernel/kernel-python-sdk/commit/b2c7aacac09a1bb7680cf493e9985438b169286c))
46
+ * satisfy browser-scoped lint checks ([8e8dde2](https://github.com/kernel/kernel-python-sdk/commit/8e8dde241c8817944baaacd155fe196f200868e8))
47
+ * satisfy generated browser-scoped type checks ([b410245](https://github.com/kernel/kernel-python-sdk/commit/b410245e1ad4bf8e29c17c59a5931654567b141f))
48
+ * sniff browser pool route cache updates ([5328730](https://github.com/kernel/kernel-python-sdk/commit/532873072f0400029768d1b7cf54b9fb1428ada9))
49
+ * type-check browser-scoped helpers ([cfff5b4](https://github.com/kernel/kernel-python-sdk/commit/cfff5b4c3635d327dd1ac0779d4e17e395efbec0))
50
+
51
+
52
+ ### Chores
53
+
54
+ * fix browser-scoped test import order ([fc34859](https://github.com/kernel/kernel-python-sdk/commit/fc34859c4f60f84038b425d9930c512e58134dea))
55
+ * **internal:** more robust bootstrap script ([6c9cdf3](https://github.com/kernel/kernel-python-sdk/commit/6c9cdf3ce828fab358c7e060f4e3313408cad257))
56
+ * keep browser-scoped generator lint clean ([a80716b](https://github.com/kernel/kernel-python-sdk/commit/a80716b791bf1f707aa7869290c47caefb0d9e27))
57
+
58
+
59
+ ### Documentation
60
+
61
+ * flesh out browser-scoped example ([ca5d188](https://github.com/kernel/kernel-python-sdk/commit/ca5d1884b590634df5623945e9585e0a66228ec3))
62
+
63
+
64
+ ### Refactors
65
+
66
+ * clean up python browser routing diff ([622f844](https://github.com/kernel/kernel-python-sdk/commit/622f8448a8a32f00b41d6e4890bfaf0a9374bd3e))
67
+ * drop browser-scoped wrapper clients ([dba503e](https://github.com/kernel/kernel-python-sdk/commit/dba503e832d54aa8d462d3d74b3027f8a9e865b6))
68
+ * inline browser resource passthrough returns ([02a2f59](https://github.com/kernel/kernel-python-sdk/commit/02a2f595c7e76ae7f0cea2ec1e88075df3a25be1))
69
+ * move python browser routing rollout to env ([0647d5c](https://github.com/kernel/kernel-python-sdk/commit/0647d5cab166e680bcb3436d1b502c3215492400))
70
+ * rename browser routing subresources config ([3ae9dab](https://github.com/kernel/kernel-python-sdk/commit/3ae9dab6b841e6f1191cdde073e36696f97feb39))
71
+ * simplify browser routing cache ([de0476f](https://github.com/kernel/kernel-python-sdk/commit/de0476fc043df48a58dd4067bb4b3c0fe7a83f0e))
72
+ * sniff browser routes in response hooks ([563de7d](https://github.com/kernel/kernel-python-sdk/commit/563de7d0ac8f141320edb060b4671935808e473a))
73
+
3
74
  ## 0.50.0 (2026-04-20)
4
75
 
5
76
  Full Changelog: [v0.49.0...v0.50.0](https://github.com/kernel/kernel-python-sdk/compare/v0.49.0...v0.50.0)
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: kernel
3
- Version: 0.50.0
3
+ Version: 0.52.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
@@ -0,0 +1,26 @@
1
+ """Example: direct-to-VM browser routing for raw HTTP."""
2
+
3
+ import httpx
4
+
5
+ from kernel import Kernel
6
+
7
+
8
+ def main() -> None:
9
+ client = Kernel()
10
+
11
+ browser = client.browsers.create()
12
+
13
+ # Raw browser curl: streams the response. Use for large responses, when you want to stream,
14
+ # or when you want httpx.Response semantics.
15
+ response: httpx.Response = client.browsers.request(browser.session_id, "GET", "https://example.com")
16
+ print("status", response.status_code)
17
+
18
+ # Buffered browser curl: returns the full response in a JSON envelope. Use for small responses.
19
+ buffered = client.browsers.curl(browser.session_id, url="https://example.com", method="GET")
20
+ print("body", buffered.body)
21
+
22
+ client.browsers.delete_by_id(browser.session_id)
23
+
24
+
25
+ if __name__ == "__main__":
26
+ main()
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "kernel"
3
- version = "0.50.0"
3
+ version = "0.52.0"
4
4
  description = "The official Python library for the kernel API"
5
5
  dynamic = ["readme"]
6
6
  license = "Apache-2.0"
@@ -3,7 +3,7 @@
3
3
  from __future__ import annotations
4
4
 
5
5
  import os
6
- from typing import TYPE_CHECKING, Any, Dict, Mapping, cast
6
+ from typing import TYPE_CHECKING, Any, Dict, Type, Mapping, cast
7
7
  from typing_extensions import Self, Literal, override
8
8
 
9
9
  import httpx
@@ -14,13 +14,19 @@ from ._types import (
14
14
  Omit,
15
15
  Timeout,
16
16
  NotGiven,
17
+ ResponseT,
17
18
  Transport,
18
19
  ProxiesTypes,
19
20
  RequestOptions,
20
21
  not_given,
21
22
  )
22
- from ._utils import is_given, get_async_library
23
+ from ._utils import (
24
+ is_given,
25
+ is_mapping_t,
26
+ get_async_library,
27
+ )
23
28
  from ._compat import cached_property
29
+ from ._models import FinalRequestOptions
24
30
  from ._version import __version__
25
31
  from ._streaming import Stream as Stream, AsyncStream as AsyncStream
26
32
  from ._exceptions import KernelError, APIStatusError
@@ -29,6 +35,15 @@ from ._base_client import (
29
35
  SyncAPIClient,
30
36
  AsyncAPIClient,
31
37
  )
38
+ from .lib.browser_routing.routing import (
39
+ BrowserRouteCache,
40
+ BrowserRoutingConfig,
41
+ strip_direct_vm_auth,
42
+ rewrite_direct_vm_options,
43
+ browser_routing_config_from_env,
44
+ maybe_evict_browser_route_from_response,
45
+ maybe_populate_browser_route_cache_from_response,
46
+ )
32
47
 
33
48
  if TYPE_CHECKING:
34
49
  from .resources import (
@@ -79,8 +94,10 @@ ENVIRONMENTS: Dict[str, str] = {
79
94
  class Kernel(SyncAPIClient):
80
95
  # client options
81
96
  api_key: str
97
+ browser_route_cache: BrowserRouteCache
82
98
 
83
99
  _environment: Literal["production", "development"] | NotGiven
100
+ _browser_routing: BrowserRoutingConfig
84
101
 
85
102
  def __init__(
86
103
  self,
@@ -105,6 +122,7 @@ class Kernel(SyncAPIClient):
105
122
  # outlining your use-case to help us decide if it should be
106
123
  # part of our public interface in the future.
107
124
  _strict_response_validation: bool = False,
125
+ _browser_route_cache: BrowserRouteCache | None = None,
108
126
  ) -> None:
109
127
  """Construct a new synchronous Kernel client instance.
110
128
 
@@ -144,6 +162,15 @@ class Kernel(SyncAPIClient):
144
162
  except KeyError as exc:
145
163
  raise ValueError(f"Unknown environment: {environment}") from exc
146
164
 
165
+ custom_headers_env = os.environ.get("KERNEL_CUSTOM_HEADERS")
166
+ if custom_headers_env is not None:
167
+ parsed: dict[str, str] = {}
168
+ for line in custom_headers_env.split("\n"):
169
+ colon = line.find(":")
170
+ if colon >= 0:
171
+ parsed[line[:colon].strip()] = line[colon + 1 :].strip()
172
+ default_headers = {**parsed, **(default_headers if is_mapping_t(default_headers) else {})}
173
+
147
174
  super().__init__(
148
175
  version=__version__,
149
176
  base_url=base_url,
@@ -154,6 +181,8 @@ class Kernel(SyncAPIClient):
154
181
  custom_query=default_query,
155
182
  _strict_response_validation=_strict_response_validation,
156
183
  )
184
+ self.browser_route_cache = _browser_route_cache or BrowserRouteCache()
185
+ self._browser_routing = browser_routing_config_from_env()
157
186
 
158
187
  @cached_property
159
188
  def deployments(self) -> DeploymentsResource:
@@ -266,6 +295,37 @@ class Kernel(SyncAPIClient):
266
295
  **self._custom_headers,
267
296
  }
268
297
 
298
+ @override
299
+ def _prepare_options(self, options: Any) -> Any:
300
+ options = cast(Any, super()._prepare_options(options))
301
+ return rewrite_direct_vm_options(options, cache=self.browser_route_cache, config=self._browser_routing)
302
+
303
+ @override
304
+ def _prepare_request(self, request: httpx.Request) -> None:
305
+ strip_direct_vm_auth(request, cache=self.browser_route_cache)
306
+
307
+ @override
308
+ def _process_response(
309
+ self,
310
+ *,
311
+ cast_to: Type[ResponseT],
312
+ options: FinalRequestOptions,
313
+ response: httpx.Response,
314
+ stream: bool,
315
+ stream_cls: type[Stream[Any]] | type[AsyncStream[Any]] | None,
316
+ retries_taken: int = 0,
317
+ ) -> ResponseT:
318
+ maybe_populate_browser_route_cache_from_response(response, cache=self.browser_route_cache)
319
+ maybe_evict_browser_route_from_response(response, cache=self.browser_route_cache)
320
+ return super()._process_response(
321
+ cast_to=cast_to,
322
+ options=options,
323
+ response=response,
324
+ stream=stream,
325
+ stream_cls=stream_cls,
326
+ retries_taken=retries_taken,
327
+ )
328
+
269
329
  def copy(
270
330
  self,
271
331
  *,
@@ -279,6 +339,7 @@ class Kernel(SyncAPIClient):
279
339
  set_default_headers: Mapping[str, str] | None = None,
280
340
  default_query: Mapping[str, object] | None = None,
281
341
  set_default_query: Mapping[str, object] | None = None,
342
+ _browser_route_cache: BrowserRouteCache | None = None,
282
343
  _extra_kwargs: Mapping[str, Any] = {},
283
344
  ) -> Self:
284
345
  """
@@ -312,6 +373,7 @@ class Kernel(SyncAPIClient):
312
373
  max_retries=max_retries if is_given(max_retries) else self.max_retries,
313
374
  default_headers=headers,
314
375
  default_query=params,
376
+ _browser_route_cache=_browser_route_cache or self.browser_route_cache,
315
377
  **_extra_kwargs,
316
378
  )
317
379
 
@@ -356,8 +418,10 @@ class Kernel(SyncAPIClient):
356
418
  class AsyncKernel(AsyncAPIClient):
357
419
  # client options
358
420
  api_key: str
421
+ browser_route_cache: BrowserRouteCache
359
422
 
360
423
  _environment: Literal["production", "development"] | NotGiven
424
+ _browser_routing: BrowserRoutingConfig
361
425
 
362
426
  def __init__(
363
427
  self,
@@ -382,6 +446,7 @@ class AsyncKernel(AsyncAPIClient):
382
446
  # outlining your use-case to help us decide if it should be
383
447
  # part of our public interface in the future.
384
448
  _strict_response_validation: bool = False,
449
+ _browser_route_cache: BrowserRouteCache | None = None,
385
450
  ) -> None:
386
451
  """Construct a new async AsyncKernel client instance.
387
452
 
@@ -421,6 +486,15 @@ class AsyncKernel(AsyncAPIClient):
421
486
  except KeyError as exc:
422
487
  raise ValueError(f"Unknown environment: {environment}") from exc
423
488
 
489
+ custom_headers_env = os.environ.get("KERNEL_CUSTOM_HEADERS")
490
+ if custom_headers_env is not None:
491
+ parsed: dict[str, str] = {}
492
+ for line in custom_headers_env.split("\n"):
493
+ colon = line.find(":")
494
+ if colon >= 0:
495
+ parsed[line[:colon].strip()] = line[colon + 1 :].strip()
496
+ default_headers = {**parsed, **(default_headers if is_mapping_t(default_headers) else {})}
497
+
424
498
  super().__init__(
425
499
  version=__version__,
426
500
  base_url=base_url,
@@ -431,6 +505,8 @@ class AsyncKernel(AsyncAPIClient):
431
505
  custom_query=default_query,
432
506
  _strict_response_validation=_strict_response_validation,
433
507
  )
508
+ self.browser_route_cache = _browser_route_cache or BrowserRouteCache()
509
+ self._browser_routing = browser_routing_config_from_env()
434
510
 
435
511
  @cached_property
436
512
  def deployments(self) -> AsyncDeploymentsResource:
@@ -543,6 +619,37 @@ class AsyncKernel(AsyncAPIClient):
543
619
  **self._custom_headers,
544
620
  }
545
621
 
622
+ @override
623
+ async def _prepare_options(self, options: Any) -> Any:
624
+ options = cast(Any, await super()._prepare_options(options))
625
+ return rewrite_direct_vm_options(options, cache=self.browser_route_cache, config=self._browser_routing)
626
+
627
+ @override
628
+ async def _prepare_request(self, request: httpx.Request) -> None:
629
+ strip_direct_vm_auth(request, cache=self.browser_route_cache)
630
+
631
+ @override
632
+ async def _process_response(
633
+ self,
634
+ *,
635
+ cast_to: Type[ResponseT],
636
+ options: FinalRequestOptions,
637
+ response: httpx.Response,
638
+ stream: bool,
639
+ stream_cls: type[Stream[Any]] | type[AsyncStream[Any]] | None,
640
+ retries_taken: int = 0,
641
+ ) -> ResponseT:
642
+ maybe_populate_browser_route_cache_from_response(response, cache=self.browser_route_cache)
643
+ maybe_evict_browser_route_from_response(response, cache=self.browser_route_cache)
644
+ return await super()._process_response(
645
+ cast_to=cast_to,
646
+ options=options,
647
+ response=response,
648
+ stream=stream,
649
+ stream_cls=stream_cls,
650
+ retries_taken=retries_taken,
651
+ )
652
+
546
653
  def copy(
547
654
  self,
548
655
  *,
@@ -556,6 +663,7 @@ class AsyncKernel(AsyncAPIClient):
556
663
  set_default_headers: Mapping[str, str] | None = None,
557
664
  default_query: Mapping[str, object] | None = None,
558
665
  set_default_query: Mapping[str, object] | None = None,
666
+ _browser_route_cache: BrowserRouteCache | None = None,
559
667
  _extra_kwargs: Mapping[str, Any] = {},
560
668
  ) -> Self:
561
669
  """
@@ -589,6 +697,7 @@ class AsyncKernel(AsyncAPIClient):
589
697
  max_retries=max_retries if is_given(max_retries) else self.max_retries,
590
698
  default_headers=headers,
591
699
  default_query=params,
700
+ _browser_route_cache=_browser_route_cache or self.browser_route_cache,
592
701
  **_extra_kwargs,
593
702
  )
594
703
 
@@ -2,17 +2,13 @@ from __future__ import annotations
2
2
 
3
3
  from typing import Any, List, Tuple, Union, Mapping, TypeVar
4
4
  from urllib.parse import parse_qs, urlencode
5
- from typing_extensions import Literal, get_args
5
+ from typing_extensions import get_args
6
6
 
7
- from ._types import NotGiven, not_given
7
+ from ._types import NotGiven, ArrayFormat, NestedFormat, not_given
8
8
  from ._utils import flatten
9
9
 
10
10
  _T = TypeVar("_T")
11
11
 
12
-
13
- ArrayFormat = Literal["comma", "repeat", "indices", "brackets"]
14
- NestedFormat = Literal["dots", "brackets"]
15
-
16
12
  PrimitiveData = Union[str, int, float, bool, None]
17
13
  # this should be Data = Union[PrimitiveData, "List[Data]", "Tuple[Data]", "Mapping[str, Data]"]
18
14
  # https://github.com/microsoft/pyright/issues/3555
@@ -47,6 +47,9 @@ AnyMapping = Mapping[str, object]
47
47
  ModelT = TypeVar("ModelT", bound=pydantic.BaseModel)
48
48
  _T = TypeVar("_T")
49
49
 
50
+ ArrayFormat = Literal["comma", "repeat", "indices", "brackets"]
51
+ NestedFormat = Literal["dots", "brackets"]
52
+
50
53
 
51
54
  # Approximates httpx internal ProxiesTypes and RequestFiles types
52
55
  # while adding support for `PathLike` instances
@@ -17,11 +17,11 @@ from typing import (
17
17
  )
18
18
  from pathlib import Path
19
19
  from datetime import date, datetime
20
- from typing_extensions import TypeGuard
20
+ from typing_extensions import TypeGuard, get_args
21
21
 
22
22
  import sniffio
23
23
 
24
- from .._types import Omit, NotGiven, FileTypes, HeadersLike
24
+ from .._types import Omit, NotGiven, FileTypes, ArrayFormat, HeadersLike
25
25
 
26
26
  _T = TypeVar("_T")
27
27
  _TupleT = TypeVar("_TupleT", bound=Tuple[object, ...])
@@ -40,25 +40,45 @@ def extract_files(
40
40
  query: Mapping[str, object],
41
41
  *,
42
42
  paths: Sequence[Sequence[str]],
43
+ array_format: ArrayFormat = "brackets",
43
44
  ) -> list[tuple[str, FileTypes]]:
44
45
  """Recursively extract files from the given dictionary based on specified paths.
45
46
 
46
47
  A path may look like this ['foo', 'files', '<array>', 'data'].
47
48
 
49
+ ``array_format`` controls how ``<array>`` segments contribute to the emitted
50
+ field name. Supported values: ``"brackets"`` (``foo[]``), ``"repeat"`` and
51
+ ``"comma"`` (``foo``), ``"indices"`` (``foo[0]``, ``foo[1]``).
52
+
48
53
  Note: this mutates the given dictionary.
49
54
  """
50
55
  files: list[tuple[str, FileTypes]] = []
51
56
  for path in paths:
52
- files.extend(_extract_items(query, path, index=0, flattened_key=None))
57
+ files.extend(_extract_items(query, path, index=0, flattened_key=None, array_format=array_format))
53
58
  return files
54
59
 
55
60
 
61
+ def _array_suffix(array_format: ArrayFormat, array_index: int) -> str:
62
+ if array_format == "brackets":
63
+ return "[]"
64
+ if array_format == "indices":
65
+ return f"[{array_index}]"
66
+ if array_format == "repeat" or array_format == "comma":
67
+ # Both repeat the bare field name for each file part; there is no
68
+ # meaningful way to comma-join binary parts.
69
+ return ""
70
+ raise NotImplementedError(
71
+ f"Unknown array_format value: {array_format}, choose from {', '.join(get_args(ArrayFormat))}"
72
+ )
73
+
74
+
56
75
  def _extract_items(
57
76
  obj: object,
58
77
  path: Sequence[str],
59
78
  *,
60
79
  index: int,
61
80
  flattened_key: str | None,
81
+ array_format: ArrayFormat,
62
82
  ) -> list[tuple[str, FileTypes]]:
63
83
  try:
64
84
  key = path[index]
@@ -75,9 +95,11 @@ def _extract_items(
75
95
 
76
96
  if is_list(obj):
77
97
  files: list[tuple[str, FileTypes]] = []
78
- for entry in obj:
79
- assert_is_file_content(entry, key=flattened_key + "[]" if flattened_key else "")
80
- files.append((flattened_key + "[]", cast(FileTypes, entry)))
98
+ for array_index, entry in enumerate(obj):
99
+ suffix = _array_suffix(array_format, array_index)
100
+ emitted_key = (flattened_key + suffix) if flattened_key else suffix
101
+ assert_is_file_content(entry, key=emitted_key)
102
+ files.append((emitted_key, cast(FileTypes, entry)))
81
103
  return files
82
104
 
83
105
  assert_is_file_content(obj, key=flattened_key)
@@ -106,6 +128,7 @@ def _extract_items(
106
128
  path,
107
129
  index=index,
108
130
  flattened_key=flattened_key,
131
+ array_format=array_format,
109
132
  )
110
133
  elif is_list(obj):
111
134
  if key != "<array>":
@@ -117,9 +140,12 @@ def _extract_items(
117
140
  item,
118
141
  path,
119
142
  index=index,
120
- flattened_key=flattened_key + "[]" if flattened_key is not None else "[]",
143
+ flattened_key=(
144
+ (flattened_key if flattened_key is not None else "") + _array_suffix(array_format, array_index)
145
+ ),
146
+ array_format=array_format,
121
147
  )
122
- for item in obj
148
+ for array_index, item in enumerate(obj)
123
149
  ]
124
150
  )
125
151
 
@@ -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.50.0" # x-release-please-version
4
+ __version__ = "0.52.0" # x-release-please-version
@@ -0,0 +1,3 @@
1
+ from __future__ import annotations
2
+
3
+ __all__: list[str] = []
@@ -0,0 +1,150 @@
1
+ from __future__ import annotations
2
+
3
+ from typing import IO, Any, Union, Mapping, cast
4
+ from contextlib import contextmanager, asynccontextmanager
5
+ from collections.abc import Iterable, Iterator, AsyncIterator
6
+
7
+ import httpx
8
+
9
+ from .util import sanitize_curl_raw_params
10
+ from .routing import BrowserRoute
11
+ from ..._types import Body, Timeout, NotGiven, not_given
12
+ from ..._models import FinalRequestOptions
13
+
14
+ BrowserRawContent = Union[bytes, bytearray, memoryview, str, IO[bytes], Iterable[bytes]]
15
+
16
+
17
+ def request_via_browser_route(
18
+ parent: Any,
19
+ route: BrowserRoute,
20
+ method: str,
21
+ url: str,
22
+ *,
23
+ content: BrowserRawContent | None = None,
24
+ json: Body | None = None,
25
+ headers: Mapping[str, str] | None = None,
26
+ params: Mapping[str, object] | None = None,
27
+ timeout: float | Timeout | None | NotGiven = not_given,
28
+ ) -> httpx.Response:
29
+ if json is not None and content is not None:
30
+ raise TypeError("Passing both `json` and `content` is not supported")
31
+ query: dict[str, object] = {**sanitize_curl_raw_params(params), "url": url, "jwt": route.jwt}
32
+ options = FinalRequestOptions.construct(
33
+ method=method.upper(),
34
+ url=route.base_url.rstrip("/") + "/curl/raw",
35
+ params=query,
36
+ headers=headers or {},
37
+ content=_normalize_binary_content(content),
38
+ json_data=json,
39
+ timeout=_normalize_timeout(timeout),
40
+ )
41
+ return cast(httpx.Response, parent.request(httpx.Response, options))
42
+
43
+
44
+ @contextmanager
45
+ def stream_via_browser_route(
46
+ parent: Any,
47
+ route: BrowserRoute,
48
+ method: str,
49
+ url: str,
50
+ *,
51
+ content: BrowserRawContent | None = None,
52
+ headers: Mapping[str, str] | None = None,
53
+ params: Mapping[str, object] | None = None,
54
+ timeout: float | Timeout | None | NotGiven = not_given,
55
+ ) -> Iterator[httpx.Response]:
56
+ query: dict[str, Any] = sanitize_curl_raw_params(params)
57
+ query["jwt"] = route.jwt
58
+ query["url"] = url
59
+ request_headers = {k: v for k, v in parent.default_headers.items() if isinstance(v, str)}
60
+ if content is None:
61
+ request_headers.pop("Content-Type", None)
62
+ if headers:
63
+ request_headers.update(headers)
64
+ request_headers.pop("Authorization", None)
65
+ effective_timeout = parent.timeout if isinstance(timeout, NotGiven) else timeout
66
+ with parent._client.stream(
67
+ method.upper(),
68
+ route.base_url.rstrip("/") + "/curl/raw",
69
+ params=query,
70
+ headers=request_headers,
71
+ content=_normalize_binary_content(content),
72
+ timeout=_normalize_timeout(effective_timeout),
73
+ ) as response:
74
+ yield response
75
+
76
+
77
+ async def async_request_via_browser_route(
78
+ parent: Any,
79
+ route: BrowserRoute,
80
+ method: str,
81
+ url: str,
82
+ *,
83
+ content: BrowserRawContent | None = None,
84
+ json: Body | None = None,
85
+ headers: Mapping[str, str] | None = None,
86
+ params: Mapping[str, object] | None = None,
87
+ timeout: float | Timeout | None | NotGiven = not_given,
88
+ ) -> httpx.Response:
89
+ if json is not None and content is not None:
90
+ raise TypeError("Passing both `json` and `content` is not supported")
91
+ query: dict[str, object] = {**sanitize_curl_raw_params(params), "url": url, "jwt": route.jwt}
92
+ options = FinalRequestOptions.construct(
93
+ method=method.upper(),
94
+ url=route.base_url.rstrip("/") + "/curl/raw",
95
+ params=query,
96
+ headers=headers or {},
97
+ content=_normalize_binary_content(content),
98
+ json_data=json,
99
+ timeout=_normalize_timeout(timeout),
100
+ )
101
+ return cast(httpx.Response, await parent.request(httpx.Response, options))
102
+
103
+
104
+ @asynccontextmanager
105
+ async def async_stream_via_browser_route(
106
+ parent: Any,
107
+ route: BrowserRoute,
108
+ method: str,
109
+ url: str,
110
+ *,
111
+ content: BrowserRawContent | None = None,
112
+ headers: Mapping[str, str] | None = None,
113
+ params: Mapping[str, object] | None = None,
114
+ timeout: float | Timeout | None | NotGiven = not_given,
115
+ ) -> AsyncIterator[httpx.Response]:
116
+ query: dict[str, Any] = sanitize_curl_raw_params(params)
117
+ query["jwt"] = route.jwt
118
+ query["url"] = url
119
+ request_headers = {k: v for k, v in parent.default_headers.items() if isinstance(v, str)}
120
+ if content is None:
121
+ request_headers.pop("Content-Type", None)
122
+ if headers:
123
+ request_headers.update(headers)
124
+ request_headers.pop("Authorization", None)
125
+ effective_timeout = parent.timeout if isinstance(timeout, NotGiven) else timeout
126
+ async with parent._client.stream(
127
+ method.upper(),
128
+ route.base_url.rstrip("/") + "/curl/raw",
129
+ params=query,
130
+ headers=request_headers,
131
+ content=_normalize_binary_content(content),
132
+ timeout=_normalize_timeout(effective_timeout),
133
+ ) as response:
134
+ yield response
135
+
136
+
137
+ def _normalize_timeout(timeout: float | Timeout | None | NotGiven) -> float | Timeout | None:
138
+ return None if isinstance(timeout, NotGiven) else timeout
139
+
140
+
141
+ def _normalize_binary_content(content: BrowserRawContent | None) -> bytes | IO[bytes] | Iterable[bytes] | None:
142
+ if content is None:
143
+ return None
144
+ if isinstance(content, str):
145
+ return content.encode()
146
+ if isinstance(content, bytearray):
147
+ return bytes(content)
148
+ if isinstance(content, memoryview):
149
+ return content.tobytes()
150
+ return content