withruntime 0.8.4__tar.gz → 0.9.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 (288) hide show
  1. {withruntime-0.8.4/withruntime.egg-info → withruntime-0.9.0}/PKG-INFO +10 -5
  2. {withruntime-0.8.4 → withruntime-0.9.0}/README.md +7 -4
  3. {withruntime-0.8.4 → withruntime-0.9.0}/pyproject.toml +3 -1
  4. {withruntime-0.8.4 → withruntime-0.9.0}/tests/test_client.py +43 -14
  5. withruntime-0.9.0/tests/test_compat_live.py +101 -0
  6. withruntime-0.9.0/tests/test_compat_new_providers.py +607 -0
  7. withruntime-0.9.0/tests/test_compat_python_disk_snapshots.py +159 -0
  8. withruntime-0.9.0/tests/test_compat_python_e2b_deadline.py +146 -0
  9. withruntime-0.9.0/tests/test_compat_python_e2b_pty.py +172 -0
  10. withruntime-0.9.0/tests/test_compat_python_e2b_stream.py +126 -0
  11. withruntime-0.9.0/tests/test_compat_python_e2b_watch.py +66 -0
  12. withruntime-0.9.0/tests/test_compat_python_interpreter_deadline.py +110 -0
  13. withruntime-0.9.0/tests/test_compat_python_modal.py +116 -0
  14. withruntime-0.9.0/tests/test_compat_python_official.py +668 -0
  15. withruntime-0.9.0/tests/test_compat_python_pins.py +63 -0
  16. withruntime-0.9.0/tests/test_compat_python_processes.py +274 -0
  17. withruntime-0.9.0/tests/test_compat_python_request_scope.py +179 -0
  18. withruntime-0.9.0/tests/test_compat_python_runloop.py +146 -0
  19. withruntime-0.9.0/tests/test_compat_python_shell.py +61 -0
  20. withruntime-0.9.0/tests/test_compat_python_snapshot_capture.py +86 -0
  21. withruntime-0.9.0/tests/test_compat_python_sprites.py +65 -0
  22. withruntime-0.9.0/tests/test_compat_router.py +133 -0
  23. {withruntime-0.8.4 → withruntime-0.9.0}/tests/test_e2b_code_interpreter.py +21 -13
  24. {withruntime-0.8.4 → withruntime-0.9.0}/tests/test_e2b_sandbox.py +30 -8
  25. withruntime-0.9.0/tests/test_e2b_watch.py +103 -0
  26. withruntime-0.9.0/tests/test_embed_and_webhook_watch.py +57 -0
  27. {withruntime-0.8.4 → withruntime-0.9.0}/tests/test_files_upload_parallel.py +8 -0
  28. withruntime-0.9.0/tests/test_interface_contract.py +81 -0
  29. withruntime-0.9.0/tests/test_process_deadline.py +269 -0
  30. withruntime-0.9.0/tests/test_process_input.py +50 -0
  31. withruntime-0.9.0/tests/test_process_output.py +50 -0
  32. withruntime-0.9.0/tests/test_sandbox_origin.py +53 -0
  33. withruntime-0.9.0/tests/test_start_report_kept.py +43 -0
  34. withruntime-0.9.0/tests/test_switch_image.py +74 -0
  35. withruntime-0.9.0/tests/test_tailscale.py +80 -0
  36. {withruntime-0.8.4 → withruntime-0.9.0}/tests/test_unpack.py +37 -0
  37. withruntime-0.9.0/withruntime/_api_defaults.py +21 -0
  38. {withruntime-0.8.4 → withruntime-0.9.0}/withruntime/_async_client.py +250 -80
  39. {withruntime-0.8.4 → withruntime-0.9.0}/withruntime/_async_products/__init__.py +2 -0
  40. {withruntime-0.8.4 → withruntime-0.9.0}/withruntime/_async_products/interpreter.py +40 -23
  41. {withruntime-0.8.4 → withruntime-0.9.0}/withruntime/_async_products/jobs.py +3 -2
  42. {withruntime-0.8.4 → withruntime-0.9.0}/withruntime/_async_products/limits.py +6 -3
  43. {withruntime-0.8.4 → withruntime-0.9.0}/withruntime/_async_products/previews.py +10 -3
  44. withruntime-0.9.0/withruntime/_async_products/tailscale.py +37 -0
  45. {withruntime-0.8.4 → withruntime-0.9.0}/withruntime/_async_products/watch.py +9 -2
  46. {withruntime-0.8.4 → withruntime-0.9.0}/withruntime/_clock.py +31 -2
  47. withruntime-0.9.0/withruntime/_compat.py +100 -0
  48. withruntime-0.9.0/withruntime/_compat_lifecycle.py +24 -0
  49. withruntime-0.9.0/withruntime/_compat_shell.py +166 -0
  50. {withruntime-0.8.4 → withruntime-0.9.0}/withruntime/_errors.py +8 -3
  51. {withruntime-0.8.4 → withruntime-0.9.0}/withruntime/_eval_sandbox.py +3 -1
  52. {withruntime-0.8.4 → withruntime-0.9.0}/withruntime/_http.py +237 -15
  53. withruntime-0.9.0/withruntime/_request_scope.py +84 -0
  54. {withruntime-0.8.4 → withruntime-0.9.0}/withruntime/_sync_client.py +250 -80
  55. {withruntime-0.8.4 → withruntime-0.9.0}/withruntime/_sync_products/__init__.py +2 -0
  56. {withruntime-0.8.4 → withruntime-0.9.0}/withruntime/_sync_products/interpreter.py +40 -23
  57. {withruntime-0.8.4 → withruntime-0.9.0}/withruntime/_sync_products/jobs.py +3 -2
  58. {withruntime-0.8.4 → withruntime-0.9.0}/withruntime/_sync_products/limits.py +6 -3
  59. {withruntime-0.8.4 → withruntime-0.9.0}/withruntime/_sync_products/previews.py +10 -3
  60. withruntime-0.9.0/withruntime/_sync_products/tailscale.py +38 -0
  61. {withruntime-0.8.4 → withruntime-0.9.0}/withruntime/_sync_products/watch.py +9 -2
  62. withruntime-0.9.0/withruntime/_unpack.py +265 -0
  63. withruntime-0.9.0/withruntime/_version.py +1 -0
  64. {withruntime-0.8.4 → withruntime-0.9.0}/withruntime/blaxel/_core.py +2 -1
  65. {withruntime-0.8.4 → withruntime-0.9.0}/withruntime/deepagents.py +2 -1
  66. {withruntime-0.8.4 → withruntime-0.9.0}/withruntime/e2b/__init__.py +10 -6
  67. withruntime-0.9.0/withruntime/e2b/_async_io.py +310 -0
  68. {withruntime-0.8.4 → withruntime-0.9.0}/withruntime/e2b/_async_sandbox.py +176 -74
  69. {withruntime-0.8.4 → withruntime-0.9.0}/withruntime/e2b/_core.py +63 -13
  70. withruntime-0.9.0/withruntime/e2b/_sync_io.py +245 -0
  71. {withruntime-0.8.4 → withruntime-0.9.0}/withruntime/e2b/_sync_sandbox.py +164 -79
  72. {withruntime-0.8.4 → withruntime-0.9.0}/withruntime/e2b/code_interpreter/_async_ci.py +18 -37
  73. withruntime-0.9.0/withruntime/e2b/code_interpreter/_models.py +156 -0
  74. {withruntime-0.8.4 → withruntime-0.9.0}/withruntime/e2b/code_interpreter/_sync_ci.py +18 -37
  75. withruntime-0.9.0/withruntime/e2b/code_interpreter/charts.py +120 -0
  76. withruntime-0.9.0/withruntime/e2b/sandbox/__init__.py +1 -0
  77. withruntime-0.9.0/withruntime/e2b/sandbox/commands/__init__.py +2 -0
  78. withruntime-0.9.0/withruntime/e2b/sandbox/commands/command_handle.py +5 -0
  79. withruntime-0.9.0/withruntime/e2b/sandbox/filesystem/__init__.py +2 -0
  80. withruntime-0.9.0/withruntime/e2b/sandbox/filesystem/filesystem.py +4 -0
  81. withruntime-0.9.0/withruntime/e2b/sandbox_async/__init__.py +2 -0
  82. withruntime-0.9.0/withruntime/e2b/sandbox_async/commands/__init__.py +4 -0
  83. withruntime-0.9.0/withruntime/e2b/sandbox_async/commands/command.py +2 -0
  84. withruntime-0.9.0/withruntime/e2b/sandbox_async/commands/command_handle.py +6 -0
  85. withruntime-0.9.0/withruntime/e2b/sandbox_async/commands/pty.py +3 -0
  86. withruntime-0.9.0/withruntime/e2b/sandbox_async/filesystem/__init__.py +2 -0
  87. withruntime-0.9.0/withruntime/e2b/sandbox_async/filesystem/filesystem.py +4 -0
  88. withruntime-0.9.0/withruntime/e2b/sandbox_sync/__init__.py +2 -0
  89. withruntime-0.9.0/withruntime/e2b/sandbox_sync/commands/__init__.py +4 -0
  90. withruntime-0.9.0/withruntime/e2b/sandbox_sync/commands/command.py +2 -0
  91. withruntime-0.9.0/withruntime/e2b/sandbox_sync/commands/command_handle.py +6 -0
  92. withruntime-0.9.0/withruntime/e2b/sandbox_sync/commands/pty.py +3 -0
  93. withruntime-0.9.0/withruntime/e2b/sandbox_sync/filesystem/__init__.py +2 -0
  94. withruntime-0.9.0/withruntime/e2b/sandbox_sync/filesystem/filesystem.py +4 -0
  95. withruntime-0.9.0/withruntime/modal/__init__.py +373 -0
  96. withruntime-0.9.0/withruntime/modal/_async.py +306 -0
  97. withruntime-0.9.0/withruntime/modal/_dual.py +25 -0
  98. withruntime-0.9.0/withruntime/modal/_fs_async.py +118 -0
  99. withruntime-0.9.0/withruntime/modal/_fs_common.py +39 -0
  100. withruntime-0.9.0/withruntime/modal/_fs_sync.py +118 -0
  101. withruntime-0.9.0/withruntime/modal/_lookup.py +23 -0
  102. withruntime-0.9.0/withruntime/modal/_snapshot.py +33 -0
  103. withruntime-0.9.0/withruntime/modal/exception.py +52 -0
  104. withruntime-0.9.0/withruntime/modal/sandbox_fs.py +46 -0
  105. withruntime-0.9.0/withruntime/modal/types.py +37 -0
  106. {withruntime-0.8.4 → withruntime-0.9.0}/withruntime/openai_agents.py +2 -1
  107. withruntime-0.9.0/withruntime/prime/__init__.py +67 -0
  108. withruntime-0.9.0/withruntime/prime/_async.py +298 -0
  109. withruntime-0.9.0/withruntime/prime/_sync.py +298 -0
  110. withruntime-0.9.0/withruntime/prime/core/__init__.py +4 -0
  111. withruntime-0.9.0/withruntime/prime/core/client.py +4 -0
  112. withruntime-0.9.0/withruntime/prime/exceptions.py +97 -0
  113. withruntime-0.9.0/withruntime/prime/models.py +269 -0
  114. withruntime-0.9.0/withruntime/prime/process.py +154 -0
  115. withruntime-0.9.0/withruntime/prime/sandbox.py +3 -0
  116. withruntime-0.9.0/withruntime/runloop/__init__.py +6 -0
  117. withruntime-0.9.0/withruntime/runloop/_async.py +643 -0
  118. withruntime-0.9.0/withruntime/runloop/_exceptions.py +2 -0
  119. withruntime-0.9.0/withruntime/runloop/_snapshots.py +48 -0
  120. withruntime-0.9.0/withruntime/runloop/_sync.py +643 -0
  121. withruntime-0.9.0/withruntime/runloop/lib/__init__.py +1 -0
  122. withruntime-0.9.0/withruntime/runloop/lib/polling.py +15 -0
  123. withruntime-0.9.0/withruntime/runloop/sdk/__init__.py +3 -0
  124. withruntime-0.9.0/withruntime/sprites/__init__.py +298 -0
  125. withruntime-0.9.0/withruntime/sprites/_capture.py +56 -0
  126. withruntime-0.9.0/withruntime/sprites/_capture_async.py +56 -0
  127. withruntime-0.9.0/withruntime/sprites/_metadata.py +64 -0
  128. withruntime-0.9.0/withruntime/sprites/_stream.py +68 -0
  129. withruntime-0.9.0/withruntime/sprites/_stream_async.py +67 -0
  130. withruntime-0.9.0/withruntime/sprites/async_client.py +217 -0
  131. withruntime-0.9.0/withruntime/sprites/async_exec.py +50 -0
  132. withruntime-0.9.0/withruntime/sprites/client.py +2 -0
  133. withruntime-0.9.0/withruntime/sprites/exceptions.py +25 -0
  134. withruntime-0.9.0/withruntime/sprites/exec.py +80 -0
  135. withruntime-0.9.0/withruntime/sprites/filesystem.py +2 -0
  136. withruntime-0.9.0/withruntime/sprites/sprite.py +2 -0
  137. withruntime-0.9.0/withruntime/sprites/types.py +36 -0
  138. {withruntime-0.8.4 → withruntime-0.9.0}/withruntime/tools.py +2 -1
  139. {withruntime-0.8.4 → withruntime-0.9.0/withruntime.egg-info}/PKG-INFO +10 -5
  140. {withruntime-0.8.4 → withruntime-0.9.0}/withruntime.egg-info/SOURCES.txt +97 -0
  141. {withruntime-0.8.4 → withruntime-0.9.0}/withruntime.egg-info/requires.txt +3 -0
  142. withruntime-0.8.4/withruntime/_unpack.py +0 -99
  143. withruntime-0.8.4/withruntime/_version.py +0 -1
  144. withruntime-0.8.4/withruntime/e2b/_async_io.py +0 -68
  145. withruntime-0.8.4/withruntime/e2b/_sync_io.py +0 -46
  146. withruntime-0.8.4/withruntime/e2b/code_interpreter/_models.py +0 -101
  147. {withruntime-0.8.4 → withruntime-0.9.0}/LICENSE +0 -0
  148. {withruntime-0.8.4 → withruntime-0.9.0}/setup.cfg +0 -0
  149. {withruntime-0.8.4 → withruntime-0.9.0}/tests/test_account_errors.py +0 -0
  150. {withruntime-0.8.4 → withruntime-0.9.0}/tests/test_async_stream_cleanup.py +0 -0
  151. {withruntime-0.8.4 → withruntime-0.9.0}/tests/test_audit.py +0 -0
  152. {withruntime-0.8.4 → withruntime-0.9.0}/tests/test_billing.py +0 -0
  153. {withruntime-0.8.4 → withruntime-0.9.0}/tests/test_blaxel.py +0 -0
  154. {withruntime-0.8.4 → withruntime-0.9.0}/tests/test_capacity_wait.py +0 -0
  155. {withruntime-0.8.4 → withruntime-0.9.0}/tests/test_daytona.py +0 -0
  156. {withruntime-0.8.4 → withruntime-0.9.0}/tests/test_deepagents.py +0 -0
  157. {withruntime-0.8.4 → withruntime-0.9.0}/tests/test_eval_sandbox.py +0 -0
  158. {withruntime-0.8.4 → withruntime-0.9.0}/tests/test_exec_stream.py +0 -0
  159. {withruntime-0.8.4 → withruntime-0.9.0}/tests/test_files_download.py +0 -0
  160. {withruntime-0.8.4 → withruntime-0.9.0}/tests/test_files_mode.py +0 -0
  161. {withruntime-0.8.4 → withruntime-0.9.0}/tests/test_harbor.py +0 -0
  162. {withruntime-0.8.4 → withruntime-0.9.0}/tests/test_http_tls_close.py +0 -0
  163. {withruntime-0.8.4 → withruntime-0.9.0}/tests/test_identity_token.py +0 -0
  164. {withruntime-0.8.4 → withruntime-0.9.0}/tests/test_images_v2.py +0 -0
  165. {withruntime-0.8.4 → withruntime-0.9.0}/tests/test_images_volumes_interpreter.py +0 -0
  166. {withruntime-0.8.4 → withruntime-0.9.0}/tests/test_inspect_ai.py +0 -0
  167. {withruntime-0.8.4 → withruntime-0.9.0}/tests/test_jobs.py +0 -0
  168. {withruntime-0.8.4 → withruntime-0.9.0}/tests/test_late_answer.py +0 -0
  169. {withruntime-0.8.4 → withruntime-0.9.0}/tests/test_lifecycle_settings.py +0 -0
  170. {withruntime-0.8.4 → withruntime-0.9.0}/tests/test_limits.py +0 -0
  171. {withruntime-0.8.4 → withruntime-0.9.0}/tests/test_mounts.py +0 -0
  172. {withruntime-0.8.4 → withruntime-0.9.0}/tests/test_network_funding.py +0 -0
  173. {withruntime-0.8.4 → withruntime-0.9.0}/tests/test_network_products.py +0 -0
  174. {withruntime-0.8.4 → withruntime-0.9.0}/tests/test_observability.py +0 -0
  175. {withruntime-0.8.4 → withruntime-0.9.0}/tests/test_openai_agents.py +0 -0
  176. {withruntime-0.8.4 → withruntime-0.9.0}/tests/test_previews_network_desktop.py +0 -0
  177. {withruntime-0.8.4 → withruntime-0.9.0}/tests/test_proxy.py +0 -0
  178. {withruntime-0.8.4 → withruntime-0.9.0}/tests/test_referrals.py +0 -0
  179. {withruntime-0.8.4 → withruntime-0.9.0}/tests/test_sandbox_sessions.py +0 -0
  180. {withruntime-0.8.4 → withruntime-0.9.0}/tests/test_secrets.py +0 -0
  181. {withruntime-0.8.4 → withruntime-0.9.0}/tests/test_snapshot_after_fork.py +0 -0
  182. {withruntime-0.8.4 → withruntime-0.9.0}/tests/test_sso.py +0 -0
  183. {withruntime-0.8.4 → withruntime-0.9.0}/tests/test_stream_exit_close.py +0 -0
  184. {withruntime-0.8.4 → withruntime-0.9.0}/tests/test_switching.py +0 -0
  185. {withruntime-0.8.4 → withruntime-0.9.0}/tests/test_tools.py +0 -0
  186. {withruntime-0.8.4 → withruntime-0.9.0}/tests/test_vercel.py +0 -0
  187. {withruntime-0.8.4 → withruntime-0.9.0}/tests/test_volume_backups.py +0 -0
  188. {withruntime-0.8.4 → withruntime-0.9.0}/tests/test_wake_awake.py +0 -0
  189. {withruntime-0.8.4 → withruntime-0.9.0}/tests/test_wallet.py +0 -0
  190. {withruntime-0.8.4 → withruntime-0.9.0}/tests/test_watch.py +0 -0
  191. {withruntime-0.8.4 → withruntime-0.9.0}/withruntime/__init__.py +0 -0
  192. {withruntime-0.8.4 → withruntime-0.9.0}/withruntime/_async_products/audit.py +0 -0
  193. {withruntime-0.8.4 → withruntime-0.9.0}/withruntime/_async_products/billing.py +0 -0
  194. {withruntime-0.8.4 → withruntime-0.9.0}/withruntime/_async_products/desktop.py +0 -0
  195. {withruntime-0.8.4 → withruntime-0.9.0}/withruntime/_async_products/images.py +0 -0
  196. {withruntime-0.8.4 → withruntime-0.9.0}/withruntime/_async_products/mcp.py +0 -0
  197. {withruntime-0.8.4 → withruntime-0.9.0}/withruntime/_async_products/mounts.py +0 -0
  198. {withruntime-0.8.4 → withruntime-0.9.0}/withruntime/_async_products/network.py +0 -0
  199. {withruntime-0.8.4 → withruntime-0.9.0}/withruntime/_async_products/network_products.py +0 -0
  200. {withruntime-0.8.4 → withruntime-0.9.0}/withruntime/_async_products/observability.py +0 -0
  201. {withruntime-0.8.4 → withruntime-0.9.0}/withruntime/_async_products/referrals.py +0 -0
  202. {withruntime-0.8.4 → withruntime-0.9.0}/withruntime/_async_products/secrets.py +0 -0
  203. {withruntime-0.8.4 → withruntime-0.9.0}/withruntime/_async_products/sso.py +0 -0
  204. {withruntime-0.8.4 → withruntime-0.9.0}/withruntime/_async_products/switching.py +0 -0
  205. {withruntime-0.8.4 → withruntime-0.9.0}/withruntime/_async_products/volumes.py +0 -0
  206. {withruntime-0.8.4 → withruntime-0.9.0}/withruntime/_connection.py +0 -0
  207. {withruntime-0.8.4 → withruntime-0.9.0}/withruntime/_proxy.py +0 -0
  208. {withruntime-0.8.4 → withruntime-0.9.0}/withruntime/_sync_products/audit.py +0 -0
  209. {withruntime-0.8.4 → withruntime-0.9.0}/withruntime/_sync_products/billing.py +0 -0
  210. {withruntime-0.8.4 → withruntime-0.9.0}/withruntime/_sync_products/desktop.py +0 -0
  211. {withruntime-0.8.4 → withruntime-0.9.0}/withruntime/_sync_products/images.py +0 -0
  212. {withruntime-0.8.4 → withruntime-0.9.0}/withruntime/_sync_products/mcp.py +0 -0
  213. {withruntime-0.8.4 → withruntime-0.9.0}/withruntime/_sync_products/mounts.py +0 -0
  214. {withruntime-0.8.4 → withruntime-0.9.0}/withruntime/_sync_products/network.py +0 -0
  215. {withruntime-0.8.4 → withruntime-0.9.0}/withruntime/_sync_products/network_products.py +0 -0
  216. {withruntime-0.8.4 → withruntime-0.9.0}/withruntime/_sync_products/observability.py +0 -0
  217. {withruntime-0.8.4 → withruntime-0.9.0}/withruntime/_sync_products/referrals.py +0 -0
  218. {withruntime-0.8.4 → withruntime-0.9.0}/withruntime/_sync_products/secrets.py +0 -0
  219. {withruntime-0.8.4 → withruntime-0.9.0}/withruntime/_sync_products/sso.py +0 -0
  220. {withruntime-0.8.4 → withruntime-0.9.0}/withruntime/_sync_products/switching.py +0 -0
  221. {withruntime-0.8.4 → withruntime-0.9.0}/withruntime/_sync_products/volumes.py +0 -0
  222. {withruntime-0.8.4 → withruntime-0.9.0}/withruntime/_tunnel.py +0 -0
  223. {withruntime-0.8.4 → withruntime-0.9.0}/withruntime/_ws.py +0 -0
  224. {withruntime-0.8.4 → withruntime-0.9.0}/withruntime/blaxel/__init__.py +0 -0
  225. {withruntime-0.8.4 → withruntime-0.9.0}/withruntime/blaxel/_async_io.py +0 -0
  226. {withruntime-0.8.4 → withruntime-0.9.0}/withruntime/blaxel/_async_sandbox.py +0 -0
  227. {withruntime-0.8.4 → withruntime-0.9.0}/withruntime/blaxel/_sync_io.py +0 -0
  228. {withruntime-0.8.4 → withruntime-0.9.0}/withruntime/blaxel/_sync_sandbox.py +0 -0
  229. {withruntime-0.8.4 → withruntime-0.9.0}/withruntime/blaxel/core/__init__.py +0 -0
  230. {withruntime-0.8.4 → withruntime-0.9.0}/withruntime/blaxel/core/agents.py +0 -0
  231. {withruntime-0.8.4 → withruntime-0.9.0}/withruntime/blaxel/core/client/__init__.py +0 -0
  232. {withruntime-0.8.4 → withruntime-0.9.0}/withruntime/blaxel/core/client/api/__init__.py +0 -0
  233. {withruntime-0.8.4 → withruntime-0.9.0}/withruntime/blaxel/core/client/api/applications/__init__.py +0 -0
  234. {withruntime-0.8.4 → withruntime-0.9.0}/withruntime/blaxel/core/client/api/applications/list_application_revisions.py +0 -0
  235. {withruntime-0.8.4 → withruntime-0.9.0}/withruntime/blaxel/core/client/api/compute/__init__.py +0 -0
  236. {withruntime-0.8.4 → withruntime-0.9.0}/withruntime/blaxel/core/client/api/compute/get_sandbox.py +0 -0
  237. {withruntime-0.8.4 → withruntime-0.9.0}/withruntime/blaxel/core/client/api/compute/update_sandbox.py +0 -0
  238. {withruntime-0.8.4 → withruntime-0.9.0}/withruntime/blaxel/core/client/api/functions/__init__.py +0 -0
  239. {withruntime-0.8.4 → withruntime-0.9.0}/withruntime/blaxel/core/client/api/functions/create_function.py +0 -0
  240. {withruntime-0.8.4 → withruntime-0.9.0}/withruntime/blaxel/core/client/api/images.py +0 -0
  241. {withruntime-0.8.4 → withruntime-0.9.0}/withruntime/blaxel/core/client/api/workspaces.py +0 -0
  242. {withruntime-0.8.4 → withruntime-0.9.0}/withruntime/blaxel/core/client/client.py +0 -0
  243. {withruntime-0.8.4 → withruntime-0.9.0}/withruntime/blaxel/core/client/models/__init__.py +0 -0
  244. {withruntime-0.8.4 → withruntime-0.9.0}/withruntime/blaxel/core/client/models/create_job_execution_request.py +0 -0
  245. {withruntime-0.8.4 → withruntime-0.9.0}/withruntime/blaxel/core/client/models/create_job_execution_request_env.py +0 -0
  246. {withruntime-0.8.4 → withruntime-0.9.0}/withruntime/blaxel/core/client/models/env.py +0 -0
  247. {withruntime-0.8.4 → withruntime-0.9.0}/withruntime/blaxel/core/client/models/function.py +0 -0
  248. {withruntime-0.8.4 → withruntime-0.9.0}/withruntime/blaxel/core/client/models/function_runtime.py +0 -0
  249. {withruntime-0.8.4 → withruntime-0.9.0}/withruntime/blaxel/core/client/models/function_spec.py +0 -0
  250. {withruntime-0.8.4 → withruntime-0.9.0}/withruntime/blaxel/core/client/models/metadata.py +0 -0
  251. {withruntime-0.8.4 → withruntime-0.9.0}/withruntime/blaxel/core/client/models/workspace.py +0 -0
  252. {withruntime-0.8.4 → withruntime-0.9.0}/withruntime/blaxel/core/client/types.py +0 -0
  253. {withruntime-0.8.4 → withruntime-0.9.0}/withruntime/blaxel/core/common.py +0 -0
  254. {withruntime-0.8.4 → withruntime-0.9.0}/withruntime/blaxel/core/drive.py +0 -0
  255. {withruntime-0.8.4 → withruntime-0.9.0}/withruntime/blaxel/core/jobs.py +0 -0
  256. {withruntime-0.8.4 → withruntime-0.9.0}/withruntime/blaxel/core/sandbox/__init__.py +0 -0
  257. {withruntime-0.8.4 → withruntime-0.9.0}/withruntime/blaxel/core/sandbox/types.py +0 -0
  258. {withruntime-0.8.4 → withruntime-0.9.0}/withruntime/blaxel/crewai.py +0 -0
  259. {withruntime-0.8.4 → withruntime-0.9.0}/withruntime/blaxel/googleadk.py +0 -0
  260. {withruntime-0.8.4 → withruntime-0.9.0}/withruntime/blaxel/langgraph.py +0 -0
  261. {withruntime-0.8.4 → withruntime-0.9.0}/withruntime/blaxel/livekit.py +0 -0
  262. {withruntime-0.8.4 → withruntime-0.9.0}/withruntime/blaxel/llamaindex.py +0 -0
  263. {withruntime-0.8.4 → withruntime-0.9.0}/withruntime/blaxel/openai.py +0 -0
  264. {withruntime-0.8.4 → withruntime-0.9.0}/withruntime/blaxel/pydantic.py +0 -0
  265. {withruntime-0.8.4 → withruntime-0.9.0}/withruntime/blaxel/telemetry.py +0 -0
  266. {withruntime-0.8.4 → withruntime-0.9.0}/withruntime/daytona/__init__.py +0 -0
  267. {withruntime-0.8.4 → withruntime-0.9.0}/withruntime/daytona/_async_daytona.py +0 -0
  268. {withruntime-0.8.4 → withruntime-0.9.0}/withruntime/daytona/_async_io.py +0 -0
  269. {withruntime-0.8.4 → withruntime-0.9.0}/withruntime/daytona/_core.py +0 -0
  270. {withruntime-0.8.4 → withruntime-0.9.0}/withruntime/daytona/_sync_daytona.py +0 -0
  271. {withruntime-0.8.4 → withruntime-0.9.0}/withruntime/daytona/_sync_io.py +0 -0
  272. {withruntime-0.8.4 → withruntime-0.9.0}/withruntime/e2b/code_interpreter/__init__.py +0 -0
  273. {withruntime-0.8.4 → withruntime-0.9.0}/withruntime/harbor.py +0 -0
  274. {withruntime-0.8.4 → withruntime-0.9.0}/withruntime/inspect_ai.py +0 -0
  275. {withruntime-0.8.4 → withruntime-0.9.0}/withruntime/vercel/__init__.py +0 -0
  276. {withruntime-0.8.4 → withruntime-0.9.0}/withruntime/vercel/_async_io.py +0 -0
  277. {withruntime-0.8.4 → withruntime-0.9.0}/withruntime/vercel/_async_sandbox.py +0 -0
  278. {withruntime-0.8.4 → withruntime-0.9.0}/withruntime/vercel/_core.py +0 -0
  279. {withruntime-0.8.4 → withruntime-0.9.0}/withruntime/vercel/_sync_io.py +0 -0
  280. {withruntime-0.8.4 → withruntime-0.9.0}/withruntime/vercel/_sync_sandbox.py +0 -0
  281. {withruntime-0.8.4 → withruntime-0.9.0}/withruntime/vercel/api.py +0 -0
  282. {withruntime-0.8.4 → withruntime-0.9.0}/withruntime/vercel/sandbox/__init__.py +0 -0
  283. {withruntime-0.8.4 → withruntime-0.9.0}/withruntime/vercel/sandbox/sync.py +0 -0
  284. {withruntime-0.8.4 → withruntime-0.9.0}/withruntime/wallet.py +0 -0
  285. {withruntime-0.8.4 → withruntime-0.9.0}/withruntime/webhooks.py +0 -0
  286. {withruntime-0.8.4 → withruntime-0.9.0}/withruntime.egg-info/dependency_links.txt +0 -0
  287. {withruntime-0.8.4 → withruntime-0.9.0}/withruntime.egg-info/entry_points.txt +0 -0
  288. {withruntime-0.8.4 → withruntime-0.9.0}/withruntime.egg-info/top_level.txt +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: withruntime
3
- Version: 0.8.4
3
+ Version: 0.9.0
4
4
  Summary: Runtime Cloud: one client (sync and async) for every Runtime product. Sandboxes first.
5
5
  License: Apache-2.0
6
6
  Project-URL: Homepage, https://withruntime.com
@@ -11,6 +11,8 @@ Keywords: sandbox,ai-agents,agents,microvm,firecracker,code-execution,code-inter
11
11
  Requires-Python: >=3.10
12
12
  Description-Content-Type: text/markdown
13
13
  License-File: LICENSE
14
+ Provides-Extra: e2b
15
+ Requires-Dist: httpx<1.0.0,>=0.27.0; extra == "e2b"
14
16
  Provides-Extra: openai-agents
15
17
  Requires-Dist: openai-agents>=0.22.3; extra == "openai-agents"
16
18
  Provides-Extra: deepagents
@@ -70,15 +72,18 @@ asyncio.run(main())
70
72
  A sandbox has `exec`, `exec_stream`, `spawn`, `terminal`, `forward_port` (any
71
73
  TCP port in the sandbox on a local port), `files` (read, write,
72
74
  list, glob, stat, move, remove, upload and download directories), `pause`,
73
- `wake`, `extend`, `update`, `keep_alive`, `fork` and `snapshot`, and the
75
+ `wake`, `extend`, `update` (its name, environment and settings), `keep_alive`,
76
+ `fork`, `snapshot`, `switch_image` (move it to a new image keeping /workspace)
77
+ and `delete` (remove it for good), and the
74
78
  `interpreter`, `network`, `previews`, `desktop`, `mounts` (your S3, R2 or Google
75
- Cloud Storage bucket as a folder), `metrics` and `mcp` (servers from the MCP
76
- catalog, run in the sandbox) products. A paused sandbox
79
+ Cloud Storage bucket as a folder), `tailscale` (a paid sandbox on your own
80
+ tailnet), `metrics` and `mcp` (servers from the MCP catalog, run in the
81
+ sandbox) products. A paused sandbox
77
82
  also wakes by itself on the next call, and `Sandbox.get_or_create(name)` returns
78
83
  the sandbox with that name or creates it. A sandbox pauses itself after 60 seconds
79
84
  with nothing happening in it, keeping its memory and processes, so an
80
85
  idle sandbox costs no compute; `idle_pause_seconds` sets 10 to 86,400, or 0 for
81
- never. The client has `sandboxes`, `images`, `volumes`, `snapshots`,
86
+ never. The client has `sandboxes`, `images`, `volumes`, `snapshots`, `jobs`,
82
87
  `secrets`, `limits`, `feedback` and `support`; `webhooks`, `events`, `otel` and
83
88
  `audit` to watch the account; `domains`, `ports`, `addresses`, `tunnel` and
84
89
  `network` to connect sandboxes to your own world (paid accounts); and `mcp`,
@@ -47,15 +47,18 @@ asyncio.run(main())
47
47
  A sandbox has `exec`, `exec_stream`, `spawn`, `terminal`, `forward_port` (any
48
48
  TCP port in the sandbox on a local port), `files` (read, write,
49
49
  list, glob, stat, move, remove, upload and download directories), `pause`,
50
- `wake`, `extend`, `update`, `keep_alive`, `fork` and `snapshot`, and the
50
+ `wake`, `extend`, `update` (its name, environment and settings), `keep_alive`,
51
+ `fork`, `snapshot`, `switch_image` (move it to a new image keeping /workspace)
52
+ and `delete` (remove it for good), and the
51
53
  `interpreter`, `network`, `previews`, `desktop`, `mounts` (your S3, R2 or Google
52
- Cloud Storage bucket as a folder), `metrics` and `mcp` (servers from the MCP
53
- catalog, run in the sandbox) products. A paused sandbox
54
+ Cloud Storage bucket as a folder), `tailscale` (a paid sandbox on your own
55
+ tailnet), `metrics` and `mcp` (servers from the MCP catalog, run in the
56
+ sandbox) products. A paused sandbox
54
57
  also wakes by itself on the next call, and `Sandbox.get_or_create(name)` returns
55
58
  the sandbox with that name or creates it. A sandbox pauses itself after 60 seconds
56
59
  with nothing happening in it, keeping its memory and processes, so an
57
60
  idle sandbox costs no compute; `idle_pause_seconds` sets 10 to 86,400, or 0 for
58
- never. The client has `sandboxes`, `images`, `volumes`, `snapshots`,
61
+ never. The client has `sandboxes`, `images`, `volumes`, `snapshots`, `jobs`,
59
62
  `secrets`, `limits`, `feedback` and `support`; `webhooks`, `events`, `otel` and
60
63
  `audit` to watch the account; `domains`, `ports`, `addresses`, `tunnel` and
61
64
  `network` to connect sandboxes to your own world (paid accounts); and `mcp`,
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "withruntime"
7
- version = "0.8.4"
7
+ version = "0.9.0"
8
8
  description = "Runtime Cloud: one client (sync and async) for every Runtime product. Sandboxes first."
9
9
  readme = "README.md"
10
10
  license = { text = "Apache-2.0" }
@@ -19,6 +19,8 @@ Source = "https://github.com/withruntime/runtime/tree/main/sdks/python"
19
19
  Issues = "https://github.com/withruntime/runtime/issues"
20
20
 
21
21
  [project.optional-dependencies]
22
+ # Preserve E2B's HTTP file-transfer timeout exception types.
23
+ e2b = ["httpx>=0.27.0,<1.0.0"]
22
24
  # withruntime.openai_agents: a sandbox client for the OpenAI Agents SDK's SandboxAgent.
23
25
  openai-agents = ["openai-agents>=0.22.3"]
24
26
  # withruntime.deepagents: a LangChain Deep Agents sandbox backend.
@@ -8,6 +8,7 @@ import asyncio
8
8
  import inspect
9
9
  import json
10
10
  import os
11
+ import shutil
11
12
  import subprocess
12
13
  import sys
13
14
  import tempfile
@@ -98,17 +99,19 @@ class Sync(unittest.TestCase):
98
99
  self.assertEqual([s.id for s in page], [ID])
99
100
  self.assertFalse(page.has_more)
100
101
 
101
- def test_directories_round_trip_through_tar(self):
102
- # The fake guest cannot run tar; this proves the archive the SDK builds is safe to unpack.
103
- import io, tarfile
104
- buffer = io.BytesIO()
102
+ def test_a_folder_goes_in_and_comes_back_through_the_folder_routes(self):
103
+ # The fixture runs the real tar behind the API's folder routes: the
104
+ # upload is unpacked by the sandbox, the download packed by it.
105
+ sbx = client().sandboxes.get(ID)
106
+ noise = os.urandom(1_500_000) # past 1 MiB compressed: sent in parts
105
107
  with tempfile.TemporaryDirectory() as root:
106
- Path(root, "src").mkdir()
107
- Path(root, "src", "a.py").write_text("print(1)\n")
108
- with tarfile.open(fileobj=buffer, mode="w:gz") as archive:
109
- archive.add(root, arcname=".")
110
- with tarfile.open(fileobj=io.BytesIO(buffer.getvalue()), mode="r:gz") as archive:
111
- self.assertIn("./src/a.py", archive.getnames())
108
+ Path(root, "up", "src").mkdir(parents=True)
109
+ Path(root, "up", "src", "a.py").write_text("print(1)\n")
110
+ Path(root, "up", "noise.bin").write_bytes(noise)
111
+ sbx.files.upload(str(Path(root, "up")), "/workspace/roundtrip")
112
+ sbx.files.download("/workspace/roundtrip", str(Path(root, "down")))
113
+ self.assertEqual(Path(root, "down", "src", "a.py").read_text(), "print(1)\n")
114
+ self.assertEqual(Path(root, "down", "noise.bin").read_bytes(), noise)
112
115
 
113
116
  def test_terminal_over_websocket(self):
114
117
  sbx = client().sandboxes.get(ID)
@@ -329,13 +332,39 @@ class Parity(unittest.TestCase):
329
332
  self.assertEqual(sync_methods, {m for m in async_methods if m in sync_methods | async_methods} & sync_methods | sync_methods)
330
333
  self.assertEqual(sorted(m for m in async_methods if not m.startswith("_")), sorted(sync_methods), name)
331
334
 
335
+ def test_import_leaves_heavy_modules_unloaded(self):
336
+ # asyncio is a third of the import budget and dataclasses brings inspect and
337
+ # tokenize: only the call that needs one should pay for it.
338
+ root = Path(__file__).resolve().parent.parent
339
+ loaded = subprocess.run([sys.executable, "-c", "import sys, withruntime; print(sorted(m for m in ('asyncio', 'concurrent.futures', 'dataclasses', 'inspect') if m in sys.modules))"],
340
+ env={**os.environ, "PYTHONPATH": str(root)}, capture_output=True, text=True, check=True, timeout=10)
341
+ self.assertEqual(loaded.stdout.strip(), "[]")
342
+
343
+ @unittest.skipUnless(shutil.which("python3.10"), "python3.10 is not on PATH")
344
+ def test_the_oldest_supported_python_compiles_every_module(self):
345
+ # pyproject says 3.10; the suite runs on the newest python3, whose grammar
346
+ # accepts what 3.10 refuses (withruntime.blaxel did not import on 3.10 or 3.11).
347
+ package = Path(__file__).resolve().parent.parent / "withruntime"
348
+ code = ("import pathlib, sys\n"
349
+ "for path in sorted(pathlib.Path(sys.argv[1]).rglob('*.py')):\n"
350
+ " compile(path.read_text(encoding='utf-8'), str(path), 'exec')\n")
351
+ result = subprocess.run([shutil.which("python3.10"), "-c", code, str(package)],
352
+ capture_output=True, text=True, timeout=60)
353
+ self.assertEqual(result.returncode, 0, result.stderr)
354
+
355
+ @unittest.skipIf(os.environ.get("RUNTIME_IMPORT_AFTER") == "1", "run after all SDK language suites finish")
332
356
  def test_import_is_cheap(self):
357
+ from statistics import median
333
358
  code = "import time; t=time.perf_counter(); import withruntime; print((time.perf_counter()-t)*1000)"
334
359
  root = Path(__file__).resolve().parent.parent
335
- subprocess.run([sys.executable, "-c", "import withruntime"], env={**os.environ, "PYTHONPATH": str(root)})
336
- ms = float(subprocess.run([sys.executable, "-c", code], env={**os.environ, "PYTHONPATH": str(root)},
337
- capture_output=True, text=True).stdout)
338
- self.assertLess(ms, 60)
360
+ env = {**os.environ, "PYTHONPATH": str(root)}
361
+ subprocess.run([sys.executable, "-c", "import withruntime"], env=env, check=True, timeout=10)
362
+ # Fresh interpreters measure import work; the median prevents one scheduler
363
+ # interruption from deciding the budget without hiding sustained regressions.
364
+ samples = [float(subprocess.run([sys.executable, "-c", code], env=env,
365
+ capture_output=True, text=True, check=True, timeout=10).stdout)
366
+ for _ in range(5)]
367
+ self.assertLess(median(samples), 60, f"import samples (ms): {samples}")
339
368
 
340
369
 
341
370
  @unittest.skipUnless(URL, "needs the fixture")
@@ -0,0 +1,101 @@
1
+ """Opt-in trial-only Python adapter acceptance, never part of routine CI.
2
+
3
+ RUNTIME_COMPAT_LIVE=1 PYTHONPATH=sdks/python python3 -m unittest discover \
4
+ -s sdks/python/tests -p test_compat_live.py
5
+
6
+ Creates exactly one explicitly trial-funded native sandbox for at most 120 seconds.
7
+ No image builds, persistent sandboxes, paid fallback, competitor calls, or existing
8
+ customer resources. This proves commands/files/streams/reconnection, not each
9
+ provider's create policy or image equivalence. Always stops the owned sandbox.
10
+ """
11
+ import asyncio
12
+ import hashlib
13
+ import json
14
+ import os
15
+ import unittest
16
+ import uuid
17
+ from withruntime import Runtime, AsyncRuntime
18
+ from withruntime._compat import ENV_PATH
19
+ from withruntime.runloop import RunloopSDK, Runloop, AsyncRunloop
20
+ from withruntime.prime import SandboxClient, AsyncSandboxClient
21
+ from withruntime.sprites import SpritesClient, AsyncSpritesClient
22
+ from withruntime.modal import Sandbox
23
+
24
+
25
+ @unittest.skipUnless(os.environ.get("RUNTIME_COMPAT_LIVE") == "1", "Opt-in live trial acceptance only")
26
+ class LiveTrial(unittest.TestCase):
27
+ def test_existing_sandbox_consumers(self):
28
+ api_key = os.environ.get("RUNTIME_API_KEY", "")
29
+ if not api_key.startswith("rtcloud_"):
30
+ raise ValueError("An explicit Runtime test API key is required; login fallback is disabled")
31
+ runtime = Runtime(api_key=api_key, wait_for_capacity=0)
32
+ usage = runtime.usage()
33
+ if (usage.get("trial") or {}).get("availableMs", 0) < 3_600_000:
34
+ runtime.close()
35
+ raise ValueError("At least one trial hour is required; no paid fallback")
36
+ name = "compat-python-" + uuid.uuid4().hex[:12]
37
+ sb = runtime.sandboxes.create(name=name, funding="trial", timeout_seconds=120,
38
+ idle_pause_seconds=0, on_lease_end="stop", labels={"compat.provider": "sprites"})
39
+ owned_id = sb.id
40
+ try:
41
+ self.assertEqual(sb.info.get("funding"), "trial", "Created sandbox must be trial-funded")
42
+ sb.files.write(ENV_PATH, json.dumps({"COMPAT_ENV": "persisted"}), mode=0o600)
43
+ runloop = RunloopSDK(runtime=runtime).devbox.from_id(sb.id)
44
+ result = runloop.cmd.exec("printf '%s' \"$COMPAT_ENV\"")
45
+ self.assertEqual((result.exit_code, result.stdout()), (0, "persisted"))
46
+ shell = runloop.shell("live-session")
47
+ shell.exec("mkdir -p /workspace/named && cd /workspace/named && export HELLO=world")
48
+ self.assertEqual(shell.exec('printf "%s:%s" "$PWD" "$HELLO"').stdout(), "/workspace/named:world")
49
+ reconnected = RunloopSDK(runtime=runtime).devbox.from_id(sb.id).shell("live-session")
50
+ self.assertEqual(reconnected.exec('printf "%s" "$HELLO"').stdout(), "world")
51
+ low = Runloop(runtime=runtime)
52
+ self.assertEqual(low.devboxes.execute_sync(sb.id, command="exit 7").exit_status, 7)
53
+ data = bytes(range(256)) * 4097
54
+ runloop.file.upload(path="/workspace/roundtrip", file=data)
55
+ self.assertEqual(hashlib.sha256(runloop.file.download(path="/workspace/roundtrip")).digest(), hashlib.sha256(data).digest())
56
+ prime = SandboxClient(runtime)
57
+ self.assertEqual(prime.execute_command(sb.id, 'printf "%s" "$COMPAT_ENV"').stdout, "persisted")
58
+ self.assertEqual(prime.execute_command(sb.id, "python3 -c 'print(\"x\"*100000,end=\"\")'").stdout, "x" * 100000)
59
+ prime.upload_bytes(sb.id, "/workspace/prime-text", "こんにちは".encode(), "prime-text")
60
+ self.assertEqual(prime.read_file(sb.id, "/workspace/prime-text").content, "こんにちは")
61
+ sprite = SpritesClient(runtime=runtime).get_sprite(name)
62
+ self.assertEqual(sprite.id, owned_id, "Only the sandbox created by this test may be used")
63
+ self.assertEqual(sprite.run("printf", "%s", "literal; data", capture_output=True).stdout, b"literal; data")
64
+ self.assertEqual(sprite.command("printf", "hello").output(), b"hello")
65
+ binary = sprite.command("python3", "-c", "import sys; sys.stdout.buffer.write(bytes(range(256)))").output()
66
+ self.assertEqual(binary, bytes(range(256)))
67
+ path = sprite.filesystem("/workspace") / "sprites-binary"
68
+ path.write_bytes(data)
69
+ self.assertEqual(path.read_bytes(), data)
70
+ modal = Sandbox.from_id(sb.id, client=runtime)
71
+ process = modal.exec("bash", "-c", "printf 'out'; printf 'err' >&2; exit 3")
72
+ self.assertEqual((process.stdout.read(), process.stderr.read(), process.wait()), ("out", "err", 3))
73
+ self._async_consumers(sb.id, name)
74
+ finally:
75
+ self.assertEqual(sb.id, owned_id)
76
+ sb.stop()
77
+ runtime.close()
78
+
79
+ def _async_consumers(self, sandbox_id, name):
80
+ async def run():
81
+ runtime = AsyncRuntime(api_key=os.environ["RUNTIME_API_KEY"], wait_for_capacity=0)
82
+ try:
83
+ low = AsyncRunloop(runtime=runtime)
84
+ self.assertEqual((await low.devboxes.execute_sync(sandbox_id, command="printf async")).stdout, "async")
85
+ prime = AsyncSandboxClient(runtime=runtime)
86
+ self.assertEqual((await prime.execute_command(sandbox_id, "printf prime")).stdout, "prime")
87
+ sprite = await AsyncSpritesClient(runtime=runtime).get_sprite(name)
88
+ self.assertEqual(sprite.id, sandbox_id)
89
+ self.assertEqual(await sprite.command("printf", "sprite").output(), b"sprite")
90
+ binary = await sprite.command("python3", "-c", "import sys; sys.stdout.buffer.write(bytes(range(256)))").output()
91
+ self.assertEqual(binary, bytes(range(256)))
92
+ modal = await Sandbox.from_id.aio(sandbox_id, client=runtime)
93
+ process = await modal.exec.aio("bash", "-c", "read line; printf '%s' \"$line\"")
94
+ process.stdin.write(b"input\n")
95
+ process.stdin.write_eof()
96
+ await process.stdin.drain.aio()
97
+ self.assertEqual(await process.stdout.read.aio(), "input")
98
+ self.assertEqual(await process.wait.aio(), 0)
99
+ finally:
100
+ await runtime.close()
101
+ asyncio.run(run())