e2b 2.28.0__tar.gz → 2.28.2__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 (235) hide show
  1. {e2b-2.28.0 → e2b-2.28.2}/PKG-INFO +1 -1
  2. {e2b-2.28.0 → e2b-2.28.2}/e2b/api/__init__.py +76 -4
  3. {e2b-2.28.0 → e2b-2.28.2}/e2b/api/client_async/__init__.py +16 -12
  4. {e2b-2.28.0 → e2b-2.28.2}/e2b/api/client_sync/__init__.py +14 -8
  5. {e2b-2.28.0 → e2b-2.28.2}/e2b/connection_config.py +1 -1
  6. {e2b-2.28.0 → e2b-2.28.2}/e2b/sandbox_sync/commands/command.py +19 -6
  7. {e2b-2.28.0 → e2b-2.28.2}/e2b/sandbox_sync/commands/pty.py +19 -6
  8. {e2b-2.28.0 → e2b-2.28.2}/e2b/sandbox_sync/filesystem/filesystem.py +34 -10
  9. {e2b-2.28.0 → e2b-2.28.2}/e2b/sandbox_sync/filesystem/watch_handle.py +7 -5
  10. {e2b-2.28.0 → e2b-2.28.2}/e2b/sandbox_sync/main.py +4 -12
  11. {e2b-2.28.0 → e2b-2.28.2}/e2b/template_async/build_api.py +8 -2
  12. {e2b-2.28.0 → e2b-2.28.2}/e2b/template_sync/build_api.py +8 -2
  13. {e2b-2.28.0 → e2b-2.28.2}/e2b_connect/client.py +4 -3
  14. {e2b-2.28.0 → e2b-2.28.2}/pyproject.toml +1 -1
  15. {e2b-2.28.0 → e2b-2.28.2}/LICENSE +0 -0
  16. {e2b-2.28.0 → e2b-2.28.2}/README.md +0 -0
  17. {e2b-2.28.0 → e2b-2.28.2}/e2b/__init__.py +0 -0
  18. {e2b-2.28.0 → e2b-2.28.2}/e2b/api/client/__init__.py +0 -0
  19. {e2b-2.28.0 → e2b-2.28.2}/e2b/api/client/api/__init__.py +0 -0
  20. {e2b-2.28.0 → e2b-2.28.2}/e2b/api/client/api/sandboxes/__init__.py +0 -0
  21. {e2b-2.28.0 → e2b-2.28.2}/e2b/api/client/api/sandboxes/delete_sandboxes_sandbox_id.py +0 -0
  22. {e2b-2.28.0 → e2b-2.28.2}/e2b/api/client/api/sandboxes/get_sandboxes.py +0 -0
  23. {e2b-2.28.0 → e2b-2.28.2}/e2b/api/client/api/sandboxes/get_sandboxes_metrics.py +0 -0
  24. {e2b-2.28.0 → e2b-2.28.2}/e2b/api/client/api/sandboxes/get_sandboxes_sandbox_id.py +0 -0
  25. {e2b-2.28.0 → e2b-2.28.2}/e2b/api/client/api/sandboxes/get_sandboxes_sandbox_id_logs.py +0 -0
  26. {e2b-2.28.0 → e2b-2.28.2}/e2b/api/client/api/sandboxes/get_sandboxes_sandbox_id_metrics.py +0 -0
  27. {e2b-2.28.0 → e2b-2.28.2}/e2b/api/client/api/sandboxes/get_v2_sandboxes.py +0 -0
  28. {e2b-2.28.0 → e2b-2.28.2}/e2b/api/client/api/sandboxes/get_v_2_sandboxes_sandbox_id_logs.py +0 -0
  29. {e2b-2.28.0 → e2b-2.28.2}/e2b/api/client/api/sandboxes/post_sandboxes.py +0 -0
  30. {e2b-2.28.0 → e2b-2.28.2}/e2b/api/client/api/sandboxes/post_sandboxes_sandbox_id_connect.py +0 -0
  31. {e2b-2.28.0 → e2b-2.28.2}/e2b/api/client/api/sandboxes/post_sandboxes_sandbox_id_pause.py +0 -0
  32. {e2b-2.28.0 → e2b-2.28.2}/e2b/api/client/api/sandboxes/post_sandboxes_sandbox_id_refreshes.py +0 -0
  33. {e2b-2.28.0 → e2b-2.28.2}/e2b/api/client/api/sandboxes/post_sandboxes_sandbox_id_resume.py +0 -0
  34. {e2b-2.28.0 → e2b-2.28.2}/e2b/api/client/api/sandboxes/post_sandboxes_sandbox_id_snapshots.py +0 -0
  35. {e2b-2.28.0 → e2b-2.28.2}/e2b/api/client/api/sandboxes/post_sandboxes_sandbox_id_timeout.py +0 -0
  36. {e2b-2.28.0 → e2b-2.28.2}/e2b/api/client/api/sandboxes/put_sandboxes_sandbox_id_network.py +0 -0
  37. {e2b-2.28.0 → e2b-2.28.2}/e2b/api/client/api/snapshots/__init__.py +0 -0
  38. {e2b-2.28.0 → e2b-2.28.2}/e2b/api/client/api/snapshots/get_snapshots.py +0 -0
  39. {e2b-2.28.0 → e2b-2.28.2}/e2b/api/client/api/tags/__init__.py +0 -0
  40. {e2b-2.28.0 → e2b-2.28.2}/e2b/api/client/api/tags/delete_templates_tags.py +0 -0
  41. {e2b-2.28.0 → e2b-2.28.2}/e2b/api/client/api/tags/get_templates_template_id_tags.py +0 -0
  42. {e2b-2.28.0 → e2b-2.28.2}/e2b/api/client/api/tags/post_templates_tags.py +0 -0
  43. {e2b-2.28.0 → e2b-2.28.2}/e2b/api/client/api/templates/__init__.py +0 -0
  44. {e2b-2.28.0 → e2b-2.28.2}/e2b/api/client/api/templates/delete_templates_template_id.py +0 -0
  45. {e2b-2.28.0 → e2b-2.28.2}/e2b/api/client/api/templates/get_templates.py +0 -0
  46. {e2b-2.28.0 → e2b-2.28.2}/e2b/api/client/api/templates/get_templates_aliases_alias.py +0 -0
  47. {e2b-2.28.0 → e2b-2.28.2}/e2b/api/client/api/templates/get_templates_template_id.py +0 -0
  48. {e2b-2.28.0 → e2b-2.28.2}/e2b/api/client/api/templates/get_templates_template_id_builds_build_id_logs.py +0 -0
  49. {e2b-2.28.0 → e2b-2.28.2}/e2b/api/client/api/templates/get_templates_template_id_builds_build_id_status.py +0 -0
  50. {e2b-2.28.0 → e2b-2.28.2}/e2b/api/client/api/templates/get_templates_template_id_files_hash.py +0 -0
  51. {e2b-2.28.0 → e2b-2.28.2}/e2b/api/client/api/templates/patch_templates_template_id.py +0 -0
  52. {e2b-2.28.0 → e2b-2.28.2}/e2b/api/client/api/templates/patch_v_2_templates_template_id.py +0 -0
  53. {e2b-2.28.0 → e2b-2.28.2}/e2b/api/client/api/templates/post_templates.py +0 -0
  54. {e2b-2.28.0 → e2b-2.28.2}/e2b/api/client/api/templates/post_templates_template_id.py +0 -0
  55. {e2b-2.28.0 → e2b-2.28.2}/e2b/api/client/api/templates/post_templates_template_id_builds_build_id.py +0 -0
  56. {e2b-2.28.0 → e2b-2.28.2}/e2b/api/client/api/templates/post_v2_templates.py +0 -0
  57. {e2b-2.28.0 → e2b-2.28.2}/e2b/api/client/api/templates/post_v3_templates.py +0 -0
  58. {e2b-2.28.0 → e2b-2.28.2}/e2b/api/client/api/templates/post_v_2_templates_template_id_builds_build_id.py +0 -0
  59. {e2b-2.28.0 → e2b-2.28.2}/e2b/api/client/api/volumes/__init__.py +0 -0
  60. {e2b-2.28.0 → e2b-2.28.2}/e2b/api/client/api/volumes/delete_volumes_volume_id.py +0 -0
  61. {e2b-2.28.0 → e2b-2.28.2}/e2b/api/client/api/volumes/get_volumes.py +0 -0
  62. {e2b-2.28.0 → e2b-2.28.2}/e2b/api/client/api/volumes/get_volumes_volume_id.py +0 -0
  63. {e2b-2.28.0 → e2b-2.28.2}/e2b/api/client/api/volumes/post_volumes.py +0 -0
  64. {e2b-2.28.0 → e2b-2.28.2}/e2b/api/client/client.py +0 -0
  65. {e2b-2.28.0 → e2b-2.28.2}/e2b/api/client/errors.py +0 -0
  66. {e2b-2.28.0 → e2b-2.28.2}/e2b/api/client/models/__init__.py +0 -0
  67. {e2b-2.28.0 → e2b-2.28.2}/e2b/api/client/models/admin_build_cancel_result.py +0 -0
  68. {e2b-2.28.0 → e2b-2.28.2}/e2b/api/client/models/admin_sandbox_kill_result.py +0 -0
  69. {e2b-2.28.0 → e2b-2.28.2}/e2b/api/client/models/assign_template_tags_request.py +0 -0
  70. {e2b-2.28.0 → e2b-2.28.2}/e2b/api/client/models/assigned_template_tags.py +0 -0
  71. {e2b-2.28.0 → e2b-2.28.2}/e2b/api/client/models/aws_registry.py +0 -0
  72. {e2b-2.28.0 → e2b-2.28.2}/e2b/api/client/models/aws_registry_type.py +0 -0
  73. {e2b-2.28.0 → e2b-2.28.2}/e2b/api/client/models/build_log_entry.py +0 -0
  74. {e2b-2.28.0 → e2b-2.28.2}/e2b/api/client/models/build_status_reason.py +0 -0
  75. {e2b-2.28.0 → e2b-2.28.2}/e2b/api/client/models/connect_sandbox.py +0 -0
  76. {e2b-2.28.0 → e2b-2.28.2}/e2b/api/client/models/created_access_token.py +0 -0
  77. {e2b-2.28.0 → e2b-2.28.2}/e2b/api/client/models/created_team_api_key.py +0 -0
  78. {e2b-2.28.0 → e2b-2.28.2}/e2b/api/client/models/delete_template_tags_request.py +0 -0
  79. {e2b-2.28.0 → e2b-2.28.2}/e2b/api/client/models/disk_metrics.py +0 -0
  80. {e2b-2.28.0 → e2b-2.28.2}/e2b/api/client/models/error.py +0 -0
  81. {e2b-2.28.0 → e2b-2.28.2}/e2b/api/client/models/gcp_registry.py +0 -0
  82. {e2b-2.28.0 → e2b-2.28.2}/e2b/api/client/models/gcp_registry_type.py +0 -0
  83. {e2b-2.28.0 → e2b-2.28.2}/e2b/api/client/models/general_registry.py +0 -0
  84. {e2b-2.28.0 → e2b-2.28.2}/e2b/api/client/models/general_registry_type.py +0 -0
  85. {e2b-2.28.0 → e2b-2.28.2}/e2b/api/client/models/identifier_masking_details.py +0 -0
  86. {e2b-2.28.0 → e2b-2.28.2}/e2b/api/client/models/listed_sandbox.py +0 -0
  87. {e2b-2.28.0 → e2b-2.28.2}/e2b/api/client/models/log_level.py +0 -0
  88. {e2b-2.28.0 → e2b-2.28.2}/e2b/api/client/models/logs_direction.py +0 -0
  89. {e2b-2.28.0 → e2b-2.28.2}/e2b/api/client/models/logs_source.py +0 -0
  90. {e2b-2.28.0 → e2b-2.28.2}/e2b/api/client/models/machine_info.py +0 -0
  91. {e2b-2.28.0 → e2b-2.28.2}/e2b/api/client/models/max_team_metric.py +0 -0
  92. {e2b-2.28.0 → e2b-2.28.2}/e2b/api/client/models/mcp_type_0.py +0 -0
  93. {e2b-2.28.0 → e2b-2.28.2}/e2b/api/client/models/new_access_token.py +0 -0
  94. {e2b-2.28.0 → e2b-2.28.2}/e2b/api/client/models/new_sandbox.py +0 -0
  95. {e2b-2.28.0 → e2b-2.28.2}/e2b/api/client/models/new_team_api_key.py +0 -0
  96. {e2b-2.28.0 → e2b-2.28.2}/e2b/api/client/models/new_volume.py +0 -0
  97. {e2b-2.28.0 → e2b-2.28.2}/e2b/api/client/models/node.py +0 -0
  98. {e2b-2.28.0 → e2b-2.28.2}/e2b/api/client/models/node_detail.py +0 -0
  99. {e2b-2.28.0 → e2b-2.28.2}/e2b/api/client/models/node_metrics.py +0 -0
  100. {e2b-2.28.0 → e2b-2.28.2}/e2b/api/client/models/node_status.py +0 -0
  101. {e2b-2.28.0 → e2b-2.28.2}/e2b/api/client/models/node_status_change.py +0 -0
  102. {e2b-2.28.0 → e2b-2.28.2}/e2b/api/client/models/post_sandboxes_sandbox_id_refreshes_body.py +0 -0
  103. {e2b-2.28.0 → e2b-2.28.2}/e2b/api/client/models/post_sandboxes_sandbox_id_snapshots_body.py +0 -0
  104. {e2b-2.28.0 → e2b-2.28.2}/e2b/api/client/models/post_sandboxes_sandbox_id_timeout_body.py +0 -0
  105. {e2b-2.28.0 → e2b-2.28.2}/e2b/api/client/models/resumed_sandbox.py +0 -0
  106. {e2b-2.28.0 → e2b-2.28.2}/e2b/api/client/models/sandbox.py +0 -0
  107. {e2b-2.28.0 → e2b-2.28.2}/e2b/api/client/models/sandbox_auto_resume_config.py +0 -0
  108. {e2b-2.28.0 → e2b-2.28.2}/e2b/api/client/models/sandbox_detail.py +0 -0
  109. {e2b-2.28.0 → e2b-2.28.2}/e2b/api/client/models/sandbox_lifecycle.py +0 -0
  110. {e2b-2.28.0 → e2b-2.28.2}/e2b/api/client/models/sandbox_log.py +0 -0
  111. {e2b-2.28.0 → e2b-2.28.2}/e2b/api/client/models/sandbox_log_entry.py +0 -0
  112. {e2b-2.28.0 → e2b-2.28.2}/e2b/api/client/models/sandbox_log_entry_fields.py +0 -0
  113. {e2b-2.28.0 → e2b-2.28.2}/e2b/api/client/models/sandbox_logs.py +0 -0
  114. {e2b-2.28.0 → e2b-2.28.2}/e2b/api/client/models/sandbox_logs_v2_response.py +0 -0
  115. {e2b-2.28.0 → e2b-2.28.2}/e2b/api/client/models/sandbox_metric.py +0 -0
  116. {e2b-2.28.0 → e2b-2.28.2}/e2b/api/client/models/sandbox_network_config.py +0 -0
  117. {e2b-2.28.0 → e2b-2.28.2}/e2b/api/client/models/sandbox_network_config_rules.py +0 -0
  118. {e2b-2.28.0 → e2b-2.28.2}/e2b/api/client/models/sandbox_network_rule.py +0 -0
  119. {e2b-2.28.0 → e2b-2.28.2}/e2b/api/client/models/sandbox_network_transform.py +0 -0
  120. {e2b-2.28.0 → e2b-2.28.2}/e2b/api/client/models/sandbox_network_transform_headers.py +0 -0
  121. {e2b-2.28.0 → e2b-2.28.2}/e2b/api/client/models/sandbox_network_update_config.py +0 -0
  122. {e2b-2.28.0 → e2b-2.28.2}/e2b/api/client/models/sandbox_network_update_config_rules.py +0 -0
  123. {e2b-2.28.0 → e2b-2.28.2}/e2b/api/client/models/sandbox_on_timeout.py +0 -0
  124. {e2b-2.28.0 → e2b-2.28.2}/e2b/api/client/models/sandbox_state.py +0 -0
  125. {e2b-2.28.0 → e2b-2.28.2}/e2b/api/client/models/sandbox_volume_mount.py +0 -0
  126. {e2b-2.28.0 → e2b-2.28.2}/e2b/api/client/models/sandboxes_with_metrics.py +0 -0
  127. {e2b-2.28.0 → e2b-2.28.2}/e2b/api/client/models/snapshot_info.py +0 -0
  128. {e2b-2.28.0 → e2b-2.28.2}/e2b/api/client/models/team.py +0 -0
  129. {e2b-2.28.0 → e2b-2.28.2}/e2b/api/client/models/team_api_key.py +0 -0
  130. {e2b-2.28.0 → e2b-2.28.2}/e2b/api/client/models/team_metric.py +0 -0
  131. {e2b-2.28.0 → e2b-2.28.2}/e2b/api/client/models/team_user.py +0 -0
  132. {e2b-2.28.0 → e2b-2.28.2}/e2b/api/client/models/template.py +0 -0
  133. {e2b-2.28.0 → e2b-2.28.2}/e2b/api/client/models/template_alias_response.py +0 -0
  134. {e2b-2.28.0 → e2b-2.28.2}/e2b/api/client/models/template_build.py +0 -0
  135. {e2b-2.28.0 → e2b-2.28.2}/e2b/api/client/models/template_build_file_upload.py +0 -0
  136. {e2b-2.28.0 → e2b-2.28.2}/e2b/api/client/models/template_build_info.py +0 -0
  137. {e2b-2.28.0 → e2b-2.28.2}/e2b/api/client/models/template_build_logs_response.py +0 -0
  138. {e2b-2.28.0 → e2b-2.28.2}/e2b/api/client/models/template_build_request.py +0 -0
  139. {e2b-2.28.0 → e2b-2.28.2}/e2b/api/client/models/template_build_request_v2.py +0 -0
  140. {e2b-2.28.0 → e2b-2.28.2}/e2b/api/client/models/template_build_request_v3.py +0 -0
  141. {e2b-2.28.0 → e2b-2.28.2}/e2b/api/client/models/template_build_start_v2.py +0 -0
  142. {e2b-2.28.0 → e2b-2.28.2}/e2b/api/client/models/template_build_status.py +0 -0
  143. {e2b-2.28.0 → e2b-2.28.2}/e2b/api/client/models/template_legacy.py +0 -0
  144. {e2b-2.28.0 → e2b-2.28.2}/e2b/api/client/models/template_request_response_v3.py +0 -0
  145. {e2b-2.28.0 → e2b-2.28.2}/e2b/api/client/models/template_step.py +0 -0
  146. {e2b-2.28.0 → e2b-2.28.2}/e2b/api/client/models/template_tag.py +0 -0
  147. {e2b-2.28.0 → e2b-2.28.2}/e2b/api/client/models/template_update_request.py +0 -0
  148. {e2b-2.28.0 → e2b-2.28.2}/e2b/api/client/models/template_update_response.py +0 -0
  149. {e2b-2.28.0 → e2b-2.28.2}/e2b/api/client/models/template_with_builds.py +0 -0
  150. {e2b-2.28.0 → e2b-2.28.2}/e2b/api/client/models/update_team_api_key.py +0 -0
  151. {e2b-2.28.0 → e2b-2.28.2}/e2b/api/client/models/volume.py +0 -0
  152. {e2b-2.28.0 → e2b-2.28.2}/e2b/api/client/models/volume_and_token.py +0 -0
  153. {e2b-2.28.0 → e2b-2.28.2}/e2b/api/client/models/volume_token.py +0 -0
  154. {e2b-2.28.0 → e2b-2.28.2}/e2b/api/client/py.typed +0 -0
  155. {e2b-2.28.0 → e2b-2.28.2}/e2b/api/client/types.py +0 -0
  156. {e2b-2.28.0 → e2b-2.28.2}/e2b/api/metadata.py +0 -0
  157. {e2b-2.28.0 → e2b-2.28.2}/e2b/envd/api.py +0 -0
  158. {e2b-2.28.0 → e2b-2.28.2}/e2b/envd/filesystem/filesystem_connect.py +0 -0
  159. {e2b-2.28.0 → e2b-2.28.2}/e2b/envd/filesystem/filesystem_pb2.py +0 -0
  160. {e2b-2.28.0 → e2b-2.28.2}/e2b/envd/filesystem/filesystem_pb2.pyi +0 -0
  161. {e2b-2.28.0 → e2b-2.28.2}/e2b/envd/process/process_connect.py +0 -0
  162. {e2b-2.28.0 → e2b-2.28.2}/e2b/envd/process/process_pb2.py +0 -0
  163. {e2b-2.28.0 → e2b-2.28.2}/e2b/envd/process/process_pb2.pyi +0 -0
  164. {e2b-2.28.0 → e2b-2.28.2}/e2b/envd/rpc.py +0 -0
  165. {e2b-2.28.0 → e2b-2.28.2}/e2b/envd/versions.py +0 -0
  166. {e2b-2.28.0 → e2b-2.28.2}/e2b/exceptions.py +0 -0
  167. {e2b-2.28.0 → e2b-2.28.2}/e2b/py.typed +0 -0
  168. {e2b-2.28.0 → e2b-2.28.2}/e2b/sandbox/_git/__init__.py +0 -0
  169. {e2b-2.28.0 → e2b-2.28.2}/e2b/sandbox/_git/args.py +0 -0
  170. {e2b-2.28.0 → e2b-2.28.2}/e2b/sandbox/_git/auth.py +0 -0
  171. {e2b-2.28.0 → e2b-2.28.2}/e2b/sandbox/_git/config.py +0 -0
  172. {e2b-2.28.0 → e2b-2.28.2}/e2b/sandbox/_git/parse.py +0 -0
  173. {e2b-2.28.0 → e2b-2.28.2}/e2b/sandbox/_git/types.py +0 -0
  174. {e2b-2.28.0 → e2b-2.28.2}/e2b/sandbox/commands/command_handle.py +0 -0
  175. {e2b-2.28.0 → e2b-2.28.2}/e2b/sandbox/commands/main.py +0 -0
  176. {e2b-2.28.0 → e2b-2.28.2}/e2b/sandbox/filesystem/filesystem.py +0 -0
  177. {e2b-2.28.0 → e2b-2.28.2}/e2b/sandbox/filesystem/watch_handle.py +0 -0
  178. {e2b-2.28.0 → e2b-2.28.2}/e2b/sandbox/main.py +0 -0
  179. {e2b-2.28.0 → e2b-2.28.2}/e2b/sandbox/mcp.py +0 -0
  180. {e2b-2.28.0 → e2b-2.28.2}/e2b/sandbox/network.py +0 -0
  181. {e2b-2.28.0 → e2b-2.28.2}/e2b/sandbox/sandbox_api.py +0 -0
  182. {e2b-2.28.0 → e2b-2.28.2}/e2b/sandbox/signature.py +0 -0
  183. {e2b-2.28.0 → e2b-2.28.2}/e2b/sandbox/utils.py +0 -0
  184. {e2b-2.28.0 → e2b-2.28.2}/e2b/sandbox_async/commands/command.py +0 -0
  185. {e2b-2.28.0 → e2b-2.28.2}/e2b/sandbox_async/commands/command_handle.py +0 -0
  186. {e2b-2.28.0 → e2b-2.28.2}/e2b/sandbox_async/commands/pty.py +0 -0
  187. {e2b-2.28.0 → e2b-2.28.2}/e2b/sandbox_async/filesystem/filesystem.py +0 -0
  188. {e2b-2.28.0 → e2b-2.28.2}/e2b/sandbox_async/filesystem/watch_handle.py +0 -0
  189. {e2b-2.28.0 → e2b-2.28.2}/e2b/sandbox_async/git.py +0 -0
  190. {e2b-2.28.0 → e2b-2.28.2}/e2b/sandbox_async/main.py +0 -0
  191. {e2b-2.28.0 → e2b-2.28.2}/e2b/sandbox_async/paginator.py +0 -0
  192. {e2b-2.28.0 → e2b-2.28.2}/e2b/sandbox_async/sandbox_api.py +0 -0
  193. {e2b-2.28.0 → e2b-2.28.2}/e2b/sandbox_async/utils.py +0 -0
  194. {e2b-2.28.0 → e2b-2.28.2}/e2b/sandbox_domains.py +0 -0
  195. {e2b-2.28.0 → e2b-2.28.2}/e2b/sandbox_sync/commands/command_handle.py +0 -0
  196. {e2b-2.28.0 → e2b-2.28.2}/e2b/sandbox_sync/git.py +0 -0
  197. {e2b-2.28.0 → e2b-2.28.2}/e2b/sandbox_sync/paginator.py +0 -0
  198. {e2b-2.28.0 → e2b-2.28.2}/e2b/sandbox_sync/sandbox_api.py +0 -0
  199. {e2b-2.28.0 → e2b-2.28.2}/e2b/template/consts.py +0 -0
  200. {e2b-2.28.0 → e2b-2.28.2}/e2b/template/dockerfile_parser.py +0 -0
  201. {e2b-2.28.0 → e2b-2.28.2}/e2b/template/logger.py +0 -0
  202. {e2b-2.28.0 → e2b-2.28.2}/e2b/template/main.py +0 -0
  203. {e2b-2.28.0 → e2b-2.28.2}/e2b/template/readycmd.py +0 -0
  204. {e2b-2.28.0 → e2b-2.28.2}/e2b/template/types.py +0 -0
  205. {e2b-2.28.0 → e2b-2.28.2}/e2b/template/utils.py +0 -0
  206. {e2b-2.28.0 → e2b-2.28.2}/e2b/template_async/main.py +0 -0
  207. {e2b-2.28.0 → e2b-2.28.2}/e2b/template_sync/main.py +0 -0
  208. {e2b-2.28.0 → e2b-2.28.2}/e2b/volume/client/__init__.py +0 -0
  209. {e2b-2.28.0 → e2b-2.28.2}/e2b/volume/client/api/__init__.py +0 -0
  210. {e2b-2.28.0 → e2b-2.28.2}/e2b/volume/client/api/volumes/__init__.py +0 -0
  211. {e2b-2.28.0 → e2b-2.28.2}/e2b/volume/client/api/volumes/delete_volumecontent_volume_id_path.py +0 -0
  212. {e2b-2.28.0 → e2b-2.28.2}/e2b/volume/client/api/volumes/get_volumecontent_volume_id_dir.py +0 -0
  213. {e2b-2.28.0 → e2b-2.28.2}/e2b/volume/client/api/volumes/get_volumecontent_volume_id_file.py +0 -0
  214. {e2b-2.28.0 → e2b-2.28.2}/e2b/volume/client/api/volumes/get_volumecontent_volume_id_path.py +0 -0
  215. {e2b-2.28.0 → e2b-2.28.2}/e2b/volume/client/api/volumes/patch_volumecontent_volume_id_path.py +0 -0
  216. {e2b-2.28.0 → e2b-2.28.2}/e2b/volume/client/api/volumes/post_volumecontent_volume_id_dir.py +0 -0
  217. {e2b-2.28.0 → e2b-2.28.2}/e2b/volume/client/api/volumes/put_volumecontent_volume_id_file.py +0 -0
  218. {e2b-2.28.0 → e2b-2.28.2}/e2b/volume/client/client.py +0 -0
  219. {e2b-2.28.0 → e2b-2.28.2}/e2b/volume/client/errors.py +0 -0
  220. {e2b-2.28.0 → e2b-2.28.2}/e2b/volume/client/models/__init__.py +0 -0
  221. {e2b-2.28.0 → e2b-2.28.2}/e2b/volume/client/models/error.py +0 -0
  222. {e2b-2.28.0 → e2b-2.28.2}/e2b/volume/client/models/patch_volumecontent_volume_id_path_body.py +0 -0
  223. {e2b-2.28.0 → e2b-2.28.2}/e2b/volume/client/models/volume_entry_stat.py +0 -0
  224. {e2b-2.28.0 → e2b-2.28.2}/e2b/volume/client/models/volume_entry_stat_type.py +0 -0
  225. {e2b-2.28.0 → e2b-2.28.2}/e2b/volume/client/py.typed +0 -0
  226. {e2b-2.28.0 → e2b-2.28.2}/e2b/volume/client/types.py +0 -0
  227. {e2b-2.28.0 → e2b-2.28.2}/e2b/volume/client_async/__init__.py +0 -0
  228. {e2b-2.28.0 → e2b-2.28.2}/e2b/volume/client_sync/__init__.py +0 -0
  229. {e2b-2.28.0 → e2b-2.28.2}/e2b/volume/connection_config.py +0 -0
  230. {e2b-2.28.0 → e2b-2.28.2}/e2b/volume/types.py +0 -0
  231. {e2b-2.28.0 → e2b-2.28.2}/e2b/volume/utils.py +0 -0
  232. {e2b-2.28.0 → e2b-2.28.2}/e2b/volume/volume_async.py +0 -0
  233. {e2b-2.28.0 → e2b-2.28.2}/e2b/volume/volume_sync.py +0 -0
  234. {e2b-2.28.0 → e2b-2.28.2}/e2b_connect/__init__.py +0 -0
  235. {e2b-2.28.0 → e2b-2.28.2}/e2b_connect/py.typed +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: e2b
3
- Version: 2.28.0
3
+ Version: 2.28.2
4
4
  Summary: E2B SDK that give agents cloud environments
5
5
  License: MIT
6
6
  Author: e2b
@@ -1,12 +1,15 @@
1
+ import asyncio
1
2
  import json
2
3
  import logging
3
4
  import os
4
5
  import re
6
+ import threading
5
7
  from dataclasses import dataclass
6
8
  from types import TracebackType
7
- from typing import Optional, Protocol, Union
9
+ from typing import Callable, Dict, Optional, Protocol, Union
8
10
 
9
- from httpx import AsyncBaseTransport, BaseTransport, Limits
11
+ import httpx
12
+ from httpx import AsyncBaseTransport, BaseTransport, Limits, Timeout
10
13
 
11
14
  from e2b.api.client.client import AuthenticatedClient
12
15
  from e2b.api.client.types import Response
@@ -102,9 +105,22 @@ class ApiClient(AuthenticatedClient):
102
105
  require_api_key: bool = True,
103
106
  require_access_token: bool = False,
104
107
  transport: Optional[Union[BaseTransport, AsyncBaseTransport]] = None,
108
+ transport_factory: Optional[Callable[[], BaseTransport]] = None,
109
+ async_transport_factory: Optional[Callable[[], AsyncBaseTransport]] = None,
105
110
  *args,
106
111
  **kwargs,
107
112
  ):
113
+ if transport is not None and (
114
+ transport_factory is not None or async_transport_factory is not None
115
+ ):
116
+ raise ValueError("Use either transport or transport_factory, not both")
117
+
118
+ self._transport_factory = transport_factory
119
+ self._async_transport_factory = async_transport_factory
120
+ self._thread_local = threading.local()
121
+ self._async_clients: Dict[int, httpx.AsyncClient] = {}
122
+ self._proxy = config.proxy
123
+
108
124
  if require_api_key and require_access_token:
109
125
  raise AuthenticationException(
110
126
  "Only one of api_key or access_token can be required, not both",
@@ -157,11 +173,20 @@ class ApiClient(AuthenticatedClient):
157
173
  "request": [self._log_request],
158
174
  "response": [self._log_response],
159
175
  },
160
- "transport": transport,
161
176
  }
162
- if transport is None:
177
+ if transport is not None:
178
+ httpx_args["transport"] = transport
179
+ if (
180
+ transport is None
181
+ and transport_factory is None
182
+ and async_transport_factory is None
183
+ ):
163
184
  httpx_args["proxy"] = config.proxy
164
185
 
186
+ # config.request_timeout is None when the timeout is explicitly
187
+ # disabled (request_timeout=0), which httpx.Timeout(None) preserves.
188
+ kwargs.setdefault("timeout", Timeout(config.request_timeout))
189
+
165
190
  super().__init__(
166
191
  base_url=config.api_url,
167
192
  httpx_args=httpx_args,
@@ -173,6 +198,53 @@ class ApiClient(AuthenticatedClient):
173
198
  **kwargs,
174
199
  )
175
200
 
201
+ def _headers_with_auth(self) -> dict:
202
+ return {
203
+ **self._headers,
204
+ self.auth_header_name: (
205
+ f"{self.prefix} {self.token}" if self.prefix else self.token
206
+ ),
207
+ }
208
+
209
+ def get_httpx_client(self) -> httpx.Client:
210
+ if self._client is not None or self._transport_factory is None:
211
+ return super().get_httpx_client()
212
+
213
+ client = getattr(self._thread_local, "client", None)
214
+ if client is None:
215
+ client = httpx.Client(
216
+ base_url=self._base_url,
217
+ cookies=self._cookies,
218
+ headers=self._headers_with_auth(),
219
+ timeout=self._timeout,
220
+ verify=self._verify_ssl,
221
+ follow_redirects=self._follow_redirects,
222
+ event_hooks=self._httpx_args.get("event_hooks"),
223
+ transport=self._transport_factory(),
224
+ )
225
+ self._thread_local.client = client
226
+ return client
227
+
228
+ def get_async_httpx_client(self) -> httpx.AsyncClient:
229
+ if self._async_client is not None or self._async_transport_factory is None:
230
+ return super().get_async_httpx_client()
231
+
232
+ loop_id = id(asyncio.get_running_loop())
233
+ client = self._async_clients.get(loop_id)
234
+ if client is None:
235
+ client = httpx.AsyncClient(
236
+ base_url=self._base_url,
237
+ cookies=self._cookies,
238
+ headers=self._headers_with_auth(),
239
+ timeout=self._timeout,
240
+ verify=self._verify_ssl,
241
+ follow_redirects=self._follow_redirects,
242
+ event_hooks=self._httpx_args.get("event_hooks"),
243
+ transport=self._async_transport_factory(),
244
+ )
245
+ self._async_clients[loop_id] = client
246
+ return client
247
+
176
248
  def _log_request(self, request):
177
249
  logger.info(f"Request {request.method} {request.url}")
178
250
 
@@ -1,25 +1,29 @@
1
1
  import asyncio
2
2
  import logging
3
- from typing import Dict, Tuple
3
+ from typing import Dict, Optional, Tuple
4
4
 
5
5
  import httpx
6
6
 
7
+ from httpx._types import ProxyTypes
8
+
7
9
  from e2b.api import AsyncApiClient, limits
8
10
  from e2b.connection_config import ConnectionConfig
9
11
 
10
12
  logger = logging.getLogger(__name__)
11
13
 
14
+ TransportKey = Tuple[int, bool, Optional[ProxyTypes]]
15
+
12
16
 
13
17
  def get_api_client(config: ConnectionConfig, **kwargs) -> AsyncApiClient:
14
18
  return AsyncApiClient(
15
19
  config,
16
- transport=get_transport(config),
20
+ async_transport_factory=lambda: get_transport(config),
17
21
  **kwargs,
18
22
  )
19
23
 
20
24
 
21
25
  class AsyncTransportWithLogger(httpx.AsyncHTTPTransport):
22
- _instances: Dict[Tuple[int, bool], "AsyncTransportWithLogger"] = {}
26
+ _instances: Dict[TransportKey, "AsyncTransportWithLogger"] = {}
23
27
 
24
28
  async def handle_async_request(self, request):
25
29
  url = f"{request.url.scheme}://{request.url.host}{request.url.path}"
@@ -39,10 +43,10 @@ class AsyncTransportWithLogger(httpx.AsyncHTTPTransport):
39
43
  def get_transport(
40
44
  config: ConnectionConfig, http2: bool = True
41
45
  ) -> AsyncTransportWithLogger:
42
- loop_id = (id(asyncio.get_running_loop()), http2)
46
+ key: TransportKey = (id(asyncio.get_running_loop()), http2, config.proxy)
43
47
 
44
- if loop_id in AsyncTransportWithLogger._instances:
45
- return AsyncTransportWithLogger._instances[loop_id]
48
+ if key in AsyncTransportWithLogger._instances:
49
+ return AsyncTransportWithLogger._instances[key]
46
50
 
47
51
  transport = AsyncTransportWithLogger(
48
52
  limits=limits,
@@ -50,21 +54,21 @@ def get_transport(
50
54
  http2=http2,
51
55
  )
52
56
 
53
- AsyncTransportWithLogger._instances[loop_id] = transport
57
+ AsyncTransportWithLogger._instances[key] = transport
54
58
  return transport
55
59
 
56
60
 
57
61
  class AsyncEnvdTransportWithLogger(AsyncTransportWithLogger):
58
- _instances: Dict[Tuple[int, bool], "AsyncEnvdTransportWithLogger"] = {}
62
+ _instances: Dict[TransportKey, "AsyncEnvdTransportWithLogger"] = {}
59
63
 
60
64
 
61
65
  def get_envd_transport(
62
66
  config: ConnectionConfig, http2: bool = True
63
67
  ) -> AsyncEnvdTransportWithLogger:
64
- loop_id = (id(asyncio.get_running_loop()), http2)
68
+ key: TransportKey = (id(asyncio.get_running_loop()), http2, config.proxy)
65
69
 
66
- if loop_id in AsyncEnvdTransportWithLogger._instances:
67
- return AsyncEnvdTransportWithLogger._instances[loop_id]
70
+ if key in AsyncEnvdTransportWithLogger._instances:
71
+ return AsyncEnvdTransportWithLogger._instances[key]
68
72
 
69
73
  transport = AsyncEnvdTransportWithLogger(
70
74
  limits=limits,
@@ -72,5 +76,5 @@ def get_envd_transport(
72
76
  http2=http2,
73
77
  )
74
78
 
75
- AsyncEnvdTransportWithLogger._instances[loop_id] = transport
79
+ AsyncEnvdTransportWithLogger._instances[key] = transport
76
80
  return transport
@@ -1,19 +1,23 @@
1
- from typing import Dict
1
+ from typing import Dict, Optional, Tuple
2
2
 
3
3
  import httpx
4
4
  import logging
5
5
  import threading
6
6
 
7
+ from httpx._types import ProxyTypes
8
+
7
9
  from e2b.api import ApiClient, limits
8
10
  from e2b.connection_config import ConnectionConfig
9
11
 
10
12
  logger = logging.getLogger(__name__)
11
13
 
14
+ TransportKey = Tuple[bool, Optional[ProxyTypes]]
15
+
12
16
 
13
17
  def get_api_client(config: ConnectionConfig, **kwargs) -> ApiClient:
14
18
  return ApiClient(
15
19
  config,
16
- transport=get_transport(config),
20
+ transport_factory=lambda: get_transport(config),
17
21
  **kwargs,
18
22
  )
19
23
 
@@ -37,10 +41,11 @@ class TransportWithLogger(httpx.HTTPTransport):
37
41
 
38
42
 
39
43
  def get_transport(config: ConnectionConfig, http2: bool = True) -> TransportWithLogger:
40
- instances: Dict[bool, TransportWithLogger] = getattr(
44
+ instances: Dict[TransportKey, TransportWithLogger] = getattr(
41
45
  TransportWithLogger._thread_local, "instances", {}
42
46
  )
43
- cached = instances.get(http2)
47
+ key: TransportKey = (http2, config.proxy)
48
+ cached = instances.get(key)
44
49
  if cached is not None:
45
50
  return cached
46
51
 
@@ -49,7 +54,7 @@ def get_transport(config: ConnectionConfig, http2: bool = True) -> TransportWith
49
54
  proxy=config.proxy,
50
55
  http2=http2,
51
56
  )
52
- instances[http2] = transport
57
+ instances[key] = transport
53
58
  TransportWithLogger._thread_local.instances = instances
54
59
  return transport
55
60
 
@@ -61,10 +66,11 @@ class EnvdTransportWithLogger(TransportWithLogger):
61
66
  def get_envd_transport(
62
67
  config: ConnectionConfig, http2: bool = True
63
68
  ) -> EnvdTransportWithLogger:
64
- instances: Dict[bool, EnvdTransportWithLogger] = getattr(
69
+ instances: Dict[TransportKey, EnvdTransportWithLogger] = getattr(
65
70
  EnvdTransportWithLogger._thread_local, "instances", {}
66
71
  )
67
- cached = instances.get(http2)
72
+ key: TransportKey = (http2, config.proxy)
73
+ cached = instances.get(key)
68
74
  if cached is not None:
69
75
  return cached
70
76
 
@@ -73,6 +79,6 @@ def get_envd_transport(
73
79
  proxy=config.proxy,
74
80
  http2=http2,
75
81
  )
76
- instances[http2] = transport
82
+ instances[key] = transport
77
83
  EnvdTransportWithLogger._thread_local.instances = instances
78
84
  return transport
@@ -95,7 +95,7 @@ class ConnectionConfig:
95
95
  proxy: Optional[ProxyTypes] = None,
96
96
  ):
97
97
  self.domain = domain or ConnectionConfig._domain()
98
- self.debug = debug or ConnectionConfig._debug()
98
+ self.debug = debug if debug is not None else ConnectionConfig._debug()
99
99
  self.api_key = api_key or ConnectionConfig._api_key()
100
100
  self.access_token = access_token or ConnectionConfig._access_token()
101
101
  self.headers = {**(headers or {}), **(api_headers or {})}
@@ -1,8 +1,9 @@
1
+ import threading
1
2
  from typing import Callable, Dict, List, Literal, Optional, Union, overload
2
3
 
3
4
  import e2b_connect
4
- import httpcore
5
5
  from packaging.version import Version
6
+ from e2b.api.client_sync import get_envd_transport
6
7
  from e2b.connection_config import (
7
8
  ConnectionConfig,
8
9
  Username,
@@ -27,20 +28,32 @@ class Commands:
27
28
  self,
28
29
  envd_api_url: str,
29
30
  connection_config: ConnectionConfig,
30
- pool: httpcore.ConnectionPool,
31
31
  envd_version: Version,
32
32
  ) -> None:
33
+ self._envd_api_url = envd_api_url
33
34
  self._connection_config = connection_config
34
35
  self._envd_version = envd_version
35
- self._rpc = process_connect.ProcessClient(
36
- envd_api_url,
36
+ self._thread_local = threading.local()
37
+
38
+ def _create_rpc(self) -> process_connect.ProcessClient:
39
+ transport = get_envd_transport(self._connection_config)
40
+ return process_connect.ProcessClient(
41
+ self._envd_api_url,
37
42
  # TODO: Fix and enable compression again — the headers compression is not solved for streaming.
38
43
  # compressor=e2b_connect.GzipCompressor,
39
- pool=pool,
44
+ pool=transport.pool,
40
45
  json=True,
41
- headers=connection_config.sandbox_headers,
46
+ headers=self._connection_config.sandbox_headers,
42
47
  )
43
48
 
49
+ @property
50
+ def _rpc(self) -> process_connect.ProcessClient:
51
+ rpc = getattr(self._thread_local, "rpc", None)
52
+ if rpc is None:
53
+ rpc = self._create_rpc()
54
+ self._thread_local.rpc = rpc
55
+ return rpc
56
+
44
57
  def list(
45
58
  self,
46
59
  request_timeout: Optional[float] = None,
@@ -1,9 +1,10 @@
1
1
  import e2b_connect
2
- import httpcore
2
+ import threading
3
3
 
4
4
  from typing import Dict, Optional
5
5
 
6
6
  from packaging.version import Version
7
+ from e2b.api.client_sync import get_envd_transport
7
8
  from e2b.envd.process import process_connect, process_pb2
8
9
  from e2b.connection_config import (
9
10
  Username,
@@ -26,20 +27,32 @@ class Pty:
26
27
  self,
27
28
  envd_api_url: str,
28
29
  connection_config: ConnectionConfig,
29
- pool: httpcore.ConnectionPool,
30
30
  envd_version: Version,
31
31
  ) -> None:
32
+ self._envd_api_url = envd_api_url
32
33
  self._connection_config = connection_config
33
34
  self._envd_version = envd_version
34
- self._rpc = process_connect.ProcessClient(
35
- envd_api_url,
35
+ self._thread_local = threading.local()
36
+
37
+ def _create_rpc(self) -> process_connect.ProcessClient:
38
+ transport = get_envd_transport(self._connection_config)
39
+ return process_connect.ProcessClient(
40
+ self._envd_api_url,
36
41
  # TODO: Fix and enable compression again — the headers compression is not solved for streaming.
37
42
  # compressor=e2b_connect.GzipCompressor,
38
- pool=pool,
43
+ pool=transport.pool,
39
44
  json=True,
40
- headers=connection_config.sandbox_headers,
45
+ headers=self._connection_config.sandbox_headers,
41
46
  )
42
47
 
48
+ @property
49
+ def _rpc(self) -> process_connect.ProcessClient:
50
+ rpc = getattr(self._thread_local, "rpc", None)
51
+ if rpc is None:
52
+ rpc = self._create_rpc()
53
+ self._thread_local.rpc = rpc
54
+ return rpc
55
+
43
56
  def kill(
44
57
  self,
45
58
  pid: int,
@@ -1,10 +1,11 @@
1
+ import threading
1
2
  from typing import IO, Dict, Iterator, List, Literal, Optional, Union, overload
2
3
 
3
- import httpcore
4
4
  import httpx
5
5
  from packaging.version import Version
6
6
 
7
7
  import e2b_connect
8
+ from e2b.api.client_sync import get_envd_transport
8
9
  from e2b.connection_config import (
9
10
  KEEPALIVE_PING_HEADER,
10
11
  KEEPALIVE_PING_INTERVAL_SEC,
@@ -71,24 +72,47 @@ class Filesystem:
71
72
  envd_api_url: str,
72
73
  envd_version: Version,
73
74
  connection_config: ConnectionConfig,
74
- pool: httpcore.ConnectionPool,
75
- envd_api: httpx.Client,
76
75
  ) -> None:
77
76
  self._envd_api_url = envd_api_url
78
77
  self._envd_version = envd_version
79
78
  self._connection_config = connection_config
80
- self._pool = pool
81
- self._envd_api = envd_api
79
+ self._thread_local = threading.local()
80
+
81
+ def _create_envd_api(self) -> httpx.Client:
82
+ transport = get_envd_transport(self._connection_config)
83
+ return httpx.Client(
84
+ base_url=self._envd_api_url,
85
+ transport=transport,
86
+ headers=self._connection_config.sandbox_headers,
87
+ )
82
88
 
83
- self._rpc = filesystem_connect.FilesystemClient(
84
- envd_api_url,
89
+ def _create_rpc(self) -> filesystem_connect.FilesystemClient:
90
+ transport = get_envd_transport(self._connection_config)
91
+ return filesystem_connect.FilesystemClient(
92
+ self._envd_api_url,
85
93
  # TODO: Fix and enable compression again — the headers compression is not solved for streaming.
86
94
  # compressor=e2b_connect.GzipCompressor,
87
- pool=pool,
95
+ pool=transport.pool,
88
96
  json=True,
89
- headers=connection_config.sandbox_headers,
97
+ headers=self._connection_config.sandbox_headers,
90
98
  )
91
99
 
100
+ @property
101
+ def _envd_api(self) -> httpx.Client:
102
+ envd_api = getattr(self._thread_local, "envd_api", None)
103
+ if envd_api is None:
104
+ envd_api = self._create_envd_api()
105
+ self._thread_local.envd_api = envd_api
106
+ return envd_api
107
+
108
+ @property
109
+ def _rpc(self) -> filesystem_connect.FilesystemClient:
110
+ rpc = getattr(self._thread_local, "rpc", None)
111
+ if rpc is None:
112
+ rpc = self._create_rpc()
113
+ self._thread_local.rpc = rpc
114
+ return rpc
115
+
92
116
  @overload
93
117
  def read(
94
118
  self,
@@ -579,4 +603,4 @@ class Filesystem:
579
603
  except Exception as e:
580
604
  raise _handle_filesystem_rpc_exception(e)
581
605
 
582
- return WatchHandle(self._rpc, r.watcher_id)
606
+ return WatchHandle(lambda: self._rpc, r.watcher_id)
@@ -1,4 +1,4 @@
1
- from typing import List
1
+ from typing import Callable, List
2
2
 
3
3
  from e2b import SandboxException
4
4
  from e2b.envd.filesystem import filesystem_connect
@@ -21,10 +21,10 @@ class WatchHandle:
21
21
 
22
22
  def __init__(
23
23
  self,
24
- rpc: filesystem_connect.FilesystemClient,
24
+ get_rpc: Callable[[], filesystem_connect.FilesystemClient],
25
25
  watcher_id: str,
26
26
  ):
27
- self._rpc = rpc
27
+ self._get_rpc = get_rpc
28
28
  self._watcher_id = watcher_id
29
29
  self._closed = False
30
30
 
@@ -34,7 +34,9 @@ class WatchHandle:
34
34
  After you stop the watcher you won't be able to get the events anymore.
35
35
  """
36
36
  try:
37
- self._rpc.remove_watcher(RemoveWatcherRequest(watcher_id=self._watcher_id))
37
+ self._get_rpc().remove_watcher(
38
+ RemoveWatcherRequest(watcher_id=self._watcher_id)
39
+ )
38
40
  except Exception as e:
39
41
  raise handle_rpc_exception(e)
40
42
 
@@ -50,7 +52,7 @@ class WatchHandle:
50
52
  raise SandboxException("The watcher is already stopped")
51
53
 
52
54
  try:
53
- r = self._rpc.get_watcher_events(
55
+ r = self._get_rpc().get_watcher_events(
54
56
  GetWatcherEventsRequest(watcher_id=self._watcher_id)
55
57
  )
56
58
  except Exception as e:
@@ -10,7 +10,6 @@ from packaging.version import Version
10
10
  from typing_extensions import Self, Unpack
11
11
 
12
12
  from e2b.api.client.types import Unset
13
- from e2b.api.client_sync import get_envd_transport as get_transport
14
13
  from e2b.connection_config import ApiParams, ConnectionConfig
15
14
  from e2b.envd.api import ENVD_API_HEALTH_ROUTE, handle_envd_api_exception
16
15
  from e2b.envd.versions import ENVD_DEBUG_FALLBACK
@@ -101,34 +100,27 @@ class Sandbox(SandboxApi):
101
100
  """
102
101
  super().__init__(**opts)
103
102
 
104
- self._transport = get_transport(self.connection_config)
105
-
106
- self._envd_api = httpx.Client(
107
- base_url=self.envd_api_url,
108
- transport=self._transport,
109
- headers=self.connection_config.sandbox_headers,
110
- )
111
103
  self._filesystem = Filesystem(
112
104
  self.envd_api_url,
113
105
  self._envd_version,
114
106
  self.connection_config,
115
- self._transport.pool,
116
- self._envd_api,
117
107
  )
118
108
  self._commands = Commands(
119
109
  self.envd_api_url,
120
110
  self.connection_config,
121
- self._transport.pool,
122
111
  self._envd_version,
123
112
  )
124
113
  self._pty = Pty(
125
114
  self.envd_api_url,
126
115
  self.connection_config,
127
- self._transport.pool,
128
116
  self._envd_version,
129
117
  )
130
118
  self._git = Git(self._commands)
131
119
 
120
+ @property
121
+ def _envd_api(self) -> httpx.Client:
122
+ return self._filesystem._envd_api
123
+
132
124
  def is_running(self, request_timeout: Optional[float] = None) -> bool:
133
125
  """
134
126
  Check if the sandbox is running.
@@ -111,8 +111,14 @@ async def upload_file(
111
111
  file_name, context_path, ignore_patterns, resolve_symlinks
112
112
  )
113
113
 
114
- client = api_client.get_async_httpx_client()
115
- response = await client.put(url, content=tar_buffer.getvalue())
114
+ async with httpx.AsyncClient(
115
+ timeout=api_client._timeout,
116
+ verify=api_client._verify_ssl,
117
+ follow_redirects=api_client._follow_redirects,
118
+ proxy=getattr(api_client, "_proxy", None),
119
+ http2=False,
120
+ ) as client:
121
+ response = await client.put(url, content=tar_buffer.getvalue())
116
122
  response.raise_for_status()
117
123
  except httpx.HTTPStatusError as e:
118
124
  raise FileUploadException(f"Failed to upload file: {e}").with_traceback(
@@ -110,8 +110,14 @@ def upload_file(
110
110
  tar_buffer = tar_file_stream(
111
111
  file_name, context_path, ignore_patterns, resolve_symlinks
112
112
  )
113
- client = api_client.get_httpx_client()
114
- response = client.put(url, content=tar_buffer.getvalue())
113
+ with httpx.Client(
114
+ timeout=api_client._timeout,
115
+ verify=api_client._verify_ssl,
116
+ follow_redirects=api_client._follow_redirects,
117
+ proxy=getattr(api_client, "_proxy", None),
118
+ http2=False,
119
+ ) as client:
120
+ response = client.put(url, content=tar_buffer.getvalue())
115
121
  response.raise_for_status()
116
122
  except httpx.HTTPStatusError as e:
117
123
  raise FileUploadException(f"Failed to upload file: {e}").with_traceback(
@@ -361,7 +361,6 @@ class Client:
361
361
  },
362
362
  }
363
363
 
364
- @_retry(RemoteProtocolError, 3)
365
364
  async def acall_server_stream(
366
365
  self,
367
366
  req,
@@ -395,7 +394,6 @@ class Client:
395
394
  for parsed in parser.parse(chunk):
396
395
  yield parsed
397
396
 
398
- @_retry(RemoteProtocolError, 3)
399
397
  def call_server_stream(
400
398
  self,
401
399
  req,
@@ -479,7 +477,10 @@ class ServerStreamParser:
479
477
  def parse(self, chunk: bytes) -> Generator[Any, None, None]:
480
478
  self.buffer += chunk
481
479
 
482
- while len(self.buffer) >= envelope_header_length:
480
+ # Once the header is consumed, the remaining payload can be shorter
481
+ # than the header length, so only require a full header when we still
482
+ # need to read one.
483
+ while self._header is not None or len(self.buffer) >= envelope_header_length:
483
484
  flags, data_len = self.header
484
485
 
485
486
  if data_len > len(self.buffer):
@@ -1,6 +1,6 @@
1
1
  [tool.poetry]
2
2
  name = "e2b"
3
- version = "2.28.0"
3
+ version = "2.28.2"
4
4
  description = "E2B SDK that give agents cloud environments"
5
5
  authors = ["e2b <hello@e2b.dev>"]
6
6
  license = "MIT"
File without changes
File without changes
File without changes
File without changes