opensandbox 0.1.8.dev1__tar.gz → 0.1.9.dev0__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.
- {opensandbox-0.1.8.dev1 → opensandbox-0.1.9.dev0}/.gitignore +2 -0
- {opensandbox-0.1.8.dev1 → opensandbox-0.1.9.dev0}/PKG-INFO +3 -2
- {opensandbox-0.1.8.dev1 → opensandbox-0.1.9.dev0}/README.md +2 -1
- {opensandbox-0.1.8.dev1 → opensandbox-0.1.9.dev0}/pyproject.toml +2 -1
- {opensandbox-0.1.8.dev1 → opensandbox-0.1.9.dev0}/src/opensandbox/__init__.py +0 -4
- {opensandbox-0.1.8.dev1 → opensandbox-0.1.9.dev0}/src/opensandbox/_pool_reconciler.py +3 -3
- opensandbox-0.1.9.dev0/src/opensandbox/adapters/converter/diagnostic_model_converter.py +31 -0
- opensandbox-0.1.9.dev0/src/opensandbox/adapters/diagnostics_adapter.py +126 -0
- {opensandbox-0.1.8.dev1 → opensandbox-0.1.9.dev0}/src/opensandbox/adapters/factory.py +6 -0
- {opensandbox-0.1.8.dev1 → opensandbox-0.1.9.dev0}/src/opensandbox/adapters/sandboxes_adapter.py +29 -0
- opensandbox-0.1.9.dev0/src/opensandbox/api/diagnostic/__init__.py +24 -0
- opensandbox-0.1.9.dev0/src/opensandbox/api/diagnostic/api/diagnostics/get_sandboxes_sandbox_id_diagnostics_events.py +282 -0
- opensandbox-0.1.9.dev0/src/opensandbox/api/diagnostic/api/diagnostics/get_sandboxes_sandbox_id_diagnostics_logs.py +278 -0
- opensandbox-0.1.9.dev0/src/opensandbox/api/diagnostic/models/__init__.py +29 -0
- opensandbox-0.1.9.dev0/src/opensandbox/api/diagnostic/models/diagnostic_content_response.py +170 -0
- opensandbox-0.1.9.dev0/src/opensandbox/api/diagnostic/models/diagnostic_content_response_delivery.py +25 -0
- opensandbox-0.1.9.dev0/src/opensandbox/api/diagnostic/models/diagnostic_content_response_kind.py +25 -0
- opensandbox-0.1.9.dev0/src/opensandbox/api/diagnostic/models/error_response.py +68 -0
- opensandbox-0.1.9.dev0/src/opensandbox/api/lifecycle/api/__init__.py +17 -0
- opensandbox-0.1.9.dev0/src/opensandbox/api/lifecycle/api/sandboxes/patch_sandboxes_sandbox_id_metadata.py +347 -0
- opensandbox-0.1.9.dev0/src/opensandbox/api/lifecycle/api/snapshots/__init__.py +17 -0
- {opensandbox-0.1.8.dev1 → opensandbox-0.1.9.dev0}/src/opensandbox/api/lifecycle/api/snapshots/delete_snapshots_snapshot_id.py +28 -8
- {opensandbox-0.1.8.dev1 → opensandbox-0.1.9.dev0}/src/opensandbox/api/lifecycle/api/snapshots/post_sandboxes_sandbox_id_snapshots.py +16 -8
- opensandbox-0.1.9.dev0/src/opensandbox/api/lifecycle/client.py +284 -0
- opensandbox-0.1.9.dev0/src/opensandbox/api/lifecycle/errors.py +32 -0
- {opensandbox-0.1.8.dev1 → opensandbox-0.1.9.dev0}/src/opensandbox/api/lifecycle/models/__init__.py +2 -0
- opensandbox-0.1.9.dev0/src/opensandbox/api/lifecycle/models/patch_sandbox_metadata_request.py +87 -0
- opensandbox-0.1.9.dev0/src/opensandbox/api/lifecycle/py.typed +1 -0
- opensandbox-0.1.9.dev0/src/opensandbox/api/lifecycle/types.py +70 -0
- {opensandbox-0.1.8.dev1 → opensandbox-0.1.9.dev0}/src/opensandbox/async_redis_pool_store.py +101 -42
- {opensandbox-0.1.8.dev1 → opensandbox-0.1.9.dev0}/src/opensandbox/config/connection.py +1 -1
- {opensandbox-0.1.8.dev1 → opensandbox-0.1.9.dev0}/src/opensandbox/config/connection_sync.py +1 -1
- {opensandbox-0.1.8.dev1 → opensandbox-0.1.9.dev0}/src/opensandbox/manager.py +48 -1
- {opensandbox-0.1.8.dev1 → opensandbox-0.1.9.dev0}/src/opensandbox/models/__init__.py +2 -0
- opensandbox-0.1.9.dev0/src/opensandbox/models/diagnostics.py +39 -0
- {opensandbox-0.1.8.dev1 → opensandbox-0.1.9.dev0}/src/opensandbox/pool.py +0 -4
- {opensandbox-0.1.8.dev1 → opensandbox-0.1.9.dev0}/src/opensandbox/pool_async.py +10 -1
- opensandbox-0.1.9.dev0/src/opensandbox/pool_redis.py +27 -0
- {opensandbox-0.1.8.dev1 → opensandbox-0.1.9.dev0}/src/opensandbox/pool_types.py +2 -0
- {opensandbox-0.1.8.dev1 → opensandbox-0.1.9.dev0}/src/opensandbox/redis_pool_store.py +47 -7
- {opensandbox-0.1.8.dev1 → opensandbox-0.1.9.dev0}/src/opensandbox/sandbox.py +42 -0
- {opensandbox-0.1.8.dev1 → opensandbox-0.1.9.dev0}/src/opensandbox/services/__init__.py +2 -0
- opensandbox-0.1.9.dev0/src/opensandbox/services/diagnostics.py +40 -0
- {opensandbox-0.1.8.dev1 → opensandbox-0.1.9.dev0}/src/opensandbox/services/sandbox.py +18 -0
- opensandbox-0.1.9.dev0/src/opensandbox/sync/adapters/diagnostics_adapter.py +126 -0
- {opensandbox-0.1.8.dev1 → opensandbox-0.1.9.dev0}/src/opensandbox/sync/adapters/factory.py +5 -0
- {opensandbox-0.1.8.dev1 → opensandbox-0.1.9.dev0}/src/opensandbox/sync/adapters/sandboxes_adapter.py +26 -0
- {opensandbox-0.1.8.dev1 → opensandbox-0.1.9.dev0}/src/opensandbox/sync/manager.py +51 -2
- {opensandbox-0.1.8.dev1 → opensandbox-0.1.9.dev0}/src/opensandbox/sync/pool.py +10 -1
- {opensandbox-0.1.8.dev1 → opensandbox-0.1.9.dev0}/src/opensandbox/sync/sandbox.py +42 -0
- {opensandbox-0.1.8.dev1 → opensandbox-0.1.9.dev0}/src/opensandbox/sync/services/__init__.py +2 -0
- opensandbox-0.1.9.dev0/src/opensandbox/sync/services/diagnostics.py +40 -0
- {opensandbox-0.1.8.dev1 → opensandbox-0.1.9.dev0}/src/opensandbox/sync/services/sandbox.py +18 -0
- {opensandbox-0.1.8.dev1 → opensandbox-0.1.9.dev0}/LICENSE +0 -0
- {opensandbox-0.1.8.dev1 → opensandbox-0.1.9.dev0}/src/opensandbox/_async_pool_reconciler.py +0 -0
- {opensandbox-0.1.8.dev1 → opensandbox-0.1.9.dev0}/src/opensandbox/_async_pool_store.py +0 -0
- {opensandbox-0.1.8.dev1 → opensandbox-0.1.9.dev0}/src/opensandbox/_pool_store.py +0 -0
- {opensandbox-0.1.8.dev1 → opensandbox-0.1.9.dev0}/src/opensandbox/adapters/__init__.py +0 -0
- {opensandbox-0.1.8.dev1 → opensandbox-0.1.9.dev0}/src/opensandbox/adapters/command_adapter.py +0 -0
- {opensandbox-0.1.8.dev1 → opensandbox-0.1.9.dev0}/src/opensandbox/adapters/converter/__init__.py +0 -0
- {opensandbox-0.1.8.dev1 → opensandbox-0.1.9.dev0}/src/opensandbox/adapters/converter/command_model_converter.py +0 -0
- {opensandbox-0.1.8.dev1 → opensandbox-0.1.9.dev0}/src/opensandbox/adapters/converter/event_node.py +0 -0
- {opensandbox-0.1.8.dev1 → opensandbox-0.1.9.dev0}/src/opensandbox/adapters/converter/exception_converter.py +0 -0
- {opensandbox-0.1.8.dev1 → opensandbox-0.1.9.dev0}/src/opensandbox/adapters/converter/execution_converter.py +0 -0
- {opensandbox-0.1.8.dev1 → opensandbox-0.1.9.dev0}/src/opensandbox/adapters/converter/execution_event_dispatcher.py +0 -0
- {opensandbox-0.1.8.dev1 → opensandbox-0.1.9.dev0}/src/opensandbox/adapters/converter/filesystem_model_converter.py +0 -0
- {opensandbox-0.1.8.dev1 → opensandbox-0.1.9.dev0}/src/opensandbox/adapters/converter/metrics_model_converter.py +0 -0
- {opensandbox-0.1.8.dev1 → opensandbox-0.1.9.dev0}/src/opensandbox/adapters/converter/response_handler.py +0 -0
- {opensandbox-0.1.8.dev1 → opensandbox-0.1.9.dev0}/src/opensandbox/adapters/converter/sandbox_model_converter.py +0 -0
- {opensandbox-0.1.8.dev1 → opensandbox-0.1.9.dev0}/src/opensandbox/adapters/egress_adapter.py +0 -0
- {opensandbox-0.1.8.dev1 → opensandbox-0.1.9.dev0}/src/opensandbox/adapters/filesystem_adapter.py +0 -0
- {opensandbox-0.1.8.dev1 → opensandbox-0.1.9.dev0}/src/opensandbox/adapters/health_adapter.py +0 -0
- {opensandbox-0.1.8.dev1 → opensandbox-0.1.9.dev0}/src/opensandbox/adapters/metrics_adapter.py +0 -0
- {opensandbox-0.1.8.dev1 → opensandbox-0.1.9.dev0}/src/opensandbox/api/__init__.py +0 -0
- {opensandbox-0.1.8.dev1/src/opensandbox/api/egress → opensandbox-0.1.9.dev0/src/opensandbox/api/diagnostic}/api/__init__.py +0 -0
- {opensandbox-0.1.8.dev1/src/opensandbox/api/egress/api/policy → opensandbox-0.1.9.dev0/src/opensandbox/api/diagnostic/api/diagnostics}/__init__.py +0 -0
- {opensandbox-0.1.8.dev1/src/opensandbox/api/egress → opensandbox-0.1.9.dev0/src/opensandbox/api/diagnostic}/client.py +0 -0
- {opensandbox-0.1.8.dev1/src/opensandbox/api/egress → opensandbox-0.1.9.dev0/src/opensandbox/api/diagnostic}/errors.py +0 -0
- {opensandbox-0.1.8.dev1/src/opensandbox/api/egress → opensandbox-0.1.9.dev0/src/opensandbox/api/diagnostic}/py.typed +0 -0
- {opensandbox-0.1.8.dev1/src/opensandbox/api/egress → opensandbox-0.1.9.dev0/src/opensandbox/api/diagnostic}/types.py +0 -0
- {opensandbox-0.1.8.dev1 → opensandbox-0.1.9.dev0}/src/opensandbox/api/egress/__init__.py +0 -0
- {opensandbox-0.1.8.dev1/src/opensandbox/api/execd → opensandbox-0.1.9.dev0/src/opensandbox/api/egress}/api/__init__.py +0 -0
- {opensandbox-0.1.8.dev1/src/opensandbox/api/execd/api/code_interpreting → opensandbox-0.1.9.dev0/src/opensandbox/api/egress/api/policy}/__init__.py +0 -0
- {opensandbox-0.1.8.dev1 → opensandbox-0.1.9.dev0}/src/opensandbox/api/egress/api/policy/get_policy.py +0 -0
- {opensandbox-0.1.8.dev1 → opensandbox-0.1.9.dev0}/src/opensandbox/api/egress/api/policy/patch_policy.py +0 -0
- {opensandbox-0.1.8.dev1/src/opensandbox/api/execd → opensandbox-0.1.9.dev0/src/opensandbox/api/egress}/client.py +0 -0
- {opensandbox-0.1.8.dev1/src/opensandbox/api/execd → opensandbox-0.1.9.dev0/src/opensandbox/api/egress}/errors.py +0 -0
- {opensandbox-0.1.8.dev1 → opensandbox-0.1.9.dev0}/src/opensandbox/api/egress/models/__init__.py +0 -0
- {opensandbox-0.1.8.dev1 → opensandbox-0.1.9.dev0}/src/opensandbox/api/egress/models/network_policy.py +0 -0
- {opensandbox-0.1.8.dev1 → opensandbox-0.1.9.dev0}/src/opensandbox/api/egress/models/network_policy_default_action.py +0 -0
- {opensandbox-0.1.8.dev1 → opensandbox-0.1.9.dev0}/src/opensandbox/api/egress/models/network_rule.py +0 -0
- {opensandbox-0.1.8.dev1 → opensandbox-0.1.9.dev0}/src/opensandbox/api/egress/models/network_rule_action.py +0 -0
- {opensandbox-0.1.8.dev1 → opensandbox-0.1.9.dev0}/src/opensandbox/api/egress/models/policy_status_response.py +0 -0
- {opensandbox-0.1.8.dev1/src/opensandbox/api/execd → opensandbox-0.1.9.dev0/src/opensandbox/api/egress}/py.typed +0 -0
- {opensandbox-0.1.8.dev1/src/opensandbox/api/execd → opensandbox-0.1.9.dev0/src/opensandbox/api/egress}/types.py +0 -0
- {opensandbox-0.1.8.dev1 → opensandbox-0.1.9.dev0}/src/opensandbox/api/execd/__init__.py +0 -0
- {opensandbox-0.1.8.dev1/src/opensandbox/api/lifecycle → opensandbox-0.1.9.dev0/src/opensandbox/api/execd}/api/__init__.py +0 -0
- {opensandbox-0.1.8.dev1/src/opensandbox/api/execd/api/command → opensandbox-0.1.9.dev0/src/opensandbox/api/execd/api/code_interpreting}/__init__.py +0 -0
- {opensandbox-0.1.8.dev1 → opensandbox-0.1.9.dev0}/src/opensandbox/api/execd/api/code_interpreting/create_code_context.py +0 -0
- {opensandbox-0.1.8.dev1 → opensandbox-0.1.9.dev0}/src/opensandbox/api/execd/api/code_interpreting/delete_context.py +0 -0
- {opensandbox-0.1.8.dev1 → opensandbox-0.1.9.dev0}/src/opensandbox/api/execd/api/code_interpreting/delete_contexts_by_language.py +0 -0
- {opensandbox-0.1.8.dev1 → opensandbox-0.1.9.dev0}/src/opensandbox/api/execd/api/code_interpreting/get_context.py +0 -0
- {opensandbox-0.1.8.dev1 → opensandbox-0.1.9.dev0}/src/opensandbox/api/execd/api/code_interpreting/interrupt_code.py +0 -0
- {opensandbox-0.1.8.dev1 → opensandbox-0.1.9.dev0}/src/opensandbox/api/execd/api/code_interpreting/list_contexts.py +0 -0
- {opensandbox-0.1.8.dev1 → opensandbox-0.1.9.dev0}/src/opensandbox/api/execd/api/code_interpreting/run_code.py +0 -0
- {opensandbox-0.1.8.dev1/src/opensandbox/api/execd/api/filesystem → opensandbox-0.1.9.dev0/src/opensandbox/api/execd/api/command}/__init__.py +0 -0
- {opensandbox-0.1.8.dev1 → opensandbox-0.1.9.dev0}/src/opensandbox/api/execd/api/command/create_session.py +0 -0
- {opensandbox-0.1.8.dev1 → opensandbox-0.1.9.dev0}/src/opensandbox/api/execd/api/command/delete_session.py +0 -0
- {opensandbox-0.1.8.dev1 → opensandbox-0.1.9.dev0}/src/opensandbox/api/execd/api/command/get_background_command_logs.py +0 -0
- {opensandbox-0.1.8.dev1 → opensandbox-0.1.9.dev0}/src/opensandbox/api/execd/api/command/get_command_status.py +0 -0
- {opensandbox-0.1.8.dev1 → opensandbox-0.1.9.dev0}/src/opensandbox/api/execd/api/command/interrupt_command.py +0 -0
- {opensandbox-0.1.8.dev1 → opensandbox-0.1.9.dev0}/src/opensandbox/api/execd/api/command/run_command.py +0 -0
- {opensandbox-0.1.8.dev1 → opensandbox-0.1.9.dev0}/src/opensandbox/api/execd/api/command/run_in_session.py +0 -0
- {opensandbox-0.1.8.dev1/src/opensandbox/api/execd/api/health → opensandbox-0.1.9.dev0/src/opensandbox/api/execd/api/filesystem}/__init__.py +0 -0
- {opensandbox-0.1.8.dev1 → opensandbox-0.1.9.dev0}/src/opensandbox/api/execd/api/filesystem/chmod_files.py +0 -0
- {opensandbox-0.1.8.dev1 → opensandbox-0.1.9.dev0}/src/opensandbox/api/execd/api/filesystem/download_file.py +0 -0
- {opensandbox-0.1.8.dev1 → opensandbox-0.1.9.dev0}/src/opensandbox/api/execd/api/filesystem/get_files_info.py +0 -0
- {opensandbox-0.1.8.dev1 → opensandbox-0.1.9.dev0}/src/opensandbox/api/execd/api/filesystem/make_dirs.py +0 -0
- {opensandbox-0.1.8.dev1 → opensandbox-0.1.9.dev0}/src/opensandbox/api/execd/api/filesystem/remove_dirs.py +0 -0
- {opensandbox-0.1.8.dev1 → opensandbox-0.1.9.dev0}/src/opensandbox/api/execd/api/filesystem/remove_files.py +0 -0
- {opensandbox-0.1.8.dev1 → opensandbox-0.1.9.dev0}/src/opensandbox/api/execd/api/filesystem/rename_files.py +0 -0
- {opensandbox-0.1.8.dev1 → opensandbox-0.1.9.dev0}/src/opensandbox/api/execd/api/filesystem/replace_content.py +0 -0
- {opensandbox-0.1.8.dev1 → opensandbox-0.1.9.dev0}/src/opensandbox/api/execd/api/filesystem/search_files.py +0 -0
- {opensandbox-0.1.8.dev1 → opensandbox-0.1.9.dev0}/src/opensandbox/api/execd/api/filesystem/upload_file.py +0 -0
- {opensandbox-0.1.8.dev1/src/opensandbox/api/execd/api/metric → opensandbox-0.1.9.dev0/src/opensandbox/api/execd/api/health}/__init__.py +0 -0
- {opensandbox-0.1.8.dev1 → opensandbox-0.1.9.dev0}/src/opensandbox/api/execd/api/health/ping.py +0 -0
- {opensandbox-0.1.8.dev1/src/opensandbox/api/lifecycle/api/sandboxes → opensandbox-0.1.9.dev0/src/opensandbox/api/execd/api/metric}/__init__.py +0 -0
- {opensandbox-0.1.8.dev1 → opensandbox-0.1.9.dev0}/src/opensandbox/api/execd/api/metric/get_metrics.py +0 -0
- {opensandbox-0.1.8.dev1 → opensandbox-0.1.9.dev0}/src/opensandbox/api/execd/api/metric/watch_metrics.py +0 -0
- {opensandbox-0.1.8.dev1/src/opensandbox/api/lifecycle → opensandbox-0.1.9.dev0/src/opensandbox/api/execd}/client.py +0 -0
- {opensandbox-0.1.8.dev1/src/opensandbox/api/lifecycle → opensandbox-0.1.9.dev0/src/opensandbox/api/execd}/errors.py +0 -0
- {opensandbox-0.1.8.dev1 → opensandbox-0.1.9.dev0}/src/opensandbox/api/execd/models/__init__.py +0 -0
- {opensandbox-0.1.8.dev1 → opensandbox-0.1.9.dev0}/src/opensandbox/api/execd/models/chmod_files_body.py +0 -0
- {opensandbox-0.1.8.dev1 → opensandbox-0.1.9.dev0}/src/opensandbox/api/execd/models/code_context.py +0 -0
- {opensandbox-0.1.8.dev1 → opensandbox-0.1.9.dev0}/src/opensandbox/api/execd/models/code_context_request.py +0 -0
- {opensandbox-0.1.8.dev1 → opensandbox-0.1.9.dev0}/src/opensandbox/api/execd/models/command_status_response.py +0 -0
- {opensandbox-0.1.8.dev1 → opensandbox-0.1.9.dev0}/src/opensandbox/api/execd/models/create_session_request.py +0 -0
- {opensandbox-0.1.8.dev1 → opensandbox-0.1.9.dev0}/src/opensandbox/api/execd/models/create_session_response.py +0 -0
- {opensandbox-0.1.8.dev1 → opensandbox-0.1.9.dev0}/src/opensandbox/api/execd/models/error_response.py +0 -0
- {opensandbox-0.1.8.dev1 → opensandbox-0.1.9.dev0}/src/opensandbox/api/execd/models/file_info.py +0 -0
- {opensandbox-0.1.8.dev1 → opensandbox-0.1.9.dev0}/src/opensandbox/api/execd/models/file_metadata.py +0 -0
- {opensandbox-0.1.8.dev1 → opensandbox-0.1.9.dev0}/src/opensandbox/api/execd/models/get_files_info_response_200.py +0 -0
- {opensandbox-0.1.8.dev1 → opensandbox-0.1.9.dev0}/src/opensandbox/api/execd/models/make_dirs_body.py +0 -0
- {opensandbox-0.1.8.dev1 → opensandbox-0.1.9.dev0}/src/opensandbox/api/execd/models/metrics.py +0 -0
- {opensandbox-0.1.8.dev1 → opensandbox-0.1.9.dev0}/src/opensandbox/api/execd/models/permission.py +0 -0
- {opensandbox-0.1.8.dev1 → opensandbox-0.1.9.dev0}/src/opensandbox/api/execd/models/rename_file_item.py +0 -0
- {opensandbox-0.1.8.dev1 → opensandbox-0.1.9.dev0}/src/opensandbox/api/execd/models/replace_content_body.py +0 -0
- {opensandbox-0.1.8.dev1 → opensandbox-0.1.9.dev0}/src/opensandbox/api/execd/models/replace_file_content_item.py +0 -0
- {opensandbox-0.1.8.dev1 → opensandbox-0.1.9.dev0}/src/opensandbox/api/execd/models/run_code_request.py +0 -0
- {opensandbox-0.1.8.dev1 → opensandbox-0.1.9.dev0}/src/opensandbox/api/execd/models/run_command_request.py +0 -0
- {opensandbox-0.1.8.dev1 → opensandbox-0.1.9.dev0}/src/opensandbox/api/execd/models/run_command_request_envs.py +0 -0
- {opensandbox-0.1.8.dev1 → opensandbox-0.1.9.dev0}/src/opensandbox/api/execd/models/run_in_session_request.py +0 -0
- {opensandbox-0.1.8.dev1 → opensandbox-0.1.9.dev0}/src/opensandbox/api/execd/models/server_stream_event.py +0 -0
- {opensandbox-0.1.8.dev1 → opensandbox-0.1.9.dev0}/src/opensandbox/api/execd/models/server_stream_event_error.py +0 -0
- {opensandbox-0.1.8.dev1 → opensandbox-0.1.9.dev0}/src/opensandbox/api/execd/models/server_stream_event_results.py +0 -0
- {opensandbox-0.1.8.dev1 → opensandbox-0.1.9.dev0}/src/opensandbox/api/execd/models/server_stream_event_type.py +0 -0
- {opensandbox-0.1.8.dev1 → opensandbox-0.1.9.dev0}/src/opensandbox/api/execd/models/upload_file_body.py +0 -0
- {opensandbox-0.1.8.dev1/src/opensandbox/api/lifecycle → opensandbox-0.1.9.dev0/src/opensandbox/api/execd}/py.typed +0 -0
- {opensandbox-0.1.8.dev1/src/opensandbox/api/lifecycle → opensandbox-0.1.9.dev0/src/opensandbox/api/execd}/types.py +0 -0
- {opensandbox-0.1.8.dev1 → opensandbox-0.1.9.dev0}/src/opensandbox/api/lifecycle/__init__.py +0 -0
- {opensandbox-0.1.8.dev1/src/opensandbox/api/lifecycle/api/snapshots → opensandbox-0.1.9.dev0/src/opensandbox/api/lifecycle/api/sandboxes}/__init__.py +0 -0
- {opensandbox-0.1.8.dev1 → opensandbox-0.1.9.dev0}/src/opensandbox/api/lifecycle/api/sandboxes/delete_sandboxes_sandbox_id.py +0 -0
- {opensandbox-0.1.8.dev1 → opensandbox-0.1.9.dev0}/src/opensandbox/api/lifecycle/api/sandboxes/get_sandboxes.py +0 -0
- {opensandbox-0.1.8.dev1 → opensandbox-0.1.9.dev0}/src/opensandbox/api/lifecycle/api/sandboxes/get_sandboxes_sandbox_id.py +0 -0
- {opensandbox-0.1.8.dev1 → opensandbox-0.1.9.dev0}/src/opensandbox/api/lifecycle/api/sandboxes/get_sandboxes_sandbox_id_endpoints_port.py +0 -0
- {opensandbox-0.1.8.dev1 → opensandbox-0.1.9.dev0}/src/opensandbox/api/lifecycle/api/sandboxes/post_sandboxes.py +0 -0
- {opensandbox-0.1.8.dev1 → opensandbox-0.1.9.dev0}/src/opensandbox/api/lifecycle/api/sandboxes/post_sandboxes_sandbox_id_pause.py +0 -0
- {opensandbox-0.1.8.dev1 → opensandbox-0.1.9.dev0}/src/opensandbox/api/lifecycle/api/sandboxes/post_sandboxes_sandbox_id_renew_expiration.py +0 -0
- {opensandbox-0.1.8.dev1 → opensandbox-0.1.9.dev0}/src/opensandbox/api/lifecycle/api/sandboxes/post_sandboxes_sandbox_id_resume.py +0 -0
- {opensandbox-0.1.8.dev1 → opensandbox-0.1.9.dev0}/src/opensandbox/api/lifecycle/api/snapshots/get_snapshots.py +0 -0
- {opensandbox-0.1.8.dev1 → opensandbox-0.1.9.dev0}/src/opensandbox/api/lifecycle/api/snapshots/get_snapshots_snapshot_id.py +0 -0
- {opensandbox-0.1.8.dev1 → opensandbox-0.1.9.dev0}/src/opensandbox/api/lifecycle/models/create_sandbox_request.py +0 -0
- {opensandbox-0.1.8.dev1 → opensandbox-0.1.9.dev0}/src/opensandbox/api/lifecycle/models/create_sandbox_request_env.py +0 -0
- {opensandbox-0.1.8.dev1 → opensandbox-0.1.9.dev0}/src/opensandbox/api/lifecycle/models/create_sandbox_request_extensions.py +0 -0
- {opensandbox-0.1.8.dev1 → opensandbox-0.1.9.dev0}/src/opensandbox/api/lifecycle/models/create_sandbox_request_metadata.py +0 -0
- {opensandbox-0.1.8.dev1 → opensandbox-0.1.9.dev0}/src/opensandbox/api/lifecycle/models/create_sandbox_response.py +0 -0
- {opensandbox-0.1.8.dev1 → opensandbox-0.1.9.dev0}/src/opensandbox/api/lifecycle/models/create_sandbox_response_metadata.py +0 -0
- {opensandbox-0.1.8.dev1 → opensandbox-0.1.9.dev0}/src/opensandbox/api/lifecycle/models/create_snapshot_request.py +0 -0
- {opensandbox-0.1.8.dev1 → opensandbox-0.1.9.dev0}/src/opensandbox/api/lifecycle/models/endpoint.py +0 -0
- {opensandbox-0.1.8.dev1 → opensandbox-0.1.9.dev0}/src/opensandbox/api/lifecycle/models/endpoint_headers.py +0 -0
- {opensandbox-0.1.8.dev1 → opensandbox-0.1.9.dev0}/src/opensandbox/api/lifecycle/models/error_response.py +0 -0
- {opensandbox-0.1.8.dev1 → opensandbox-0.1.9.dev0}/src/opensandbox/api/lifecycle/models/host.py +0 -0
- {opensandbox-0.1.8.dev1 → opensandbox-0.1.9.dev0}/src/opensandbox/api/lifecycle/models/image_spec.py +0 -0
- {opensandbox-0.1.8.dev1 → opensandbox-0.1.9.dev0}/src/opensandbox/api/lifecycle/models/image_spec_auth.py +0 -0
- {opensandbox-0.1.8.dev1 → opensandbox-0.1.9.dev0}/src/opensandbox/api/lifecycle/models/list_sandboxes_response.py +0 -0
- {opensandbox-0.1.8.dev1 → opensandbox-0.1.9.dev0}/src/opensandbox/api/lifecycle/models/list_snapshots_response.py +0 -0
- {opensandbox-0.1.8.dev1 → opensandbox-0.1.9.dev0}/src/opensandbox/api/lifecycle/models/network_policy.py +0 -0
- {opensandbox-0.1.8.dev1 → opensandbox-0.1.9.dev0}/src/opensandbox/api/lifecycle/models/network_policy_default_action.py +0 -0
- {opensandbox-0.1.8.dev1 → opensandbox-0.1.9.dev0}/src/opensandbox/api/lifecycle/models/network_rule.py +0 -0
- {opensandbox-0.1.8.dev1 → opensandbox-0.1.9.dev0}/src/opensandbox/api/lifecycle/models/network_rule_action.py +0 -0
- {opensandbox-0.1.8.dev1 → opensandbox-0.1.9.dev0}/src/opensandbox/api/lifecycle/models/ossfs.py +0 -0
- {opensandbox-0.1.8.dev1 → opensandbox-0.1.9.dev0}/src/opensandbox/api/lifecycle/models/ossfs_version.py +0 -0
- {opensandbox-0.1.8.dev1 → opensandbox-0.1.9.dev0}/src/opensandbox/api/lifecycle/models/pagination_info.py +0 -0
- {opensandbox-0.1.8.dev1 → opensandbox-0.1.9.dev0}/src/opensandbox/api/lifecycle/models/platform_spec.py +0 -0
- {opensandbox-0.1.8.dev1 → opensandbox-0.1.9.dev0}/src/opensandbox/api/lifecycle/models/platform_spec_arch.py +0 -0
- {opensandbox-0.1.8.dev1 → opensandbox-0.1.9.dev0}/src/opensandbox/api/lifecycle/models/platform_spec_os.py +0 -0
- {opensandbox-0.1.8.dev1 → opensandbox-0.1.9.dev0}/src/opensandbox/api/lifecycle/models/pvc.py +0 -0
- {opensandbox-0.1.8.dev1 → opensandbox-0.1.9.dev0}/src/opensandbox/api/lifecycle/models/renew_sandbox_expiration_request.py +0 -0
- {opensandbox-0.1.8.dev1 → opensandbox-0.1.9.dev0}/src/opensandbox/api/lifecycle/models/renew_sandbox_expiration_response.py +0 -0
- {opensandbox-0.1.8.dev1 → opensandbox-0.1.9.dev0}/src/opensandbox/api/lifecycle/models/resource_limits.py +0 -0
- {opensandbox-0.1.8.dev1 → opensandbox-0.1.9.dev0}/src/opensandbox/api/lifecycle/models/sandbox.py +0 -0
- {opensandbox-0.1.8.dev1 → opensandbox-0.1.9.dev0}/src/opensandbox/api/lifecycle/models/sandbox_metadata.py +0 -0
- {opensandbox-0.1.8.dev1 → opensandbox-0.1.9.dev0}/src/opensandbox/api/lifecycle/models/sandbox_status.py +0 -0
- {opensandbox-0.1.8.dev1 → opensandbox-0.1.9.dev0}/src/opensandbox/api/lifecycle/models/snapshot.py +0 -0
- {opensandbox-0.1.8.dev1 → opensandbox-0.1.9.dev0}/src/opensandbox/api/lifecycle/models/snapshot_status.py +0 -0
- {opensandbox-0.1.8.dev1 → opensandbox-0.1.9.dev0}/src/opensandbox/api/lifecycle/models/volume.py +0 -0
- {opensandbox-0.1.8.dev1 → opensandbox-0.1.9.dev0}/src/opensandbox/config/__init__.py +0 -0
- {opensandbox-0.1.8.dev1 → opensandbox-0.1.9.dev0}/src/opensandbox/constants.py +0 -0
- {opensandbox-0.1.8.dev1 → opensandbox-0.1.9.dev0}/src/opensandbox/exceptions/__init__.py +0 -0
- {opensandbox-0.1.8.dev1 → opensandbox-0.1.9.dev0}/src/opensandbox/exceptions/sandbox.py +0 -0
- {opensandbox-0.1.8.dev1 → opensandbox-0.1.9.dev0}/src/opensandbox/models/execd.py +0 -0
- {opensandbox-0.1.8.dev1 → opensandbox-0.1.9.dev0}/src/opensandbox/models/execd_sync.py +0 -0
- {opensandbox-0.1.8.dev1 → opensandbox-0.1.9.dev0}/src/opensandbox/models/filesystem.py +0 -0
- {opensandbox-0.1.8.dev1 → opensandbox-0.1.9.dev0}/src/opensandbox/models/sandboxes.py +0 -0
- {opensandbox-0.1.8.dev1 → opensandbox-0.1.9.dev0}/src/opensandbox/py.typed +0 -0
- {opensandbox-0.1.8.dev1 → opensandbox-0.1.9.dev0}/src/opensandbox/services/command.py +0 -0
- {opensandbox-0.1.8.dev1 → opensandbox-0.1.9.dev0}/src/opensandbox/services/egress.py +0 -0
- {opensandbox-0.1.8.dev1 → opensandbox-0.1.9.dev0}/src/opensandbox/services/filesystem.py +0 -0
- {opensandbox-0.1.8.dev1 → opensandbox-0.1.9.dev0}/src/opensandbox/services/health.py +0 -0
- {opensandbox-0.1.8.dev1 → opensandbox-0.1.9.dev0}/src/opensandbox/services/metrics.py +0 -0
- {opensandbox-0.1.8.dev1 → opensandbox-0.1.9.dev0}/src/opensandbox/sync/__init__.py +0 -0
- {opensandbox-0.1.8.dev1 → opensandbox-0.1.9.dev0}/src/opensandbox/sync/adapters/__init__.py +0 -0
- {opensandbox-0.1.8.dev1 → opensandbox-0.1.9.dev0}/src/opensandbox/sync/adapters/command_adapter.py +0 -0
- {opensandbox-0.1.8.dev1 → opensandbox-0.1.9.dev0}/src/opensandbox/sync/adapters/converter/__init__.py +0 -0
- {opensandbox-0.1.8.dev1 → opensandbox-0.1.9.dev0}/src/opensandbox/sync/adapters/converter/execution_event_dispatcher.py +0 -0
- {opensandbox-0.1.8.dev1 → opensandbox-0.1.9.dev0}/src/opensandbox/sync/adapters/egress_adapter.py +0 -0
- {opensandbox-0.1.8.dev1 → opensandbox-0.1.9.dev0}/src/opensandbox/sync/adapters/filesystem_adapter.py +0 -0
- {opensandbox-0.1.8.dev1 → opensandbox-0.1.9.dev0}/src/opensandbox/sync/adapters/health_adapter.py +0 -0
- {opensandbox-0.1.8.dev1 → opensandbox-0.1.9.dev0}/src/opensandbox/sync/adapters/metrics_adapter.py +0 -0
- {opensandbox-0.1.8.dev1 → opensandbox-0.1.9.dev0}/src/opensandbox/sync/services/command.py +0 -0
- {opensandbox-0.1.8.dev1 → opensandbox-0.1.9.dev0}/src/opensandbox/sync/services/egress.py +0 -0
- {opensandbox-0.1.8.dev1 → opensandbox-0.1.9.dev0}/src/opensandbox/sync/services/filesystem.py +0 -0
- {opensandbox-0.1.8.dev1 → opensandbox-0.1.9.dev0}/src/opensandbox/sync/services/health.py +0 -0
- {opensandbox-0.1.8.dev1 → opensandbox-0.1.9.dev0}/src/opensandbox/sync/services/metrics.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: opensandbox
|
|
3
|
-
Version: 0.1.
|
|
3
|
+
Version: 0.1.9.dev0
|
|
4
4
|
Summary: OpenSandbox Python SDK - Secure, isolated execution environments
|
|
5
5
|
Project-URL: Homepage, https://open-sandbox.ai
|
|
6
6
|
Project-URL: Repository, https://github.com/alibaba/OpenSandbox
|
|
@@ -420,8 +420,9 @@ The store does not create or close Redis clients.
|
|
|
420
420
|
```python
|
|
421
421
|
import redis
|
|
422
422
|
|
|
423
|
-
from opensandbox import PoolCreationSpec,
|
|
423
|
+
from opensandbox import PoolCreationSpec, SandboxPoolSync
|
|
424
424
|
from opensandbox.config import ConnectionConfigSync
|
|
425
|
+
from opensandbox.pool_redis import RedisPoolStateStore
|
|
425
426
|
|
|
426
427
|
redis_client = redis.Redis.from_url(
|
|
427
428
|
"redis://user:password@redis.example.com:6379/0",
|
|
@@ -187,8 +187,9 @@ The store does not create or close Redis clients.
|
|
|
187
187
|
```python
|
|
188
188
|
import redis
|
|
189
189
|
|
|
190
|
-
from opensandbox import PoolCreationSpec,
|
|
190
|
+
from opensandbox import PoolCreationSpec, SandboxPoolSync
|
|
191
191
|
from opensandbox.config import ConnectionConfigSync
|
|
192
|
+
from opensandbox.pool_redis import RedisPoolStateStore
|
|
192
193
|
|
|
193
194
|
redis_client = redis.Redis.from_url(
|
|
194
195
|
"redis://user:password@redis.example.com:6379/0",
|
|
@@ -67,7 +67,7 @@ source = "vcs"
|
|
|
67
67
|
root = "../../.."
|
|
68
68
|
tag_regex = "^python/sandbox/v(?P<version>\\d+\\.\\d+\\.\\d+(?:[\\.\\w\\+\\-]*)?)$"
|
|
69
69
|
git_describe_command = 'git describe --dirty --tags --long --match "python/sandbox/v*"'
|
|
70
|
-
fallback_version = "0.1.
|
|
70
|
+
fallback_version = "0.1.9"
|
|
71
71
|
|
|
72
72
|
[tool.hatch.build]
|
|
73
73
|
include = [
|
|
@@ -142,6 +142,7 @@ branch = true
|
|
|
142
142
|
|
|
143
143
|
[dependency-groups]
|
|
144
144
|
dev = [
|
|
145
|
+
"redis>=5.0,<6.0",
|
|
145
146
|
"pytest>=7.0.0",
|
|
146
147
|
"pytest-asyncio>=0.21.0",
|
|
147
148
|
"pytest-cov>=4.0.0",
|
|
@@ -102,12 +102,10 @@ from importlib.metadata import version as _pkg_version
|
|
|
102
102
|
from opensandbox.manager import SandboxManager
|
|
103
103
|
from opensandbox.pool import (
|
|
104
104
|
AcquirePolicy,
|
|
105
|
-
AsyncRedisPoolStateStore,
|
|
106
105
|
AsyncSandboxPool,
|
|
107
106
|
InMemoryAsyncPoolStateStore,
|
|
108
107
|
InMemoryPoolStateStore,
|
|
109
108
|
PoolCreationSpec,
|
|
110
|
-
RedisPoolStateStore,
|
|
111
109
|
SandboxPool,
|
|
112
110
|
SandboxPoolAsync,
|
|
113
111
|
)
|
|
@@ -133,6 +131,4 @@ __all__ = [
|
|
|
133
131
|
"PoolCreationSpec",
|
|
134
132
|
"InMemoryAsyncPoolStateStore",
|
|
135
133
|
"InMemoryPoolStateStore",
|
|
136
|
-
"AsyncRedisPoolStateStore",
|
|
137
|
-
"RedisPoolStateStore",
|
|
138
134
|
]
|
|
@@ -31,8 +31,8 @@ logger = logging.getLogger(__name__)
|
|
|
31
31
|
@dataclass
|
|
32
32
|
class ReconcileState:
|
|
33
33
|
degraded_threshold: int
|
|
34
|
-
backoff_base: timedelta = timedelta(seconds=
|
|
35
|
-
backoff_max: timedelta = timedelta(
|
|
34
|
+
backoff_base: timedelta = timedelta(seconds=30)
|
|
35
|
+
backoff_max: timedelta = timedelta(days=1)
|
|
36
36
|
failure_count: int = 0
|
|
37
37
|
state: PoolState = PoolState.HEALTHY
|
|
38
38
|
last_error: str | None = None
|
|
@@ -53,7 +53,7 @@ class ReconcileState:
|
|
|
53
53
|
if self.failure_count >= self.degraded_threshold:
|
|
54
54
|
self.state = PoolState.DEGRADED
|
|
55
55
|
self.backoff_attempts += 1
|
|
56
|
-
exponent = min(self.backoff_attempts,
|
|
56
|
+
exponent = min(self.backoff_attempts - 1, 30)
|
|
57
57
|
delay = min(
|
|
58
58
|
self.backoff_base.total_seconds() * (1 << exponent),
|
|
59
59
|
self.backoff_max.total_seconds(),
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
#
|
|
2
|
+
# Copyright 2026 Alibaba Group Holding Ltd.
|
|
3
|
+
#
|
|
4
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
5
|
+
# you may not use this file except in compliance with the License.
|
|
6
|
+
# You may obtain a copy of the License at
|
|
7
|
+
#
|
|
8
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
|
9
|
+
#
|
|
10
|
+
# Unless required by applicable law or agreed to in writing, software
|
|
11
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
12
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
13
|
+
# See the License for the specific language governing permissions and
|
|
14
|
+
# limitations under the License.
|
|
15
|
+
#
|
|
16
|
+
"""Converters for diagnostics API models."""
|
|
17
|
+
|
|
18
|
+
from opensandbox.api.diagnostic.models import (
|
|
19
|
+
DiagnosticContentResponse as ApiDiagnosticContentResponse,
|
|
20
|
+
)
|
|
21
|
+
from opensandbox.models.diagnostics import DiagnosticContent
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
class DiagnosticModelConverter:
|
|
25
|
+
"""Convert generated diagnostics API models to public SDK models."""
|
|
26
|
+
|
|
27
|
+
@staticmethod
|
|
28
|
+
def to_diagnostic_content(
|
|
29
|
+
response: ApiDiagnosticContentResponse,
|
|
30
|
+
) -> DiagnosticContent:
|
|
31
|
+
return DiagnosticContent.model_validate(response.to_dict())
|
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
#
|
|
2
|
+
# Copyright 2026 Alibaba Group Holding Ltd.
|
|
3
|
+
#
|
|
4
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
5
|
+
# you may not use this file except in compliance with the License.
|
|
6
|
+
# You may obtain a copy of the License at
|
|
7
|
+
#
|
|
8
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
|
9
|
+
#
|
|
10
|
+
# Unless required by applicable law or agreed to in writing, software
|
|
11
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
12
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
13
|
+
# See the License for the specific language governing permissions and
|
|
14
|
+
# limitations under the License.
|
|
15
|
+
#
|
|
16
|
+
"""Diagnostics service adapter implementation."""
|
|
17
|
+
|
|
18
|
+
import logging
|
|
19
|
+
|
|
20
|
+
import httpx # type: ignore[reportMissingImports]
|
|
21
|
+
|
|
22
|
+
from opensandbox.adapters.converter.diagnostic_model_converter import (
|
|
23
|
+
DiagnosticModelConverter,
|
|
24
|
+
)
|
|
25
|
+
from opensandbox.adapters.converter.exception_converter import ExceptionConverter
|
|
26
|
+
from opensandbox.adapters.converter.response_handler import (
|
|
27
|
+
handle_api_error,
|
|
28
|
+
require_parsed,
|
|
29
|
+
)
|
|
30
|
+
from opensandbox.config import ConnectionConfig
|
|
31
|
+
from opensandbox.models.diagnostics import DiagnosticContent
|
|
32
|
+
from opensandbox.services.diagnostics import Diagnostics
|
|
33
|
+
|
|
34
|
+
logger = logging.getLogger(__name__)
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
class DiagnosticsAdapter(Diagnostics):
|
|
38
|
+
"""Adapter for sandbox diagnostics management API operations."""
|
|
39
|
+
|
|
40
|
+
def __init__(self, connection_config: ConnectionConfig) -> None:
|
|
41
|
+
self.connection_config = connection_config
|
|
42
|
+
from opensandbox.api.diagnostic import AuthenticatedClient
|
|
43
|
+
|
|
44
|
+
api_key = self.connection_config.get_api_key()
|
|
45
|
+
timeout_seconds = self.connection_config.request_timeout.total_seconds()
|
|
46
|
+
timeout = httpx.Timeout(timeout_seconds)
|
|
47
|
+
|
|
48
|
+
headers = {
|
|
49
|
+
"Accept": "application/json",
|
|
50
|
+
"User-Agent": self.connection_config.user_agent,
|
|
51
|
+
**self.connection_config.headers,
|
|
52
|
+
}
|
|
53
|
+
if api_key:
|
|
54
|
+
headers["OPEN-SANDBOX-API-KEY"] = api_key
|
|
55
|
+
|
|
56
|
+
self._client = AuthenticatedClient(
|
|
57
|
+
base_url=self.connection_config.get_base_url(),
|
|
58
|
+
token=api_key or "",
|
|
59
|
+
prefix="",
|
|
60
|
+
auth_header_name="OPEN-SANDBOX-API-KEY",
|
|
61
|
+
timeout=timeout,
|
|
62
|
+
)
|
|
63
|
+
self._httpx_client = httpx.AsyncClient(
|
|
64
|
+
base_url=self.connection_config.get_base_url(),
|
|
65
|
+
headers=headers,
|
|
66
|
+
timeout=timeout,
|
|
67
|
+
transport=self.connection_config.transport,
|
|
68
|
+
)
|
|
69
|
+
self._client.set_async_httpx_client(self._httpx_client)
|
|
70
|
+
|
|
71
|
+
async def _get_client(self):
|
|
72
|
+
return self._client
|
|
73
|
+
|
|
74
|
+
async def get_logs(
|
|
75
|
+
self,
|
|
76
|
+
sandbox_id: str,
|
|
77
|
+
scope: str,
|
|
78
|
+
) -> DiagnosticContent:
|
|
79
|
+
try:
|
|
80
|
+
from opensandbox.api.diagnostic.api.diagnostics import (
|
|
81
|
+
get_sandboxes_sandbox_id_diagnostics_logs,
|
|
82
|
+
)
|
|
83
|
+
from opensandbox.api.diagnostic.models import DiagnosticContentResponse
|
|
84
|
+
|
|
85
|
+
response_obj = await get_sandboxes_sandbox_id_diagnostics_logs.asyncio_detailed(
|
|
86
|
+
sandbox_id=sandbox_id,
|
|
87
|
+
client=await self._get_client(),
|
|
88
|
+
scope=scope,
|
|
89
|
+
)
|
|
90
|
+
handle_api_error(response_obj, f"Get diagnostic logs for sandbox {sandbox_id}")
|
|
91
|
+
parsed = require_parsed(
|
|
92
|
+
response_obj,
|
|
93
|
+
DiagnosticContentResponse,
|
|
94
|
+
f"Get diagnostic logs for sandbox {sandbox_id}",
|
|
95
|
+
)
|
|
96
|
+
return DiagnosticModelConverter.to_diagnostic_content(parsed)
|
|
97
|
+
except Exception as e:
|
|
98
|
+
logger.error("Failed to get diagnostic logs for sandbox %s", sandbox_id, exc_info=e)
|
|
99
|
+
raise ExceptionConverter.to_sandbox_exception(e) from e
|
|
100
|
+
|
|
101
|
+
async def get_events(
|
|
102
|
+
self,
|
|
103
|
+
sandbox_id: str,
|
|
104
|
+
scope: str,
|
|
105
|
+
) -> DiagnosticContent:
|
|
106
|
+
try:
|
|
107
|
+
from opensandbox.api.diagnostic.api.diagnostics import (
|
|
108
|
+
get_sandboxes_sandbox_id_diagnostics_events,
|
|
109
|
+
)
|
|
110
|
+
from opensandbox.api.diagnostic.models import DiagnosticContentResponse
|
|
111
|
+
|
|
112
|
+
response_obj = await get_sandboxes_sandbox_id_diagnostics_events.asyncio_detailed(
|
|
113
|
+
sandbox_id=sandbox_id,
|
|
114
|
+
client=await self._get_client(),
|
|
115
|
+
scope=scope,
|
|
116
|
+
)
|
|
117
|
+
handle_api_error(response_obj, f"Get diagnostic events for sandbox {sandbox_id}")
|
|
118
|
+
parsed = require_parsed(
|
|
119
|
+
response_obj,
|
|
120
|
+
DiagnosticContentResponse,
|
|
121
|
+
f"Get diagnostic events for sandbox {sandbox_id}",
|
|
122
|
+
)
|
|
123
|
+
return DiagnosticModelConverter.to_diagnostic_content(parsed)
|
|
124
|
+
except Exception as e:
|
|
125
|
+
logger.error("Failed to get diagnostic events for sandbox %s", sandbox_id, exc_info=e)
|
|
126
|
+
raise ExceptionConverter.to_sandbox_exception(e) from e
|
|
@@ -25,6 +25,7 @@ to ensure consistent pooling/proxy/retry behavior across services.
|
|
|
25
25
|
"""
|
|
26
26
|
|
|
27
27
|
from opensandbox.adapters.command_adapter import CommandsAdapter
|
|
28
|
+
from opensandbox.adapters.diagnostics_adapter import DiagnosticsAdapter
|
|
28
29
|
from opensandbox.adapters.egress_adapter import EgressAdapter
|
|
29
30
|
from opensandbox.adapters.filesystem_adapter import FilesystemAdapter
|
|
30
31
|
from opensandbox.adapters.health_adapter import HealthAdapter
|
|
@@ -33,6 +34,7 @@ from opensandbox.adapters.sandboxes_adapter import SandboxesAdapter
|
|
|
33
34
|
from opensandbox.config import ConnectionConfig
|
|
34
35
|
from opensandbox.models.sandboxes import SandboxEndpoint
|
|
35
36
|
from opensandbox.services.command import Commands
|
|
37
|
+
from opensandbox.services.diagnostics import Diagnostics
|
|
36
38
|
from opensandbox.services.egress import Egress
|
|
37
39
|
from opensandbox.services.filesystem import Filesystem
|
|
38
40
|
from opensandbox.services.health import Health
|
|
@@ -70,6 +72,10 @@ class AdapterFactory:
|
|
|
70
72
|
"""
|
|
71
73
|
return SandboxesAdapter(self.connection_config)
|
|
72
74
|
|
|
75
|
+
def create_diagnostics_service(self) -> Diagnostics:
|
|
76
|
+
"""Create a diagnostics service for sandbox troubleshooting operations."""
|
|
77
|
+
return DiagnosticsAdapter(self.connection_config)
|
|
78
|
+
|
|
73
79
|
def create_filesystem_service(self, endpoint: SandboxEndpoint) -> Filesystem:
|
|
74
80
|
"""Create a filesystem service for file and directory operations.
|
|
75
81
|
|
{opensandbox-0.1.8.dev1 → opensandbox-0.1.9.dev0}/src/opensandbox/adapters/sandboxes_adapter.py
RENAMED
|
@@ -233,6 +233,35 @@ class SandboxesAdapter(Sandboxes):
|
|
|
233
233
|
logger.error("Failed to list sandboxes", exc_info=e)
|
|
234
234
|
raise ExceptionConverter.to_sandbox_exception(e) from e
|
|
235
235
|
|
|
236
|
+
async def patch_sandbox_metadata(
|
|
237
|
+
self, sandbox_id: str, patch: dict[str, str | None]
|
|
238
|
+
) -> SandboxInfo:
|
|
239
|
+
"""Patch metadata for a sandbox using the metadata-specific lifecycle endpoint."""
|
|
240
|
+
try:
|
|
241
|
+
from opensandbox.api.lifecycle.api.sandboxes import (
|
|
242
|
+
patch_sandboxes_sandbox_id_metadata,
|
|
243
|
+
)
|
|
244
|
+
from opensandbox.api.lifecycle.models import PatchSandboxMetadataRequest
|
|
245
|
+
from opensandbox.api.lifecycle.models import Sandbox as ApiSandbox
|
|
246
|
+
|
|
247
|
+
client = await self._get_client()
|
|
248
|
+
response_obj = await patch_sandboxes_sandbox_id_metadata.asyncio_detailed(
|
|
249
|
+
client=client,
|
|
250
|
+
sandbox_id=sandbox_id,
|
|
251
|
+
body=PatchSandboxMetadataRequest.from_dict(patch),
|
|
252
|
+
)
|
|
253
|
+
|
|
254
|
+
handle_api_error(response_obj, f"Patch sandbox {sandbox_id} metadata")
|
|
255
|
+
parsed = require_parsed(
|
|
256
|
+
response_obj,
|
|
257
|
+
ApiSandbox,
|
|
258
|
+
f"Patch sandbox {sandbox_id} metadata",
|
|
259
|
+
)
|
|
260
|
+
return SandboxModelConverter.to_sandbox_info(parsed)
|
|
261
|
+
except Exception as e:
|
|
262
|
+
logger.error("Failed to patch sandbox %s metadata", sandbox_id, exc_info=e)
|
|
263
|
+
raise ExceptionConverter.to_sandbox_exception(e) from e
|
|
264
|
+
|
|
236
265
|
async def create_snapshot(
|
|
237
266
|
self, sandbox_id: str, request: CreateSnapshotRequest | None = None
|
|
238
267
|
) -> SnapshotInfo:
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
#
|
|
2
|
+
# Copyright 2026 Alibaba Group Holding Ltd.
|
|
3
|
+
#
|
|
4
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
5
|
+
# you may not use this file except in compliance with the License.
|
|
6
|
+
# You may obtain a copy of the License at
|
|
7
|
+
#
|
|
8
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
|
9
|
+
#
|
|
10
|
+
# Unless required by applicable law or agreed to in writing, software
|
|
11
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
12
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
13
|
+
# See the License for the specific language governing permissions and
|
|
14
|
+
# limitations under the License.
|
|
15
|
+
#
|
|
16
|
+
|
|
17
|
+
"""A client library for accessing OpenSandbox Diagnostics API"""
|
|
18
|
+
|
|
19
|
+
from .client import AuthenticatedClient, Client
|
|
20
|
+
|
|
21
|
+
__all__ = (
|
|
22
|
+
"AuthenticatedClient",
|
|
23
|
+
"Client",
|
|
24
|
+
)
|
|
@@ -0,0 +1,282 @@
|
|
|
1
|
+
#
|
|
2
|
+
# Copyright 2026 Alibaba Group Holding Ltd.
|
|
3
|
+
#
|
|
4
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
5
|
+
# you may not use this file except in compliance with the License.
|
|
6
|
+
# You may obtain a copy of the License at
|
|
7
|
+
#
|
|
8
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
|
9
|
+
#
|
|
10
|
+
# Unless required by applicable law or agreed to in writing, software
|
|
11
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
12
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
13
|
+
# See the License for the specific language governing permissions and
|
|
14
|
+
# limitations under the License.
|
|
15
|
+
#
|
|
16
|
+
|
|
17
|
+
from http import HTTPStatus
|
|
18
|
+
from typing import Any
|
|
19
|
+
from urllib.parse import quote
|
|
20
|
+
|
|
21
|
+
import httpx
|
|
22
|
+
|
|
23
|
+
from ... import errors
|
|
24
|
+
from ...client import AuthenticatedClient, Client
|
|
25
|
+
from ...models.diagnostic_content_response import DiagnosticContentResponse
|
|
26
|
+
from ...models.error_response import ErrorResponse
|
|
27
|
+
from ...types import UNSET, Response
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
def _get_kwargs(
|
|
31
|
+
sandbox_id: str,
|
|
32
|
+
*,
|
|
33
|
+
scope: str,
|
|
34
|
+
) -> dict[str, Any]:
|
|
35
|
+
params: dict[str, Any] = {}
|
|
36
|
+
|
|
37
|
+
params["scope"] = scope
|
|
38
|
+
|
|
39
|
+
params = {k: v for k, v in params.items() if v is not UNSET and v is not None}
|
|
40
|
+
|
|
41
|
+
_kwargs: dict[str, Any] = {
|
|
42
|
+
"method": "get",
|
|
43
|
+
"url": "/sandboxes/{sandbox_id}/diagnostics/events".format(
|
|
44
|
+
sandbox_id=quote(str(sandbox_id), safe=""),
|
|
45
|
+
),
|
|
46
|
+
"params": params,
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
return _kwargs
|
|
50
|
+
|
|
51
|
+
|
|
52
|
+
def _parse_response(
|
|
53
|
+
*, client: AuthenticatedClient | Client, response: httpx.Response
|
|
54
|
+
) -> DiagnosticContentResponse | ErrorResponse | None:
|
|
55
|
+
if response.status_code == 200:
|
|
56
|
+
response_200 = DiagnosticContentResponse.from_dict(response.json())
|
|
57
|
+
|
|
58
|
+
return response_200
|
|
59
|
+
|
|
60
|
+
if response.status_code == 400:
|
|
61
|
+
response_400 = ErrorResponse.from_dict(response.json())
|
|
62
|
+
|
|
63
|
+
return response_400
|
|
64
|
+
|
|
65
|
+
if response.status_code == 401:
|
|
66
|
+
response_401 = ErrorResponse.from_dict(response.json())
|
|
67
|
+
|
|
68
|
+
return response_401
|
|
69
|
+
|
|
70
|
+
if response.status_code == 403:
|
|
71
|
+
response_403 = ErrorResponse.from_dict(response.json())
|
|
72
|
+
|
|
73
|
+
return response_403
|
|
74
|
+
|
|
75
|
+
if response.status_code == 404:
|
|
76
|
+
response_404 = ErrorResponse.from_dict(response.json())
|
|
77
|
+
|
|
78
|
+
return response_404
|
|
79
|
+
|
|
80
|
+
if response.status_code == 500:
|
|
81
|
+
response_500 = ErrorResponse.from_dict(response.json())
|
|
82
|
+
|
|
83
|
+
return response_500
|
|
84
|
+
|
|
85
|
+
if response.status_code == 501:
|
|
86
|
+
response_501 = ErrorResponse.from_dict(response.json())
|
|
87
|
+
|
|
88
|
+
return response_501
|
|
89
|
+
|
|
90
|
+
if client.raise_on_unexpected_status:
|
|
91
|
+
raise errors.UnexpectedStatus(response.status_code, response.content)
|
|
92
|
+
else:
|
|
93
|
+
return None
|
|
94
|
+
|
|
95
|
+
|
|
96
|
+
def _build_response(
|
|
97
|
+
*, client: AuthenticatedClient | Client, response: httpx.Response
|
|
98
|
+
) -> Response[DiagnosticContentResponse | ErrorResponse]:
|
|
99
|
+
return Response(
|
|
100
|
+
status_code=HTTPStatus(response.status_code),
|
|
101
|
+
content=response.content,
|
|
102
|
+
headers=response.headers,
|
|
103
|
+
parsed=_parse_response(client=client, response=response),
|
|
104
|
+
)
|
|
105
|
+
|
|
106
|
+
|
|
107
|
+
def sync_detailed(
|
|
108
|
+
sandbox_id: str,
|
|
109
|
+
*,
|
|
110
|
+
client: AuthenticatedClient | Client,
|
|
111
|
+
scope: str,
|
|
112
|
+
) -> Response[DiagnosticContentResponse | ErrorResponse]:
|
|
113
|
+
"""Get diagnostic events
|
|
114
|
+
|
|
115
|
+
Retrieve a best-effort descriptor for sandbox diagnostic event text.
|
|
116
|
+
|
|
117
|
+
Events are rendered as diagnostic text rather than exposed as a stable
|
|
118
|
+
structured event model. Depending on the selected `scope` and runtime, event
|
|
119
|
+
text may include lifecycle transitions, runtime or platform events such as
|
|
120
|
+
Kubernetes Events, network diagnostic events, process activity events, or
|
|
121
|
+
other implementation-defined event material.
|
|
122
|
+
|
|
123
|
+
This endpoint does not provide streaming, pagination, or a stable line-level
|
|
124
|
+
schema in this version. The server returns a JSON descriptor for currently
|
|
125
|
+
available diagnostic event text for the requested scope, subject to
|
|
126
|
+
implementation-defined retention and response size limits. The descriptor
|
|
127
|
+
either embeds the text as `content` or returns a `contentUrl` where the
|
|
128
|
+
text can be downloaded.
|
|
129
|
+
|
|
130
|
+
Args:
|
|
131
|
+
sandbox_id (str):
|
|
132
|
+
scope (str):
|
|
133
|
+
|
|
134
|
+
Raises:
|
|
135
|
+
errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True.
|
|
136
|
+
httpx.TimeoutException: If the request takes longer than Client.timeout.
|
|
137
|
+
|
|
138
|
+
Returns:
|
|
139
|
+
Response[DiagnosticContentResponse | ErrorResponse]
|
|
140
|
+
"""
|
|
141
|
+
|
|
142
|
+
kwargs = _get_kwargs(
|
|
143
|
+
sandbox_id=sandbox_id,
|
|
144
|
+
scope=scope,
|
|
145
|
+
)
|
|
146
|
+
|
|
147
|
+
response = client.get_httpx_client().request(
|
|
148
|
+
**kwargs,
|
|
149
|
+
)
|
|
150
|
+
|
|
151
|
+
return _build_response(client=client, response=response)
|
|
152
|
+
|
|
153
|
+
|
|
154
|
+
def sync(
|
|
155
|
+
sandbox_id: str,
|
|
156
|
+
*,
|
|
157
|
+
client: AuthenticatedClient | Client,
|
|
158
|
+
scope: str,
|
|
159
|
+
) -> DiagnosticContentResponse | ErrorResponse | None:
|
|
160
|
+
"""Get diagnostic events
|
|
161
|
+
|
|
162
|
+
Retrieve a best-effort descriptor for sandbox diagnostic event text.
|
|
163
|
+
|
|
164
|
+
Events are rendered as diagnostic text rather than exposed as a stable
|
|
165
|
+
structured event model. Depending on the selected `scope` and runtime, event
|
|
166
|
+
text may include lifecycle transitions, runtime or platform events such as
|
|
167
|
+
Kubernetes Events, network diagnostic events, process activity events, or
|
|
168
|
+
other implementation-defined event material.
|
|
169
|
+
|
|
170
|
+
This endpoint does not provide streaming, pagination, or a stable line-level
|
|
171
|
+
schema in this version. The server returns a JSON descriptor for currently
|
|
172
|
+
available diagnostic event text for the requested scope, subject to
|
|
173
|
+
implementation-defined retention and response size limits. The descriptor
|
|
174
|
+
either embeds the text as `content` or returns a `contentUrl` where the
|
|
175
|
+
text can be downloaded.
|
|
176
|
+
|
|
177
|
+
Args:
|
|
178
|
+
sandbox_id (str):
|
|
179
|
+
scope (str):
|
|
180
|
+
|
|
181
|
+
Raises:
|
|
182
|
+
errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True.
|
|
183
|
+
httpx.TimeoutException: If the request takes longer than Client.timeout.
|
|
184
|
+
|
|
185
|
+
Returns:
|
|
186
|
+
DiagnosticContentResponse | ErrorResponse
|
|
187
|
+
"""
|
|
188
|
+
|
|
189
|
+
return sync_detailed(
|
|
190
|
+
sandbox_id=sandbox_id,
|
|
191
|
+
client=client,
|
|
192
|
+
scope=scope,
|
|
193
|
+
).parsed
|
|
194
|
+
|
|
195
|
+
|
|
196
|
+
async def asyncio_detailed(
|
|
197
|
+
sandbox_id: str,
|
|
198
|
+
*,
|
|
199
|
+
client: AuthenticatedClient | Client,
|
|
200
|
+
scope: str,
|
|
201
|
+
) -> Response[DiagnosticContentResponse | ErrorResponse]:
|
|
202
|
+
"""Get diagnostic events
|
|
203
|
+
|
|
204
|
+
Retrieve a best-effort descriptor for sandbox diagnostic event text.
|
|
205
|
+
|
|
206
|
+
Events are rendered as diagnostic text rather than exposed as a stable
|
|
207
|
+
structured event model. Depending on the selected `scope` and runtime, event
|
|
208
|
+
text may include lifecycle transitions, runtime or platform events such as
|
|
209
|
+
Kubernetes Events, network diagnostic events, process activity events, or
|
|
210
|
+
other implementation-defined event material.
|
|
211
|
+
|
|
212
|
+
This endpoint does not provide streaming, pagination, or a stable line-level
|
|
213
|
+
schema in this version. The server returns a JSON descriptor for currently
|
|
214
|
+
available diagnostic event text for the requested scope, subject to
|
|
215
|
+
implementation-defined retention and response size limits. The descriptor
|
|
216
|
+
either embeds the text as `content` or returns a `contentUrl` where the
|
|
217
|
+
text can be downloaded.
|
|
218
|
+
|
|
219
|
+
Args:
|
|
220
|
+
sandbox_id (str):
|
|
221
|
+
scope (str):
|
|
222
|
+
|
|
223
|
+
Raises:
|
|
224
|
+
errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True.
|
|
225
|
+
httpx.TimeoutException: If the request takes longer than Client.timeout.
|
|
226
|
+
|
|
227
|
+
Returns:
|
|
228
|
+
Response[DiagnosticContentResponse | ErrorResponse]
|
|
229
|
+
"""
|
|
230
|
+
|
|
231
|
+
kwargs = _get_kwargs(
|
|
232
|
+
sandbox_id=sandbox_id,
|
|
233
|
+
scope=scope,
|
|
234
|
+
)
|
|
235
|
+
|
|
236
|
+
response = await client.get_async_httpx_client().request(**kwargs)
|
|
237
|
+
|
|
238
|
+
return _build_response(client=client, response=response)
|
|
239
|
+
|
|
240
|
+
|
|
241
|
+
async def asyncio(
|
|
242
|
+
sandbox_id: str,
|
|
243
|
+
*,
|
|
244
|
+
client: AuthenticatedClient | Client,
|
|
245
|
+
scope: str,
|
|
246
|
+
) -> DiagnosticContentResponse | ErrorResponse | None:
|
|
247
|
+
"""Get diagnostic events
|
|
248
|
+
|
|
249
|
+
Retrieve a best-effort descriptor for sandbox diagnostic event text.
|
|
250
|
+
|
|
251
|
+
Events are rendered as diagnostic text rather than exposed as a stable
|
|
252
|
+
structured event model. Depending on the selected `scope` and runtime, event
|
|
253
|
+
text may include lifecycle transitions, runtime or platform events such as
|
|
254
|
+
Kubernetes Events, network diagnostic events, process activity events, or
|
|
255
|
+
other implementation-defined event material.
|
|
256
|
+
|
|
257
|
+
This endpoint does not provide streaming, pagination, or a stable line-level
|
|
258
|
+
schema in this version. The server returns a JSON descriptor for currently
|
|
259
|
+
available diagnostic event text for the requested scope, subject to
|
|
260
|
+
implementation-defined retention and response size limits. The descriptor
|
|
261
|
+
either embeds the text as `content` or returns a `contentUrl` where the
|
|
262
|
+
text can be downloaded.
|
|
263
|
+
|
|
264
|
+
Args:
|
|
265
|
+
sandbox_id (str):
|
|
266
|
+
scope (str):
|
|
267
|
+
|
|
268
|
+
Raises:
|
|
269
|
+
errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True.
|
|
270
|
+
httpx.TimeoutException: If the request takes longer than Client.timeout.
|
|
271
|
+
|
|
272
|
+
Returns:
|
|
273
|
+
DiagnosticContentResponse | ErrorResponse
|
|
274
|
+
"""
|
|
275
|
+
|
|
276
|
+
return (
|
|
277
|
+
await asyncio_detailed(
|
|
278
|
+
sandbox_id=sandbox_id,
|
|
279
|
+
client=client,
|
|
280
|
+
scope=scope,
|
|
281
|
+
)
|
|
282
|
+
).parsed
|