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.
- {e2b-2.28.0 → e2b-2.28.2}/PKG-INFO +1 -1
- {e2b-2.28.0 → e2b-2.28.2}/e2b/api/__init__.py +76 -4
- {e2b-2.28.0 → e2b-2.28.2}/e2b/api/client_async/__init__.py +16 -12
- {e2b-2.28.0 → e2b-2.28.2}/e2b/api/client_sync/__init__.py +14 -8
- {e2b-2.28.0 → e2b-2.28.2}/e2b/connection_config.py +1 -1
- {e2b-2.28.0 → e2b-2.28.2}/e2b/sandbox_sync/commands/command.py +19 -6
- {e2b-2.28.0 → e2b-2.28.2}/e2b/sandbox_sync/commands/pty.py +19 -6
- {e2b-2.28.0 → e2b-2.28.2}/e2b/sandbox_sync/filesystem/filesystem.py +34 -10
- {e2b-2.28.0 → e2b-2.28.2}/e2b/sandbox_sync/filesystem/watch_handle.py +7 -5
- {e2b-2.28.0 → e2b-2.28.2}/e2b/sandbox_sync/main.py +4 -12
- {e2b-2.28.0 → e2b-2.28.2}/e2b/template_async/build_api.py +8 -2
- {e2b-2.28.0 → e2b-2.28.2}/e2b/template_sync/build_api.py +8 -2
- {e2b-2.28.0 → e2b-2.28.2}/e2b_connect/client.py +4 -3
- {e2b-2.28.0 → e2b-2.28.2}/pyproject.toml +1 -1
- {e2b-2.28.0 → e2b-2.28.2}/LICENSE +0 -0
- {e2b-2.28.0 → e2b-2.28.2}/README.md +0 -0
- {e2b-2.28.0 → e2b-2.28.2}/e2b/__init__.py +0 -0
- {e2b-2.28.0 → e2b-2.28.2}/e2b/api/client/__init__.py +0 -0
- {e2b-2.28.0 → e2b-2.28.2}/e2b/api/client/api/__init__.py +0 -0
- {e2b-2.28.0 → e2b-2.28.2}/e2b/api/client/api/sandboxes/__init__.py +0 -0
- {e2b-2.28.0 → e2b-2.28.2}/e2b/api/client/api/sandboxes/delete_sandboxes_sandbox_id.py +0 -0
- {e2b-2.28.0 → e2b-2.28.2}/e2b/api/client/api/sandboxes/get_sandboxes.py +0 -0
- {e2b-2.28.0 → e2b-2.28.2}/e2b/api/client/api/sandboxes/get_sandboxes_metrics.py +0 -0
- {e2b-2.28.0 → e2b-2.28.2}/e2b/api/client/api/sandboxes/get_sandboxes_sandbox_id.py +0 -0
- {e2b-2.28.0 → e2b-2.28.2}/e2b/api/client/api/sandboxes/get_sandboxes_sandbox_id_logs.py +0 -0
- {e2b-2.28.0 → e2b-2.28.2}/e2b/api/client/api/sandboxes/get_sandboxes_sandbox_id_metrics.py +0 -0
- {e2b-2.28.0 → e2b-2.28.2}/e2b/api/client/api/sandboxes/get_v2_sandboxes.py +0 -0
- {e2b-2.28.0 → e2b-2.28.2}/e2b/api/client/api/sandboxes/get_v_2_sandboxes_sandbox_id_logs.py +0 -0
- {e2b-2.28.0 → e2b-2.28.2}/e2b/api/client/api/sandboxes/post_sandboxes.py +0 -0
- {e2b-2.28.0 → e2b-2.28.2}/e2b/api/client/api/sandboxes/post_sandboxes_sandbox_id_connect.py +0 -0
- {e2b-2.28.0 → e2b-2.28.2}/e2b/api/client/api/sandboxes/post_sandboxes_sandbox_id_pause.py +0 -0
- {e2b-2.28.0 → e2b-2.28.2}/e2b/api/client/api/sandboxes/post_sandboxes_sandbox_id_refreshes.py +0 -0
- {e2b-2.28.0 → e2b-2.28.2}/e2b/api/client/api/sandboxes/post_sandboxes_sandbox_id_resume.py +0 -0
- {e2b-2.28.0 → e2b-2.28.2}/e2b/api/client/api/sandboxes/post_sandboxes_sandbox_id_snapshots.py +0 -0
- {e2b-2.28.0 → e2b-2.28.2}/e2b/api/client/api/sandboxes/post_sandboxes_sandbox_id_timeout.py +0 -0
- {e2b-2.28.0 → e2b-2.28.2}/e2b/api/client/api/sandboxes/put_sandboxes_sandbox_id_network.py +0 -0
- {e2b-2.28.0 → e2b-2.28.2}/e2b/api/client/api/snapshots/__init__.py +0 -0
- {e2b-2.28.0 → e2b-2.28.2}/e2b/api/client/api/snapshots/get_snapshots.py +0 -0
- {e2b-2.28.0 → e2b-2.28.2}/e2b/api/client/api/tags/__init__.py +0 -0
- {e2b-2.28.0 → e2b-2.28.2}/e2b/api/client/api/tags/delete_templates_tags.py +0 -0
- {e2b-2.28.0 → e2b-2.28.2}/e2b/api/client/api/tags/get_templates_template_id_tags.py +0 -0
- {e2b-2.28.0 → e2b-2.28.2}/e2b/api/client/api/tags/post_templates_tags.py +0 -0
- {e2b-2.28.0 → e2b-2.28.2}/e2b/api/client/api/templates/__init__.py +0 -0
- {e2b-2.28.0 → e2b-2.28.2}/e2b/api/client/api/templates/delete_templates_template_id.py +0 -0
- {e2b-2.28.0 → e2b-2.28.2}/e2b/api/client/api/templates/get_templates.py +0 -0
- {e2b-2.28.0 → e2b-2.28.2}/e2b/api/client/api/templates/get_templates_aliases_alias.py +0 -0
- {e2b-2.28.0 → e2b-2.28.2}/e2b/api/client/api/templates/get_templates_template_id.py +0 -0
- {e2b-2.28.0 → e2b-2.28.2}/e2b/api/client/api/templates/get_templates_template_id_builds_build_id_logs.py +0 -0
- {e2b-2.28.0 → e2b-2.28.2}/e2b/api/client/api/templates/get_templates_template_id_builds_build_id_status.py +0 -0
- {e2b-2.28.0 → e2b-2.28.2}/e2b/api/client/api/templates/get_templates_template_id_files_hash.py +0 -0
- {e2b-2.28.0 → e2b-2.28.2}/e2b/api/client/api/templates/patch_templates_template_id.py +0 -0
- {e2b-2.28.0 → e2b-2.28.2}/e2b/api/client/api/templates/patch_v_2_templates_template_id.py +0 -0
- {e2b-2.28.0 → e2b-2.28.2}/e2b/api/client/api/templates/post_templates.py +0 -0
- {e2b-2.28.0 → e2b-2.28.2}/e2b/api/client/api/templates/post_templates_template_id.py +0 -0
- {e2b-2.28.0 → e2b-2.28.2}/e2b/api/client/api/templates/post_templates_template_id_builds_build_id.py +0 -0
- {e2b-2.28.0 → e2b-2.28.2}/e2b/api/client/api/templates/post_v2_templates.py +0 -0
- {e2b-2.28.0 → e2b-2.28.2}/e2b/api/client/api/templates/post_v3_templates.py +0 -0
- {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
- {e2b-2.28.0 → e2b-2.28.2}/e2b/api/client/api/volumes/__init__.py +0 -0
- {e2b-2.28.0 → e2b-2.28.2}/e2b/api/client/api/volumes/delete_volumes_volume_id.py +0 -0
- {e2b-2.28.0 → e2b-2.28.2}/e2b/api/client/api/volumes/get_volumes.py +0 -0
- {e2b-2.28.0 → e2b-2.28.2}/e2b/api/client/api/volumes/get_volumes_volume_id.py +0 -0
- {e2b-2.28.0 → e2b-2.28.2}/e2b/api/client/api/volumes/post_volumes.py +0 -0
- {e2b-2.28.0 → e2b-2.28.2}/e2b/api/client/client.py +0 -0
- {e2b-2.28.0 → e2b-2.28.2}/e2b/api/client/errors.py +0 -0
- {e2b-2.28.0 → e2b-2.28.2}/e2b/api/client/models/__init__.py +0 -0
- {e2b-2.28.0 → e2b-2.28.2}/e2b/api/client/models/admin_build_cancel_result.py +0 -0
- {e2b-2.28.0 → e2b-2.28.2}/e2b/api/client/models/admin_sandbox_kill_result.py +0 -0
- {e2b-2.28.0 → e2b-2.28.2}/e2b/api/client/models/assign_template_tags_request.py +0 -0
- {e2b-2.28.0 → e2b-2.28.2}/e2b/api/client/models/assigned_template_tags.py +0 -0
- {e2b-2.28.0 → e2b-2.28.2}/e2b/api/client/models/aws_registry.py +0 -0
- {e2b-2.28.0 → e2b-2.28.2}/e2b/api/client/models/aws_registry_type.py +0 -0
- {e2b-2.28.0 → e2b-2.28.2}/e2b/api/client/models/build_log_entry.py +0 -0
- {e2b-2.28.0 → e2b-2.28.2}/e2b/api/client/models/build_status_reason.py +0 -0
- {e2b-2.28.0 → e2b-2.28.2}/e2b/api/client/models/connect_sandbox.py +0 -0
- {e2b-2.28.0 → e2b-2.28.2}/e2b/api/client/models/created_access_token.py +0 -0
- {e2b-2.28.0 → e2b-2.28.2}/e2b/api/client/models/created_team_api_key.py +0 -0
- {e2b-2.28.0 → e2b-2.28.2}/e2b/api/client/models/delete_template_tags_request.py +0 -0
- {e2b-2.28.0 → e2b-2.28.2}/e2b/api/client/models/disk_metrics.py +0 -0
- {e2b-2.28.0 → e2b-2.28.2}/e2b/api/client/models/error.py +0 -0
- {e2b-2.28.0 → e2b-2.28.2}/e2b/api/client/models/gcp_registry.py +0 -0
- {e2b-2.28.0 → e2b-2.28.2}/e2b/api/client/models/gcp_registry_type.py +0 -0
- {e2b-2.28.0 → e2b-2.28.2}/e2b/api/client/models/general_registry.py +0 -0
- {e2b-2.28.0 → e2b-2.28.2}/e2b/api/client/models/general_registry_type.py +0 -0
- {e2b-2.28.0 → e2b-2.28.2}/e2b/api/client/models/identifier_masking_details.py +0 -0
- {e2b-2.28.0 → e2b-2.28.2}/e2b/api/client/models/listed_sandbox.py +0 -0
- {e2b-2.28.0 → e2b-2.28.2}/e2b/api/client/models/log_level.py +0 -0
- {e2b-2.28.0 → e2b-2.28.2}/e2b/api/client/models/logs_direction.py +0 -0
- {e2b-2.28.0 → e2b-2.28.2}/e2b/api/client/models/logs_source.py +0 -0
- {e2b-2.28.0 → e2b-2.28.2}/e2b/api/client/models/machine_info.py +0 -0
- {e2b-2.28.0 → e2b-2.28.2}/e2b/api/client/models/max_team_metric.py +0 -0
- {e2b-2.28.0 → e2b-2.28.2}/e2b/api/client/models/mcp_type_0.py +0 -0
- {e2b-2.28.0 → e2b-2.28.2}/e2b/api/client/models/new_access_token.py +0 -0
- {e2b-2.28.0 → e2b-2.28.2}/e2b/api/client/models/new_sandbox.py +0 -0
- {e2b-2.28.0 → e2b-2.28.2}/e2b/api/client/models/new_team_api_key.py +0 -0
- {e2b-2.28.0 → e2b-2.28.2}/e2b/api/client/models/new_volume.py +0 -0
- {e2b-2.28.0 → e2b-2.28.2}/e2b/api/client/models/node.py +0 -0
- {e2b-2.28.0 → e2b-2.28.2}/e2b/api/client/models/node_detail.py +0 -0
- {e2b-2.28.0 → e2b-2.28.2}/e2b/api/client/models/node_metrics.py +0 -0
- {e2b-2.28.0 → e2b-2.28.2}/e2b/api/client/models/node_status.py +0 -0
- {e2b-2.28.0 → e2b-2.28.2}/e2b/api/client/models/node_status_change.py +0 -0
- {e2b-2.28.0 → e2b-2.28.2}/e2b/api/client/models/post_sandboxes_sandbox_id_refreshes_body.py +0 -0
- {e2b-2.28.0 → e2b-2.28.2}/e2b/api/client/models/post_sandboxes_sandbox_id_snapshots_body.py +0 -0
- {e2b-2.28.0 → e2b-2.28.2}/e2b/api/client/models/post_sandboxes_sandbox_id_timeout_body.py +0 -0
- {e2b-2.28.0 → e2b-2.28.2}/e2b/api/client/models/resumed_sandbox.py +0 -0
- {e2b-2.28.0 → e2b-2.28.2}/e2b/api/client/models/sandbox.py +0 -0
- {e2b-2.28.0 → e2b-2.28.2}/e2b/api/client/models/sandbox_auto_resume_config.py +0 -0
- {e2b-2.28.0 → e2b-2.28.2}/e2b/api/client/models/sandbox_detail.py +0 -0
- {e2b-2.28.0 → e2b-2.28.2}/e2b/api/client/models/sandbox_lifecycle.py +0 -0
- {e2b-2.28.0 → e2b-2.28.2}/e2b/api/client/models/sandbox_log.py +0 -0
- {e2b-2.28.0 → e2b-2.28.2}/e2b/api/client/models/sandbox_log_entry.py +0 -0
- {e2b-2.28.0 → e2b-2.28.2}/e2b/api/client/models/sandbox_log_entry_fields.py +0 -0
- {e2b-2.28.0 → e2b-2.28.2}/e2b/api/client/models/sandbox_logs.py +0 -0
- {e2b-2.28.0 → e2b-2.28.2}/e2b/api/client/models/sandbox_logs_v2_response.py +0 -0
- {e2b-2.28.0 → e2b-2.28.2}/e2b/api/client/models/sandbox_metric.py +0 -0
- {e2b-2.28.0 → e2b-2.28.2}/e2b/api/client/models/sandbox_network_config.py +0 -0
- {e2b-2.28.0 → e2b-2.28.2}/e2b/api/client/models/sandbox_network_config_rules.py +0 -0
- {e2b-2.28.0 → e2b-2.28.2}/e2b/api/client/models/sandbox_network_rule.py +0 -0
- {e2b-2.28.0 → e2b-2.28.2}/e2b/api/client/models/sandbox_network_transform.py +0 -0
- {e2b-2.28.0 → e2b-2.28.2}/e2b/api/client/models/sandbox_network_transform_headers.py +0 -0
- {e2b-2.28.0 → e2b-2.28.2}/e2b/api/client/models/sandbox_network_update_config.py +0 -0
- {e2b-2.28.0 → e2b-2.28.2}/e2b/api/client/models/sandbox_network_update_config_rules.py +0 -0
- {e2b-2.28.0 → e2b-2.28.2}/e2b/api/client/models/sandbox_on_timeout.py +0 -0
- {e2b-2.28.0 → e2b-2.28.2}/e2b/api/client/models/sandbox_state.py +0 -0
- {e2b-2.28.0 → e2b-2.28.2}/e2b/api/client/models/sandbox_volume_mount.py +0 -0
- {e2b-2.28.0 → e2b-2.28.2}/e2b/api/client/models/sandboxes_with_metrics.py +0 -0
- {e2b-2.28.0 → e2b-2.28.2}/e2b/api/client/models/snapshot_info.py +0 -0
- {e2b-2.28.0 → e2b-2.28.2}/e2b/api/client/models/team.py +0 -0
- {e2b-2.28.0 → e2b-2.28.2}/e2b/api/client/models/team_api_key.py +0 -0
- {e2b-2.28.0 → e2b-2.28.2}/e2b/api/client/models/team_metric.py +0 -0
- {e2b-2.28.0 → e2b-2.28.2}/e2b/api/client/models/team_user.py +0 -0
- {e2b-2.28.0 → e2b-2.28.2}/e2b/api/client/models/template.py +0 -0
- {e2b-2.28.0 → e2b-2.28.2}/e2b/api/client/models/template_alias_response.py +0 -0
- {e2b-2.28.0 → e2b-2.28.2}/e2b/api/client/models/template_build.py +0 -0
- {e2b-2.28.0 → e2b-2.28.2}/e2b/api/client/models/template_build_file_upload.py +0 -0
- {e2b-2.28.0 → e2b-2.28.2}/e2b/api/client/models/template_build_info.py +0 -0
- {e2b-2.28.0 → e2b-2.28.2}/e2b/api/client/models/template_build_logs_response.py +0 -0
- {e2b-2.28.0 → e2b-2.28.2}/e2b/api/client/models/template_build_request.py +0 -0
- {e2b-2.28.0 → e2b-2.28.2}/e2b/api/client/models/template_build_request_v2.py +0 -0
- {e2b-2.28.0 → e2b-2.28.2}/e2b/api/client/models/template_build_request_v3.py +0 -0
- {e2b-2.28.0 → e2b-2.28.2}/e2b/api/client/models/template_build_start_v2.py +0 -0
- {e2b-2.28.0 → e2b-2.28.2}/e2b/api/client/models/template_build_status.py +0 -0
- {e2b-2.28.0 → e2b-2.28.2}/e2b/api/client/models/template_legacy.py +0 -0
- {e2b-2.28.0 → e2b-2.28.2}/e2b/api/client/models/template_request_response_v3.py +0 -0
- {e2b-2.28.0 → e2b-2.28.2}/e2b/api/client/models/template_step.py +0 -0
- {e2b-2.28.0 → e2b-2.28.2}/e2b/api/client/models/template_tag.py +0 -0
- {e2b-2.28.0 → e2b-2.28.2}/e2b/api/client/models/template_update_request.py +0 -0
- {e2b-2.28.0 → e2b-2.28.2}/e2b/api/client/models/template_update_response.py +0 -0
- {e2b-2.28.0 → e2b-2.28.2}/e2b/api/client/models/template_with_builds.py +0 -0
- {e2b-2.28.0 → e2b-2.28.2}/e2b/api/client/models/update_team_api_key.py +0 -0
- {e2b-2.28.0 → e2b-2.28.2}/e2b/api/client/models/volume.py +0 -0
- {e2b-2.28.0 → e2b-2.28.2}/e2b/api/client/models/volume_and_token.py +0 -0
- {e2b-2.28.0 → e2b-2.28.2}/e2b/api/client/models/volume_token.py +0 -0
- {e2b-2.28.0 → e2b-2.28.2}/e2b/api/client/py.typed +0 -0
- {e2b-2.28.0 → e2b-2.28.2}/e2b/api/client/types.py +0 -0
- {e2b-2.28.0 → e2b-2.28.2}/e2b/api/metadata.py +0 -0
- {e2b-2.28.0 → e2b-2.28.2}/e2b/envd/api.py +0 -0
- {e2b-2.28.0 → e2b-2.28.2}/e2b/envd/filesystem/filesystem_connect.py +0 -0
- {e2b-2.28.0 → e2b-2.28.2}/e2b/envd/filesystem/filesystem_pb2.py +0 -0
- {e2b-2.28.0 → e2b-2.28.2}/e2b/envd/filesystem/filesystem_pb2.pyi +0 -0
- {e2b-2.28.0 → e2b-2.28.2}/e2b/envd/process/process_connect.py +0 -0
- {e2b-2.28.0 → e2b-2.28.2}/e2b/envd/process/process_pb2.py +0 -0
- {e2b-2.28.0 → e2b-2.28.2}/e2b/envd/process/process_pb2.pyi +0 -0
- {e2b-2.28.0 → e2b-2.28.2}/e2b/envd/rpc.py +0 -0
- {e2b-2.28.0 → e2b-2.28.2}/e2b/envd/versions.py +0 -0
- {e2b-2.28.0 → e2b-2.28.2}/e2b/exceptions.py +0 -0
- {e2b-2.28.0 → e2b-2.28.2}/e2b/py.typed +0 -0
- {e2b-2.28.0 → e2b-2.28.2}/e2b/sandbox/_git/__init__.py +0 -0
- {e2b-2.28.0 → e2b-2.28.2}/e2b/sandbox/_git/args.py +0 -0
- {e2b-2.28.0 → e2b-2.28.2}/e2b/sandbox/_git/auth.py +0 -0
- {e2b-2.28.0 → e2b-2.28.2}/e2b/sandbox/_git/config.py +0 -0
- {e2b-2.28.0 → e2b-2.28.2}/e2b/sandbox/_git/parse.py +0 -0
- {e2b-2.28.0 → e2b-2.28.2}/e2b/sandbox/_git/types.py +0 -0
- {e2b-2.28.0 → e2b-2.28.2}/e2b/sandbox/commands/command_handle.py +0 -0
- {e2b-2.28.0 → e2b-2.28.2}/e2b/sandbox/commands/main.py +0 -0
- {e2b-2.28.0 → e2b-2.28.2}/e2b/sandbox/filesystem/filesystem.py +0 -0
- {e2b-2.28.0 → e2b-2.28.2}/e2b/sandbox/filesystem/watch_handle.py +0 -0
- {e2b-2.28.0 → e2b-2.28.2}/e2b/sandbox/main.py +0 -0
- {e2b-2.28.0 → e2b-2.28.2}/e2b/sandbox/mcp.py +0 -0
- {e2b-2.28.0 → e2b-2.28.2}/e2b/sandbox/network.py +0 -0
- {e2b-2.28.0 → e2b-2.28.2}/e2b/sandbox/sandbox_api.py +0 -0
- {e2b-2.28.0 → e2b-2.28.2}/e2b/sandbox/signature.py +0 -0
- {e2b-2.28.0 → e2b-2.28.2}/e2b/sandbox/utils.py +0 -0
- {e2b-2.28.0 → e2b-2.28.2}/e2b/sandbox_async/commands/command.py +0 -0
- {e2b-2.28.0 → e2b-2.28.2}/e2b/sandbox_async/commands/command_handle.py +0 -0
- {e2b-2.28.0 → e2b-2.28.2}/e2b/sandbox_async/commands/pty.py +0 -0
- {e2b-2.28.0 → e2b-2.28.2}/e2b/sandbox_async/filesystem/filesystem.py +0 -0
- {e2b-2.28.0 → e2b-2.28.2}/e2b/sandbox_async/filesystem/watch_handle.py +0 -0
- {e2b-2.28.0 → e2b-2.28.2}/e2b/sandbox_async/git.py +0 -0
- {e2b-2.28.0 → e2b-2.28.2}/e2b/sandbox_async/main.py +0 -0
- {e2b-2.28.0 → e2b-2.28.2}/e2b/sandbox_async/paginator.py +0 -0
- {e2b-2.28.0 → e2b-2.28.2}/e2b/sandbox_async/sandbox_api.py +0 -0
- {e2b-2.28.0 → e2b-2.28.2}/e2b/sandbox_async/utils.py +0 -0
- {e2b-2.28.0 → e2b-2.28.2}/e2b/sandbox_domains.py +0 -0
- {e2b-2.28.0 → e2b-2.28.2}/e2b/sandbox_sync/commands/command_handle.py +0 -0
- {e2b-2.28.0 → e2b-2.28.2}/e2b/sandbox_sync/git.py +0 -0
- {e2b-2.28.0 → e2b-2.28.2}/e2b/sandbox_sync/paginator.py +0 -0
- {e2b-2.28.0 → e2b-2.28.2}/e2b/sandbox_sync/sandbox_api.py +0 -0
- {e2b-2.28.0 → e2b-2.28.2}/e2b/template/consts.py +0 -0
- {e2b-2.28.0 → e2b-2.28.2}/e2b/template/dockerfile_parser.py +0 -0
- {e2b-2.28.0 → e2b-2.28.2}/e2b/template/logger.py +0 -0
- {e2b-2.28.0 → e2b-2.28.2}/e2b/template/main.py +0 -0
- {e2b-2.28.0 → e2b-2.28.2}/e2b/template/readycmd.py +0 -0
- {e2b-2.28.0 → e2b-2.28.2}/e2b/template/types.py +0 -0
- {e2b-2.28.0 → e2b-2.28.2}/e2b/template/utils.py +0 -0
- {e2b-2.28.0 → e2b-2.28.2}/e2b/template_async/main.py +0 -0
- {e2b-2.28.0 → e2b-2.28.2}/e2b/template_sync/main.py +0 -0
- {e2b-2.28.0 → e2b-2.28.2}/e2b/volume/client/__init__.py +0 -0
- {e2b-2.28.0 → e2b-2.28.2}/e2b/volume/client/api/__init__.py +0 -0
- {e2b-2.28.0 → e2b-2.28.2}/e2b/volume/client/api/volumes/__init__.py +0 -0
- {e2b-2.28.0 → e2b-2.28.2}/e2b/volume/client/api/volumes/delete_volumecontent_volume_id_path.py +0 -0
- {e2b-2.28.0 → e2b-2.28.2}/e2b/volume/client/api/volumes/get_volumecontent_volume_id_dir.py +0 -0
- {e2b-2.28.0 → e2b-2.28.2}/e2b/volume/client/api/volumes/get_volumecontent_volume_id_file.py +0 -0
- {e2b-2.28.0 → e2b-2.28.2}/e2b/volume/client/api/volumes/get_volumecontent_volume_id_path.py +0 -0
- {e2b-2.28.0 → e2b-2.28.2}/e2b/volume/client/api/volumes/patch_volumecontent_volume_id_path.py +0 -0
- {e2b-2.28.0 → e2b-2.28.2}/e2b/volume/client/api/volumes/post_volumecontent_volume_id_dir.py +0 -0
- {e2b-2.28.0 → e2b-2.28.2}/e2b/volume/client/api/volumes/put_volumecontent_volume_id_file.py +0 -0
- {e2b-2.28.0 → e2b-2.28.2}/e2b/volume/client/client.py +0 -0
- {e2b-2.28.0 → e2b-2.28.2}/e2b/volume/client/errors.py +0 -0
- {e2b-2.28.0 → e2b-2.28.2}/e2b/volume/client/models/__init__.py +0 -0
- {e2b-2.28.0 → e2b-2.28.2}/e2b/volume/client/models/error.py +0 -0
- {e2b-2.28.0 → e2b-2.28.2}/e2b/volume/client/models/patch_volumecontent_volume_id_path_body.py +0 -0
- {e2b-2.28.0 → e2b-2.28.2}/e2b/volume/client/models/volume_entry_stat.py +0 -0
- {e2b-2.28.0 → e2b-2.28.2}/e2b/volume/client/models/volume_entry_stat_type.py +0 -0
- {e2b-2.28.0 → e2b-2.28.2}/e2b/volume/client/py.typed +0 -0
- {e2b-2.28.0 → e2b-2.28.2}/e2b/volume/client/types.py +0 -0
- {e2b-2.28.0 → e2b-2.28.2}/e2b/volume/client_async/__init__.py +0 -0
- {e2b-2.28.0 → e2b-2.28.2}/e2b/volume/client_sync/__init__.py +0 -0
- {e2b-2.28.0 → e2b-2.28.2}/e2b/volume/connection_config.py +0 -0
- {e2b-2.28.0 → e2b-2.28.2}/e2b/volume/types.py +0 -0
- {e2b-2.28.0 → e2b-2.28.2}/e2b/volume/utils.py +0 -0
- {e2b-2.28.0 → e2b-2.28.2}/e2b/volume/volume_async.py +0 -0
- {e2b-2.28.0 → e2b-2.28.2}/e2b/volume/volume_sync.py +0 -0
- {e2b-2.28.0 → e2b-2.28.2}/e2b_connect/__init__.py +0 -0
- {e2b-2.28.0 → e2b-2.28.2}/e2b_connect/py.typed +0 -0
|
@@ -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
|
-
|
|
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
|
-
|
|
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[
|
|
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
|
-
|
|
46
|
+
key: TransportKey = (id(asyncio.get_running_loop()), http2, config.proxy)
|
|
43
47
|
|
|
44
|
-
if
|
|
45
|
-
return AsyncTransportWithLogger._instances[
|
|
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[
|
|
57
|
+
AsyncTransportWithLogger._instances[key] = transport
|
|
54
58
|
return transport
|
|
55
59
|
|
|
56
60
|
|
|
57
61
|
class AsyncEnvdTransportWithLogger(AsyncTransportWithLogger):
|
|
58
|
-
_instances: Dict[
|
|
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
|
-
|
|
68
|
+
key: TransportKey = (id(asyncio.get_running_loop()), http2, config.proxy)
|
|
65
69
|
|
|
66
|
-
if
|
|
67
|
-
return AsyncEnvdTransportWithLogger._instances[
|
|
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[
|
|
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
|
-
|
|
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[
|
|
44
|
+
instances: Dict[TransportKey, TransportWithLogger] = getattr(
|
|
41
45
|
TransportWithLogger._thread_local, "instances", {}
|
|
42
46
|
)
|
|
43
|
-
|
|
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[
|
|
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[
|
|
69
|
+
instances: Dict[TransportKey, EnvdTransportWithLogger] = getattr(
|
|
65
70
|
EnvdTransportWithLogger._thread_local, "instances", {}
|
|
66
71
|
)
|
|
67
|
-
|
|
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[
|
|
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
|
|
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.
|
|
36
|
-
|
|
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=
|
|
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
|
|
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.
|
|
35
|
-
|
|
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=
|
|
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.
|
|
81
|
-
|
|
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
|
-
|
|
84
|
-
|
|
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=
|
|
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
|
-
|
|
24
|
+
get_rpc: Callable[[], filesystem_connect.FilesystemClient],
|
|
25
25
|
watcher_id: str,
|
|
26
26
|
):
|
|
27
|
-
self.
|
|
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.
|
|
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.
|
|
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
|
-
|
|
115
|
-
|
|
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
|
-
|
|
114
|
-
|
|
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
|
-
|
|
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):
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{e2b-2.28.0 → e2b-2.28.2}/e2b/api/client/api/sandboxes/post_sandboxes_sandbox_id_refreshes.py
RENAMED
|
File without changes
|
|
File without changes
|
{e2b-2.28.0 → e2b-2.28.2}/e2b/api/client/api/sandboxes/post_sandboxes_sandbox_id_snapshots.py
RENAMED
|
File without changes
|