runta-sdk 0.2.2__tar.gz → 0.2.3__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.
- {runta_sdk-0.2.2 → runta_sdk-0.2.3}/PKG-INFO +30 -1
- {runta_sdk-0.2.2 → runta_sdk-0.2.3}/README.md +29 -0
- {runta_sdk-0.2.2 → runta_sdk-0.2.3}/integrations/harbor/runta_harbor/environment.py +13 -21
- {runta_sdk-0.2.2 → runta_sdk-0.2.3}/pyproject.toml +1 -1
- {runta_sdk-0.2.2 → runta_sdk-0.2.3}/runta_sdk.egg-info/PKG-INFO +30 -1
- {runta_sdk-0.2.2 → runta_sdk-0.2.3}/runta_sdk.egg-info/SOURCES.txt +2 -0
- {runta_sdk-0.2.2 → runta_sdk-0.2.3}/src/runta/__init__.py +72 -1
- {runta_sdk-0.2.2 → runta_sdk-0.2.3}/src/runta/_internal/async_http.py +24 -0
- {runta_sdk-0.2.2 → runta_sdk-0.2.3}/src/runta/_internal/openapi/models/runtime.py +21 -0
- {runta_sdk-0.2.2 → runta_sdk-0.2.3}/src/runta/_internal/streaming_transfer.py +228 -5
- {runta_sdk-0.2.2 → runta_sdk-0.2.3}/src/runta/_internal/sync_http.py +23 -0
- runta_sdk-0.2.3/tests/test_download_dir_contents.py +541 -0
- runta_sdk-0.2.3/tests/test_download_dir_contents_live.py +126 -0
- runta_sdk-0.2.3/tests/test_harbor_directory_download.py +76 -0
- runta_sdk-0.2.2/tests/test_harbor_directory_download.py +0 -193
- {runta_sdk-0.2.2 → runta_sdk-0.2.3}/integrations/harbor/runta_harbor/__init__.py +0 -0
- {runta_sdk-0.2.2 → runta_sdk-0.2.3}/integrations/harbor/runta_harbor/py.typed +0 -0
- {runta_sdk-0.2.2 → runta_sdk-0.2.3}/integrations/openai-agents-runta/src/agents_runta/__init__.py +0 -0
- {runta_sdk-0.2.2 → runta_sdk-0.2.3}/integrations/openai-agents-runta/src/agents_runta/durable/__init__.py +0 -0
- {runta_sdk-0.2.2 → runta_sdk-0.2.3}/integrations/openai-agents-runta/src/agents_runta/durable/runner.py +0 -0
- {runta_sdk-0.2.2 → runta_sdk-0.2.3}/integrations/openai-agents-runta/src/agents_runta/durable/store.py +0 -0
- {runta_sdk-0.2.2 → runta_sdk-0.2.3}/integrations/openai-agents-runta/src/agents_runta/py.typed +0 -0
- {runta_sdk-0.2.2 → runta_sdk-0.2.3}/integrations/openai-agents-runta/src/agents_runta/sandbox.py +0 -0
- {runta_sdk-0.2.2 → runta_sdk-0.2.3}/runta_sdk.egg-info/dependency_links.txt +0 -0
- {runta_sdk-0.2.2 → runta_sdk-0.2.3}/runta_sdk.egg-info/requires.txt +0 -0
- {runta_sdk-0.2.2 → runta_sdk-0.2.3}/runta_sdk.egg-info/top_level.txt +0 -0
- {runta_sdk-0.2.2 → runta_sdk-0.2.3}/setup.cfg +0 -0
- {runta_sdk-0.2.2 → runta_sdk-0.2.3}/src/runta/_internal/__init__.py +0 -0
- {runta_sdk-0.2.2 → runta_sdk-0.2.3}/src/runta/_internal/async_file_io.py +0 -0
- {runta_sdk-0.2.2 → runta_sdk-0.2.3}/src/runta/_internal/byte_budget.py +0 -0
- {runta_sdk-0.2.2 → runta_sdk-0.2.3}/src/runta/_internal/config.py +0 -0
- {runta_sdk-0.2.2 → runta_sdk-0.2.3}/src/runta/_internal/execution.py +0 -0
- {runta_sdk-0.2.2 → runta_sdk-0.2.3}/src/runta/_internal/execution.sh +0 -0
- {runta_sdk-0.2.2 → runta_sdk-0.2.3}/src/runta/_internal/helpers.py +0 -0
- {runta_sdk-0.2.2 → runta_sdk-0.2.3}/src/runta/_internal/http_limits.py +0 -0
- {runta_sdk-0.2.2 → runta_sdk-0.2.3}/src/runta/_internal/openapi/__init__.py +0 -0
- {runta_sdk-0.2.2 → runta_sdk-0.2.3}/src/runta/_internal/openapi/api/__init__.py +0 -0
- {runta_sdk-0.2.2 → runta_sdk-0.2.3}/src/runta/_internal/openapi/api/auth/__init__.py +0 -0
- {runta_sdk-0.2.2 → runta_sdk-0.2.3}/src/runta/_internal/openapi/api/auth/begin_device_authorization.py +0 -0
- {runta_sdk-0.2.2 → runta_sdk-0.2.3}/src/runta/_internal/openapi/api/auth/exchange_device_token.py +0 -0
- {runta_sdk-0.2.2 → runta_sdk-0.2.3}/src/runta/_internal/openapi/api/auth/revoke_current_token.py +0 -0
- {runta_sdk-0.2.2 → runta_sdk-0.2.3}/src/runta/_internal/openapi/api/checkpoints/__init__.py +0 -0
- {runta_sdk-0.2.2 → runta_sdk-0.2.3}/src/runta/_internal/openapi/api/checkpoints/create_checkpoint.py +0 -0
- {runta_sdk-0.2.2 → runta_sdk-0.2.3}/src/runta/_internal/openapi/api/checkpoints/delete_checkpoint.py +0 -0
- {runta_sdk-0.2.2 → runta_sdk-0.2.3}/src/runta/_internal/openapi/api/checkpoints/get_checkpoint.py +0 -0
- {runta_sdk-0.2.2 → runta_sdk-0.2.3}/src/runta/_internal/openapi/api/checkpoints/list_checkpoints.py +0 -0
- {runta_sdk-0.2.2 → runta_sdk-0.2.3}/src/runta/_internal/openapi/api/cloud_agents/__init__.py +0 -0
- {runta_sdk-0.2.2 → runta_sdk-0.2.3}/src/runta/_internal/openapi/api/cloud_agents/cancel_cloud_agent_run.py +0 -0
- {runta_sdk-0.2.2 → runta_sdk-0.2.3}/src/runta/_internal/openapi/api/cloud_agents/create_cloud_agent.py +0 -0
- {runta_sdk-0.2.2 → runta_sdk-0.2.3}/src/runta/_internal/openapi/api/cloud_agents/create_cloud_agent_artifact.py +0 -0
- {runta_sdk-0.2.2 → runta_sdk-0.2.3}/src/runta/_internal/openapi/api/cloud_agents/create_cloud_agent_computer_session.py +0 -0
- {runta_sdk-0.2.2 → runta_sdk-0.2.3}/src/runta/_internal/openapi/api/cloud_agents/create_cloud_agent_run.py +0 -0
- {runta_sdk-0.2.2 → runta_sdk-0.2.3}/src/runta/_internal/openapi/api/cloud_agents/delete_cloud_agent.py +0 -0
- {runta_sdk-0.2.2 → runta_sdk-0.2.3}/src/runta/_internal/openapi/api/cloud_agents/delete_cloud_agent_artifact.py +0 -0
- {runta_sdk-0.2.2 → runta_sdk-0.2.3}/src/runta/_internal/openapi/api/cloud_agents/delete_cloud_agent_workspace_file.py +0 -0
- {runta_sdk-0.2.2 → runta_sdk-0.2.3}/src/runta/_internal/openapi/api/cloud_agents/execute_cloud_agent_workspace_operation.py +0 -0
- {runta_sdk-0.2.2 → runta_sdk-0.2.3}/src/runta/_internal/openapi/api/cloud_agents/follow_up_cloud_agent_run.py +0 -0
- {runta_sdk-0.2.2 → runta_sdk-0.2.3}/src/runta/_internal/openapi/api/cloud_agents/get_cloud_agent.py +0 -0
- {runta_sdk-0.2.2 → runta_sdk-0.2.3}/src/runta/_internal/openapi/api/cloud_agents/get_cloud_agent_artifact.py +0 -0
- {runta_sdk-0.2.2 → runta_sdk-0.2.3}/src/runta/_internal/openapi/api/cloud_agents/get_cloud_agent_run.py +0 -0
- {runta_sdk-0.2.2 → runta_sdk-0.2.3}/src/runta/_internal/openapi/api/cloud_agents/list_cloud_agent_artifacts.py +0 -0
- {runta_sdk-0.2.2 → runta_sdk-0.2.3}/src/runta/_internal/openapi/api/cloud_agents/list_cloud_agent_runs.py +0 -0
- {runta_sdk-0.2.2 → runta_sdk-0.2.3}/src/runta/_internal/openapi/api/cloud_agents/list_cloud_agent_session_events.py +0 -0
- {runta_sdk-0.2.2 → runta_sdk-0.2.3}/src/runta/_internal/openapi/api/cloud_agents/list_cloud_agents.py +0 -0
- {runta_sdk-0.2.2 → runta_sdk-0.2.3}/src/runta/_internal/openapi/api/cloud_agents/resume_cloud_agent_run.py +0 -0
- {runta_sdk-0.2.2 → runta_sdk-0.2.3}/src/runta/_internal/openapi/api/cloud_agents/stream_cloud_agent_run_events.py +0 -0
- {runta_sdk-0.2.2 → runta_sdk-0.2.3}/src/runta/_internal/openapi/api/cloud_agents/update_cloud_agent.py +0 -0
- {runta_sdk-0.2.2 → runta_sdk-0.2.3}/src/runta/_internal/openapi/api/cloud_agents/write_cloud_agent_workspace_file.py +0 -0
- {runta_sdk-0.2.2 → runta_sdk-0.2.3}/src/runta/_internal/openapi/api/events/__init__.py +0 -0
- {runta_sdk-0.2.2 → runta_sdk-0.2.3}/src/runta/_internal/openapi/api/events/get_organization_event.py +0 -0
- {runta_sdk-0.2.2 → runta_sdk-0.2.3}/src/runta/_internal/openapi/api/events/get_organization_token_analysis.py +0 -0
- {runta_sdk-0.2.2 → runta_sdk-0.2.3}/src/runta/_internal/openapi/api/events/list_organization_events.py +0 -0
- {runta_sdk-0.2.2 → runta_sdk-0.2.3}/src/runta/_internal/openapi/api/events/list_organization_token_analysis.py +0 -0
- {runta_sdk-0.2.2 → runta_sdk-0.2.3}/src/runta/_internal/openapi/api/events/list_organization_token_savings.py +0 -0
- {runta_sdk-0.2.2 → runta_sdk-0.2.3}/src/runta/_internal/openapi/api/files/__init__.py +0 -0
- {runta_sdk-0.2.2 → runta_sdk-0.2.3}/src/runta/_internal/openapi/api/files/read_runtime_file.py +0 -0
- {runta_sdk-0.2.2 → runta_sdk-0.2.3}/src/runta/_internal/openapi/api/files/write_runtime_file.py +0 -0
- {runta_sdk-0.2.2 → runta_sdk-0.2.3}/src/runta/_internal/openapi/api/git_hub/__init__.py +0 -0
- {runta_sdk-0.2.2 → runta_sdk-0.2.3}/src/runta/_internal/openapi/api/git_hub/create_git_hub_authorization_request.py +0 -0
- {runta_sdk-0.2.2 → runta_sdk-0.2.3}/src/runta/_internal/openapi/api/git_hub/create_git_hub_runtime_binding.py +0 -0
- {runta_sdk-0.2.2 → runta_sdk-0.2.3}/src/runta/_internal/openapi/api/git_hub/delete_git_hub_runtime_binding.py +0 -0
- {runta_sdk-0.2.2 → runta_sdk-0.2.3}/src/runta/_internal/openapi/api/git_hub/get_git_hub_authorization_request.py +0 -0
- {runta_sdk-0.2.2 → runta_sdk-0.2.3}/src/runta/_internal/openapi/api/git_hub/get_git_hub_runtime_binding.py +0 -0
- {runta_sdk-0.2.2 → runta_sdk-0.2.3}/src/runta/_internal/openapi/api/git_hub/list_git_hub_authorization_requests.py +0 -0
- {runta_sdk-0.2.2 → runta_sdk-0.2.3}/src/runta/_internal/openapi/api/git_hub/list_git_hub_branches.py +0 -0
- {runta_sdk-0.2.2 → runta_sdk-0.2.3}/src/runta/_internal/openapi/api/git_hub/list_git_hub_repositories.py +0 -0
- {runta_sdk-0.2.2 → runta_sdk-0.2.3}/src/runta/_internal/openapi/api/git_hub/replace_git_hub_runtime_bindings.py +0 -0
- {runta_sdk-0.2.2 → runta_sdk-0.2.3}/src/runta/_internal/openapi/api/health/__init__.py +0 -0
- {runta_sdk-0.2.2 → runta_sdk-0.2.3}/src/runta/_internal/openapi/api/health/head_healthz.py +0 -0
- {runta_sdk-0.2.2 → runta_sdk-0.2.3}/src/runta/_internal/openapi/api/health/healthz.py +0 -0
- {runta_sdk-0.2.2 → runta_sdk-0.2.3}/src/runta/_internal/openapi/api/identity/__init__.py +0 -0
- {runta_sdk-0.2.2 → runta_sdk-0.2.3}/src/runta/_internal/openapi/api/identity/get_me.py +0 -0
- {runta_sdk-0.2.2 → runta_sdk-0.2.3}/src/runta/_internal/openapi/api/managed_model_providers/__init__.py +0 -0
- {runta_sdk-0.2.2 → runta_sdk-0.2.3}/src/runta/_internal/openapi/api/managed_model_providers/list_managed_model_providers.py +0 -0
- {runta_sdk-0.2.2 → runta_sdk-0.2.3}/src/runta/_internal/openapi/api/managed_model_providers/update_managed_model_provider.py +0 -0
- {runta_sdk-0.2.2 → runta_sdk-0.2.3}/src/runta/_internal/openapi/api/runtimes/__init__.py +0 -0
- {runta_sdk-0.2.2 → runta_sdk-0.2.3}/src/runta/_internal/openapi/api/runtimes/cancel_runtime_image_build.py +0 -0
- {runta_sdk-0.2.2 → runta_sdk-0.2.3}/src/runta/_internal/openapi/api/runtimes/create_runtime.py +0 -0
- {runta_sdk-0.2.2 → runta_sdk-0.2.3}/src/runta/_internal/openapi/api/runtimes/create_runtime_image_build.py +0 -0
- {runta_sdk-0.2.2 → runta_sdk-0.2.3}/src/runta/_internal/openapi/api/runtimes/create_runtime_vnc_credential.py +0 -0
- {runta_sdk-0.2.2 → runta_sdk-0.2.3}/src/runta/_internal/openapi/api/runtimes/delete_runtime.py +0 -0
- {runta_sdk-0.2.2 → runta_sdk-0.2.3}/src/runta/_internal/openapi/api/runtimes/delete_runtime_image.py +0 -0
- {runta_sdk-0.2.2 → runta_sdk-0.2.3}/src/runta/_internal/openapi/api/runtimes/disable_runtime_vnc.py +0 -0
- {runta_sdk-0.2.2 → runta_sdk-0.2.3}/src/runta/_internal/openapi/api/runtimes/dismiss_runtime_image_build.py +0 -0
- {runta_sdk-0.2.2 → runta_sdk-0.2.3}/src/runta/_internal/openapi/api/runtimes/enable_runtime_vnc.py +0 -0
- {runta_sdk-0.2.2 → runta_sdk-0.2.3}/src/runta/_internal/openapi/api/runtimes/get_runtime.py +0 -0
- {runta_sdk-0.2.2 → runta_sdk-0.2.3}/src/runta/_internal/openapi/api/runtimes/get_runtime_image_build.py +0 -0
- {runta_sdk-0.2.2 → runta_sdk-0.2.3}/src/runta/_internal/openapi/api/runtimes/list_runtime_image_builds.py +0 -0
- {runta_sdk-0.2.2 → runta_sdk-0.2.3}/src/runta/_internal/openapi/api/runtimes/list_runtime_images.py +0 -0
- {runta_sdk-0.2.2 → runta_sdk-0.2.3}/src/runta/_internal/openapi/api/runtimes/list_runtime_vnc_credentials.py +0 -0
- {runta_sdk-0.2.2 → runta_sdk-0.2.3}/src/runta/_internal/openapi/api/runtimes/list_runtimes.py +0 -0
- {runta_sdk-0.2.2 → runta_sdk-0.2.3}/src/runta/_internal/openapi/api/runtimes/patch_runtime.py +0 -0
- {runta_sdk-0.2.2 → runta_sdk-0.2.3}/src/runta/_internal/openapi/api/runtimes/pause_runtime.py +0 -0
- {runta_sdk-0.2.2 → runta_sdk-0.2.3}/src/runta/_internal/openapi/api/runtimes/resume_runtime.py +0 -0
- {runta_sdk-0.2.2 → runta_sdk-0.2.3}/src/runta/_internal/openapi/api/runtimes/revoke_runtime_vnc_credential.py +0 -0
- {runta_sdk-0.2.2 → runta_sdk-0.2.3}/src/runta/_internal/openapi/api/runtimes/start_runtime.py +0 -0
- {runta_sdk-0.2.2 → runta_sdk-0.2.3}/src/runta/_internal/openapi/api/runtimes/stop_runtime.py +0 -0
- {runta_sdk-0.2.2 → runta_sdk-0.2.3}/src/runta/_internal/openapi/api/secrets/__init__.py +0 -0
- {runta_sdk-0.2.2 → runta_sdk-0.2.3}/src/runta/_internal/openapi/api/secrets/create_secret.py +0 -0
- {runta_sdk-0.2.2 → runta_sdk-0.2.3}/src/runta/_internal/openapi/api/secrets/delete_secret.py +0 -0
- {runta_sdk-0.2.2 → runta_sdk-0.2.3}/src/runta/_internal/openapi/api/secrets/get_secret.py +0 -0
- {runta_sdk-0.2.2 → runta_sdk-0.2.3}/src/runta/_internal/openapi/api/secrets/list_secrets.py +0 -0
- {runta_sdk-0.2.2 → runta_sdk-0.2.3}/src/runta/_internal/openapi/api/secrets/set_secret.py +0 -0
- {runta_sdk-0.2.2 → runta_sdk-0.2.3}/src/runta/_internal/openapi/api/ssh_keys/__init__.py +0 -0
- {runta_sdk-0.2.2 → runta_sdk-0.2.3}/src/runta/_internal/openapi/api/ssh_keys/attach_runtime_ssh_key.py +0 -0
- {runta_sdk-0.2.2 → runta_sdk-0.2.3}/src/runta/_internal/openapi/api/ssh_keys/create_ssh_key.py +0 -0
- {runta_sdk-0.2.2 → runta_sdk-0.2.3}/src/runta/_internal/openapi/api/ssh_keys/delete_ssh_key.py +0 -0
- {runta_sdk-0.2.2 → runta_sdk-0.2.3}/src/runta/_internal/openapi/api/ssh_keys/detach_runtime_ssh_key.py +0 -0
- {runta_sdk-0.2.2 → runta_sdk-0.2.3}/src/runta/_internal/openapi/api/ssh_keys/get_ssh_host_key.py +0 -0
- {runta_sdk-0.2.2 → runta_sdk-0.2.3}/src/runta/_internal/openapi/api/ssh_keys/list_runtime_ssh_keys.py +0 -0
- {runta_sdk-0.2.2 → runta_sdk-0.2.3}/src/runta/_internal/openapi/api/ssh_keys/list_ssh_keys.py +0 -0
- {runta_sdk-0.2.2 → runta_sdk-0.2.3}/src/runta/_internal/openapi/client.py +0 -0
- {runta_sdk-0.2.2 → runta_sdk-0.2.3}/src/runta/_internal/openapi/errors.py +0 -0
- {runta_sdk-0.2.2 → runta_sdk-0.2.3}/src/runta/_internal/openapi/models/__init__.py +0 -0
- {runta_sdk-0.2.2 → runta_sdk-0.2.3}/src/runta/_internal/openapi/models/allowlist_egress_policy.py +0 -0
- {runta_sdk-0.2.2 → runta_sdk-0.2.3}/src/runta/_internal/openapi/models/allowlist_egress_policy_mode.py +0 -0
- {runta_sdk-0.2.2 → runta_sdk-0.2.3}/src/runta/_internal/openapi/models/approved_git_hub_authorization.py +0 -0
- {runta_sdk-0.2.2 → runta_sdk-0.2.3}/src/runta/_internal/openapi/models/approved_git_hub_authorization_status.py +0 -0
- {runta_sdk-0.2.2 → runta_sdk-0.2.3}/src/runta/_internal/openapi/models/begin_device_authorization_request.py +0 -0
- {runta_sdk-0.2.2 → runta_sdk-0.2.3}/src/runta/_internal/openapi/models/begin_device_authorization_request_client_id.py +0 -0
- {runta_sdk-0.2.2 → runta_sdk-0.2.3}/src/runta/_internal/openapi/models/checkpoint.py +0 -0
- {runta_sdk-0.2.2 → runta_sdk-0.2.3}/src/runta/_internal/openapi/models/checkpoint_pagination.py +0 -0
- {runta_sdk-0.2.2 → runta_sdk-0.2.3}/src/runta/_internal/openapi/models/checkpoint_response.py +0 -0
- {runta_sdk-0.2.2 → runta_sdk-0.2.3}/src/runta/_internal/openapi/models/checkpoint_runtime_restore_request.py +0 -0
- {runta_sdk-0.2.2 → runta_sdk-0.2.3}/src/runta/_internal/openapi/models/checkpoint_source_runtime.py +0 -0
- {runta_sdk-0.2.2 → runta_sdk-0.2.3}/src/runta/_internal/openapi/models/cloud_agent.py +0 -0
- {runta_sdk-0.2.2 → runta_sdk-0.2.3}/src/runta/_internal/openapi/models/cloud_agent_artifact.py +0 -0
- {runta_sdk-0.2.2 → runta_sdk-0.2.3}/src/runta/_internal/openapi/models/cloud_agent_computer_session.py +0 -0
- {runta_sdk-0.2.2 → runta_sdk-0.2.3}/src/runta/_internal/openapi/models/cloud_agent_computer_session_channels.py +0 -0
- {runta_sdk-0.2.2 → runta_sdk-0.2.3}/src/runta/_internal/openapi/models/cloud_agent_event.py +0 -0
- {runta_sdk-0.2.2 → runta_sdk-0.2.3}/src/runta/_internal/openapi/models/cloud_agent_harness_request.py +0 -0
- {runta_sdk-0.2.2 → runta_sdk-0.2.3}/src/runta/_internal/openapi/models/cloud_agent_latest_reply.py +0 -0
- {runta_sdk-0.2.2 → runta_sdk-0.2.3}/src/runta/_internal/openapi/models/cloud_agent_list.py +0 -0
- {runta_sdk-0.2.2 → runta_sdk-0.2.3}/src/runta/_internal/openapi/models/cloud_agent_prompt_image.py +0 -0
- {runta_sdk-0.2.2 → runta_sdk-0.2.3}/src/runta/_internal/openapi/models/cloud_agent_prompt_image_mime_type.py +0 -0
- {runta_sdk-0.2.2 → runta_sdk-0.2.3}/src/runta/_internal/openapi/models/cloud_agent_prompt_image_type.py +0 -0
- {runta_sdk-0.2.2 → runta_sdk-0.2.3}/src/runta/_internal/openapi/models/cloud_agent_run.py +0 -0
- {runta_sdk-0.2.2 → runta_sdk-0.2.3}/src/runta/_internal/openapi/models/cloud_agent_runtime_reference.py +0 -0
- {runta_sdk-0.2.2 → runta_sdk-0.2.3}/src/runta/_internal/openapi/models/cloud_agent_runtime_reference_type.py +0 -0
- {runta_sdk-0.2.2 → runta_sdk-0.2.3}/src/runta/_internal/openapi/models/cloud_agent_session_events.py +0 -0
- {runta_sdk-0.2.2 → runta_sdk-0.2.3}/src/runta/_internal/openapi/models/cloud_agent_vnc_session_channel.py +0 -0
- {runta_sdk-0.2.2 → runta_sdk-0.2.3}/src/runta/_internal/openapi/models/cloud_agent_workspace_delete_request.py +0 -0
- {runta_sdk-0.2.2 → runta_sdk-0.2.3}/src/runta/_internal/openapi/models/cloud_agent_workspace_write_request.py +0 -0
- {runta_sdk-0.2.2 → runta_sdk-0.2.3}/src/runta/_internal/openapi/models/cloud_agent_workspace_write_result.py +0 -0
- {runta_sdk-0.2.2 → runta_sdk-0.2.3}/src/runta/_internal/openapi/models/cold_restore_resource_requests.py +0 -0
- {runta_sdk-0.2.2 → runta_sdk-0.2.3}/src/runta/_internal/openapi/models/cold_restore_resources.py +0 -0
- {runta_sdk-0.2.2 → runta_sdk-0.2.3}/src/runta/_internal/openapi/models/create_checkpoint_request.py +0 -0
- {runta_sdk-0.2.2 → runta_sdk-0.2.3}/src/runta/_internal/openapi/models/create_checkpoint_request_kind.py +0 -0
- {runta_sdk-0.2.2 → runta_sdk-0.2.3}/src/runta/_internal/openapi/models/create_cloud_agent_artifact_request.py +0 -0
- {runta_sdk-0.2.2 → runta_sdk-0.2.3}/src/runta/_internal/openapi/models/create_cloud_agent_request.py +0 -0
- {runta_sdk-0.2.2 → runta_sdk-0.2.3}/src/runta/_internal/openapi/models/create_cloud_agent_run_request.py +0 -0
- {runta_sdk-0.2.2 → runta_sdk-0.2.3}/src/runta/_internal/openapi/models/create_git_hub_authorization_request_request.py +0 -0
- {runta_sdk-0.2.2 → runta_sdk-0.2.3}/src/runta/_internal/openapi/models/create_git_hub_runtime_binding_request.py +0 -0
- {runta_sdk-0.2.2 → runta_sdk-0.2.3}/src/runta/_internal/openapi/models/create_llm_token_saving_policy.py +0 -0
- {runta_sdk-0.2.2 → runta_sdk-0.2.3}/src/runta/_internal/openapi/models/create_runtime_image_build_request.py +0 -0
- {runta_sdk-0.2.2 → runta_sdk-0.2.3}/src/runta/_internal/openapi/models/create_runtime_image_build_request_architecture.py +0 -0
- {runta_sdk-0.2.2 → runta_sdk-0.2.3}/src/runta/_internal/openapi/models/create_runtime_image_selection.py +0 -0
- {runta_sdk-0.2.2 → runta_sdk-0.2.3}/src/runta/_internal/openapi/models/create_runtime_resource_requests.py +0 -0
- {runta_sdk-0.2.2 → runta_sdk-0.2.3}/src/runta/_internal/openapi/models/create_runtime_resources.py +0 -0
- {runta_sdk-0.2.2 → runta_sdk-0.2.3}/src/runta/_internal/openapi/models/create_secret_request.py +0 -0
- {runta_sdk-0.2.2 → runta_sdk-0.2.3}/src/runta/_internal/openapi/models/create_ssh_key_request.py +0 -0
- {runta_sdk-0.2.2 → runta_sdk-0.2.3}/src/runta/_internal/openapi/models/create_vnc_credential_request.py +0 -0
- {runta_sdk-0.2.2 → runta_sdk-0.2.3}/src/runta/_internal/openapi/models/create_vnc_credential_response.py +0 -0
- {runta_sdk-0.2.2 → runta_sdk-0.2.3}/src/runta/_internal/openapi/models/denied_git_hub_authorization.py +0 -0
- {runta_sdk-0.2.2 → runta_sdk-0.2.3}/src/runta/_internal/openapi/models/denied_git_hub_authorization_status.py +0 -0
- {runta_sdk-0.2.2 → runta_sdk-0.2.3}/src/runta/_internal/openapi/models/denylist_egress_policy.py +0 -0
- {runta_sdk-0.2.2 → runta_sdk-0.2.3}/src/runta/_internal/openapi/models/denylist_egress_policy_mode.py +0 -0
- {runta_sdk-0.2.2 → runta_sdk-0.2.3}/src/runta/_internal/openapi/models/device_authorization_start.py +0 -0
- {runta_sdk-0.2.2 → runta_sdk-0.2.3}/src/runta/_internal/openapi/models/device_authorization_start_response.py +0 -0
- {runta_sdk-0.2.2 → runta_sdk-0.2.3}/src/runta/_internal/openapi/models/device_token_error.py +0 -0
- {runta_sdk-0.2.2 → runta_sdk-0.2.3}/src/runta/_internal/openapi/models/device_token_response.py +0 -0
- {runta_sdk-0.2.2 → runta_sdk-0.2.3}/src/runta/_internal/openapi/models/disabled_idle_policy.py +0 -0
- {runta_sdk-0.2.2 → runta_sdk-0.2.3}/src/runta/_internal/openapi/models/disabled_idle_policy_mode.py +0 -0
- {runta_sdk-0.2.2 → runta_sdk-0.2.3}/src/runta/_internal/openapi/models/empty_object.py +0 -0
- {runta_sdk-0.2.2 → runta_sdk-0.2.3}/src/runta/_internal/openapi/models/empty_response.py +0 -0
- {runta_sdk-0.2.2 → runta_sdk-0.2.3}/src/runta/_internal/openapi/models/error_body.py +0 -0
- {runta_sdk-0.2.2 → runta_sdk-0.2.3}/src/runta/_internal/openapi/models/error_envelope.py +0 -0
- {runta_sdk-0.2.2 → runta_sdk-0.2.3}/src/runta/_internal/openapi/models/event.py +0 -0
- {runta_sdk-0.2.2 → runta_sdk-0.2.3}/src/runta/_internal/openapi/models/event_list.py +0 -0
- {runta_sdk-0.2.2 → runta_sdk-0.2.3}/src/runta/_internal/openapi/models/event_list_response.py +0 -0
- {runta_sdk-0.2.2 → runta_sdk-0.2.3}/src/runta/_internal/openapi/models/event_response.py +0 -0
- {runta_sdk-0.2.2 → runta_sdk-0.2.3}/src/runta/_internal/openapi/models/exchange_device_token_request.py +0 -0
- {runta_sdk-0.2.2 → runta_sdk-0.2.3}/src/runta/_internal/openapi/models/expired_git_hub_authorization.py +0 -0
- {runta_sdk-0.2.2 → runta_sdk-0.2.3}/src/runta/_internal/openapi/models/expired_git_hub_authorization_status.py +0 -0
- {runta_sdk-0.2.2 → runta_sdk-0.2.3}/src/runta/_internal/openapi/models/fresh_runtime_create_request.py +0 -0
- {runta_sdk-0.2.2 → runta_sdk-0.2.3}/src/runta/_internal/openapi/models/fresh_runtime_create_request_environment_variables.py +0 -0
- {runta_sdk-0.2.2 → runta_sdk-0.2.3}/src/runta/_internal/openapi/models/git_hub_authorization_decision_metadata.py +0 -0
- {runta_sdk-0.2.2 → runta_sdk-0.2.3}/src/runta/_internal/openapi/models/git_hub_authorization_request.py +0 -0
- {runta_sdk-0.2.2 → runta_sdk-0.2.3}/src/runta/_internal/openapi/models/git_hub_authorization_request_list.py +0 -0
- {runta_sdk-0.2.2 → runta_sdk-0.2.3}/src/runta/_internal/openapi/models/git_hub_authorization_request_list_response.py +0 -0
- {runta_sdk-0.2.2 → runta_sdk-0.2.3}/src/runta/_internal/openapi/models/git_hub_authorization_request_response.py +0 -0
- {runta_sdk-0.2.2 → runta_sdk-0.2.3}/src/runta/_internal/openapi/models/git_hub_branch.py +0 -0
- {runta_sdk-0.2.2 → runta_sdk-0.2.3}/src/runta/_internal/openapi/models/git_hub_branch_list.py +0 -0
- {runta_sdk-0.2.2 → runta_sdk-0.2.3}/src/runta/_internal/openapi/models/git_hub_branch_list_response.py +0 -0
- {runta_sdk-0.2.2 → runta_sdk-0.2.3}/src/runta/_internal/openapi/models/git_hub_installation.py +0 -0
- {runta_sdk-0.2.2 → runta_sdk-0.2.3}/src/runta/_internal/openapi/models/git_hub_repository.py +0 -0
- {runta_sdk-0.2.2 → runta_sdk-0.2.3}/src/runta/_internal/openapi/models/git_hub_repository_list.py +0 -0
- {runta_sdk-0.2.2 → runta_sdk-0.2.3}/src/runta/_internal/openapi/models/git_hub_repository_list_response.py +0 -0
- {runta_sdk-0.2.2 → runta_sdk-0.2.3}/src/runta/_internal/openapi/models/git_hub_runtime_binding.py +0 -0
- {runta_sdk-0.2.2 → runta_sdk-0.2.3}/src/runta/_internal/openapi/models/git_hub_runtime_binding_list.py +0 -0
- {runta_sdk-0.2.2 → runta_sdk-0.2.3}/src/runta/_internal/openapi/models/git_hub_runtime_binding_list_response.py +0 -0
- {runta_sdk-0.2.2 → runta_sdk-0.2.3}/src/runta/_internal/openapi/models/git_hub_runtime_binding_response.py +0 -0
- {runta_sdk-0.2.2 → runta_sdk-0.2.3}/src/runta/_internal/openapi/models/installed_git_hub_authorization.py +0 -0
- {runta_sdk-0.2.2 → runta_sdk-0.2.3}/src/runta/_internal/openapi/models/installed_git_hub_authorization_status.py +0 -0
- {runta_sdk-0.2.2 → runta_sdk-0.2.3}/src/runta/_internal/openapi/models/list_checkpoints_response.py +0 -0
- {runta_sdk-0.2.2 → runta_sdk-0.2.3}/src/runta/_internal/openapi/models/list_runtime_image_builds_response.py +0 -0
- {runta_sdk-0.2.2 → runta_sdk-0.2.3}/src/runta/_internal/openapi/models/list_runtime_images_response.py +0 -0
- {runta_sdk-0.2.2 → runta_sdk-0.2.3}/src/runta/_internal/openapi/models/list_runtimes_response.py +0 -0
- {runta_sdk-0.2.2 → runta_sdk-0.2.3}/src/runta/_internal/openapi/models/list_secrets_response.py +0 -0
- {runta_sdk-0.2.2 → runta_sdk-0.2.3}/src/runta/_internal/openapi/models/list_ssh_keys_response.py +0 -0
- {runta_sdk-0.2.2 → runta_sdk-0.2.3}/src/runta/_internal/openapi/models/list_vnc_credentials_response.py +0 -0
- {runta_sdk-0.2.2 → runta_sdk-0.2.3}/src/runta/_internal/openapi/models/llm_token_saving_policy.py +0 -0
- {runta_sdk-0.2.2 → runta_sdk-0.2.3}/src/runta/_internal/openapi/models/managed_model_provider.py +0 -0
- {runta_sdk-0.2.2 → runta_sdk-0.2.3}/src/runta/_internal/openapi/models/managed_model_provider_list.py +0 -0
- {runta_sdk-0.2.2 → runta_sdk-0.2.3}/src/runta/_internal/openapi/models/managed_model_provider_reference.py +0 -0
- {runta_sdk-0.2.2 → runta_sdk-0.2.3}/src/runta/_internal/openapi/models/managed_model_provider_reference_type.py +0 -0
- {runta_sdk-0.2.2 → runta_sdk-0.2.3}/src/runta/_internal/openapi/models/patch_llm_token_saving_policy.py +0 -0
- {runta_sdk-0.2.2 → runta_sdk-0.2.3}/src/runta/_internal/openapi/models/patch_runtime_request.py +0 -0
- {runta_sdk-0.2.2 → runta_sdk-0.2.3}/src/runta/_internal/openapi/models/patch_runtime_request_environment_variables.py +0 -0
- {runta_sdk-0.2.2 → runta_sdk-0.2.3}/src/runta/_internal/openapi/models/patch_runtime_resource_requests.py +0 -0
- {runta_sdk-0.2.2 → runta_sdk-0.2.3}/src/runta/_internal/openapi/models/patch_runtime_resources.py +0 -0
- {runta_sdk-0.2.2 → runta_sdk-0.2.3}/src/runta/_internal/openapi/models/pending_git_hub_authorization.py +0 -0
- {runta_sdk-0.2.2 → runta_sdk-0.2.3}/src/runta/_internal/openapi/models/pending_git_hub_authorization_status.py +0 -0
- {runta_sdk-0.2.2 → runta_sdk-0.2.3}/src/runta/_internal/openapi/models/public_checkpoint_state.py +0 -0
- {runta_sdk-0.2.2 → runta_sdk-0.2.3}/src/runta/_internal/openapi/models/public_error_code.py +0 -0
- {runta_sdk-0.2.2 → runta_sdk-0.2.3}/src/runta/_internal/openapi/models/public_ingress_protocol.py +0 -0
- {runta_sdk-0.2.2 → runta_sdk-0.2.3}/src/runta/_internal/openapi/models/public_ingress_spec.py +0 -0
- {runta_sdk-0.2.2 → runta_sdk-0.2.3}/src/runta/_internal/openapi/models/public_runtime_status.py +0 -0
- {runta_sdk-0.2.2 → runta_sdk-0.2.3}/src/runta/_internal/openapi/models/replace_git_hub_runtime_bindings_request.py +0 -0
- {runta_sdk-0.2.2 → runta_sdk-0.2.3}/src/runta/_internal/openapi/models/replace_git_hub_runtime_bindings_request_repositories_item.py +0 -0
- {runta_sdk-0.2.2 → runta_sdk-0.2.3}/src/runta/_internal/openapi/models/runtime_desired_status.py +0 -0
- {runta_sdk-0.2.2 → runta_sdk-0.2.3}/src/runta/_internal/openapi/models/runtime_environment_variables.py +0 -0
- {runta_sdk-0.2.2 → runta_sdk-0.2.3}/src/runta/_internal/openapi/models/runtime_image.py +0 -0
- {runta_sdk-0.2.2 → runta_sdk-0.2.3}/src/runta/_internal/openapi/models/runtime_image_architectures_item.py +0 -0
- {runta_sdk-0.2.2 → runta_sdk-0.2.3}/src/runta/_internal/openapi/models/runtime_image_build.py +0 -0
- {runta_sdk-0.2.2 → runta_sdk-0.2.3}/src/runta/_internal/openapi/models/runtime_image_build_architecture.py +0 -0
- {runta_sdk-0.2.2 → runta_sdk-0.2.3}/src/runta/_internal/openapi/models/runtime_image_build_attempt.py +0 -0
- {runta_sdk-0.2.2 → runta_sdk-0.2.3}/src/runta/_internal/openapi/models/runtime_image_build_attempt_outcome.py +0 -0
- {runta_sdk-0.2.2 → runta_sdk-0.2.3}/src/runta/_internal/openapi/models/runtime_image_build_response.py +0 -0
- {runta_sdk-0.2.2 → runta_sdk-0.2.3}/src/runta/_internal/openapi/models/runtime_image_build_status.py +0 -0
- {runta_sdk-0.2.2 → runta_sdk-0.2.3}/src/runta/_internal/openapi/models/runtime_image_disk_capability.py +0 -0
- {runta_sdk-0.2.2 → runta_sdk-0.2.3}/src/runta/_internal/openapi/models/runtime_image_model_provider.py +0 -0
- {runta_sdk-0.2.2 → runta_sdk-0.2.3}/src/runta/_internal/openapi/models/runtime_image_protocol_binding.py +0 -0
- {runta_sdk-0.2.2 → runta_sdk-0.2.3}/src/runta/_internal/openapi/models/runtime_image_recommended_resources.py +0 -0
- {runta_sdk-0.2.2 → runta_sdk-0.2.3}/src/runta/_internal/openapi/models/runtime_image_subscription_option.py +0 -0
- {runta_sdk-0.2.2 → runta_sdk-0.2.3}/src/runta/_internal/openapi/models/runtime_image_web_ui.py +0 -0
- {runta_sdk-0.2.2 → runta_sdk-0.2.3}/src/runta/_internal/openapi/models/runtime_pagination.py +0 -0
- {runta_sdk-0.2.2 → runta_sdk-0.2.3}/src/runta/_internal/openapi/models/runtime_repository_selection.py +0 -0
- {runta_sdk-0.2.2 → runta_sdk-0.2.3}/src/runta/_internal/openapi/models/runtime_resource_current.py +0 -0
- {runta_sdk-0.2.2 → runta_sdk-0.2.3}/src/runta/_internal/openapi/models/runtime_resource_limits.py +0 -0
- {runta_sdk-0.2.2 → runta_sdk-0.2.3}/src/runta/_internal/openapi/models/runtime_resource_requests.py +0 -0
- {runta_sdk-0.2.2 → runta_sdk-0.2.3}/src/runta/_internal/openapi/models/runtime_resources.py +0 -0
- {runta_sdk-0.2.2 → runta_sdk-0.2.3}/src/runta/_internal/openapi/models/runtime_response.py +0 -0
- {runta_sdk-0.2.2 → runta_sdk-0.2.3}/src/runta/_internal/openapi/models/runtime_secret_configuration.py +0 -0
- {runta_sdk-0.2.2 → runta_sdk-0.2.3}/src/runta/_internal/openapi/models/runtime_workspace_file_entry.py +0 -0
- {runta_sdk-0.2.2 → runta_sdk-0.2.3}/src/runta/_internal/openapi/models/runtime_workspace_file_kind.py +0 -0
- {runta_sdk-0.2.2 → runta_sdk-0.2.3}/src/runta/_internal/openapi/models/runtime_workspace_operation_kind.py +0 -0
- {runta_sdk-0.2.2 → runta_sdk-0.2.3}/src/runta/_internal/openapi/models/runtime_workspace_operation_request.py +0 -0
- {runta_sdk-0.2.2 → runta_sdk-0.2.3}/src/runta/_internal/openapi/models/runtime_workspace_operation_result.py +0 -0
- {runta_sdk-0.2.2 → runta_sdk-0.2.3}/src/runta/_internal/openapi/models/runtime_workspace_port.py +0 -0
- {runta_sdk-0.2.2 → runta_sdk-0.2.3}/src/runta/_internal/openapi/models/runtime_workspace_search_match.py +0 -0
- {runta_sdk-0.2.2 → runta_sdk-0.2.3}/src/runta/_internal/openapi/models/secret.py +0 -0
- {runta_sdk-0.2.2 → runta_sdk-0.2.3}/src/runta/_internal/openapi/models/secret_egress_injection.py +0 -0
- {runta_sdk-0.2.2 → runta_sdk-0.2.3}/src/runta/_internal/openapi/models/secret_environment_injection.py +0 -0
- {runta_sdk-0.2.2 → runta_sdk-0.2.3}/src/runta/_internal/openapi/models/secret_file_injection.py +0 -0
- {runta_sdk-0.2.2 → runta_sdk-0.2.3}/src/runta/_internal/openapi/models/secret_injection_action.py +0 -0
- {runta_sdk-0.2.2 → runta_sdk-0.2.3}/src/runta/_internal/openapi/models/secret_response.py +0 -0
- {runta_sdk-0.2.2 → runta_sdk-0.2.3}/src/runta/_internal/openapi/models/set_secret_request.py +0 -0
- {runta_sdk-0.2.2 → runta_sdk-0.2.3}/src/runta/_internal/openapi/models/ssh_host_key.py +0 -0
- {runta_sdk-0.2.2 → runta_sdk-0.2.3}/src/runta/_internal/openapi/models/ssh_host_key_response.py +0 -0
- {runta_sdk-0.2.2 → runta_sdk-0.2.3}/src/runta/_internal/openapi/models/ssh_key.py +0 -0
- {runta_sdk-0.2.2 → runta_sdk-0.2.3}/src/runta/_internal/openapi/models/ssh_key_response.py +0 -0
- {runta_sdk-0.2.2 → runta_sdk-0.2.3}/src/runta/_internal/openapi/models/suspend_and_wakeup_idle_policy.py +0 -0
- {runta_sdk-0.2.2 → runta_sdk-0.2.3}/src/runta/_internal/openapi/models/suspend_and_wakeup_idle_policy_mode.py +0 -0
- {runta_sdk-0.2.2 → runta_sdk-0.2.3}/src/runta/_internal/openapi/models/suspend_only_idle_policy.py +0 -0
- {runta_sdk-0.2.2 → runta_sdk-0.2.3}/src/runta/_internal/openapi/models/suspend_only_idle_policy_mode.py +0 -0
- {runta_sdk-0.2.2 → runta_sdk-0.2.3}/src/runta/_internal/openapi/models/token_analysis_detail.py +0 -0
- {runta_sdk-0.2.2 → runta_sdk-0.2.3}/src/runta/_internal/openapi/models/token_analysis_detail_response.py +0 -0
- {runta_sdk-0.2.2 → runta_sdk-0.2.3}/src/runta/_internal/openapi/models/token_analysis_finding.py +0 -0
- {runta_sdk-0.2.2 → runta_sdk-0.2.3}/src/runta/_internal/openapi/models/token_analysis_finding_confidence.py +0 -0
- {runta_sdk-0.2.2 → runta_sdk-0.2.3}/src/runta/_internal/openapi/models/token_analysis_finding_kind.py +0 -0
- {runta_sdk-0.2.2 → runta_sdk-0.2.3}/src/runta/_internal/openapi/models/token_analysis_finding_severity.py +0 -0
- {runta_sdk-0.2.2 → runta_sdk-0.2.3}/src/runta/_internal/openapi/models/token_analysis_issue.py +0 -0
- {runta_sdk-0.2.2 → runta_sdk-0.2.3}/src/runta/_internal/openapi/models/token_analysis_issue_confidence.py +0 -0
- {runta_sdk-0.2.2 → runta_sdk-0.2.3}/src/runta/_internal/openapi/models/token_analysis_issue_kind.py +0 -0
- {runta_sdk-0.2.2 → runta_sdk-0.2.3}/src/runta/_internal/openapi/models/token_analysis_issue_severity.py +0 -0
- {runta_sdk-0.2.2 → runta_sdk-0.2.3}/src/runta/_internal/openapi/models/token_analysis_list.py +0 -0
- {runta_sdk-0.2.2 → runta_sdk-0.2.3}/src/runta/_internal/openapi/models/token_analysis_list_response.py +0 -0
- {runta_sdk-0.2.2 → runta_sdk-0.2.3}/src/runta/_internal/openapi/models/token_analysis_summary.py +0 -0
- {runta_sdk-0.2.2 → runta_sdk-0.2.3}/src/runta/_internal/openapi/models/token_analysis_tool_call.py +0 -0
- {runta_sdk-0.2.2 → runta_sdk-0.2.3}/src/runta/_internal/openapi/models/token_saving_event.py +0 -0
- {runta_sdk-0.2.2 → runta_sdk-0.2.3}/src/runta/_internal/openapi/models/token_saving_method.py +0 -0
- {runta_sdk-0.2.2 → runta_sdk-0.2.3}/src/runta/_internal/openapi/models/token_saving_method_method.py +0 -0
- {runta_sdk-0.2.2 → runta_sdk-0.2.3}/src/runta/_internal/openapi/models/token_savings_list.py +0 -0
- {runta_sdk-0.2.2 → runta_sdk-0.2.3}/src/runta/_internal/openapi/models/token_savings_list_response.py +0 -0
- {runta_sdk-0.2.2 → runta_sdk-0.2.3}/src/runta/_internal/openapi/models/token_savings_summary.py +0 -0
- {runta_sdk-0.2.2 → runta_sdk-0.2.3}/src/runta/_internal/openapi/models/update_cloud_agent_request.py +0 -0
- {runta_sdk-0.2.2 → runta_sdk-0.2.3}/src/runta/_internal/openapi/models/update_managed_model_provider_request.py +0 -0
- {runta_sdk-0.2.2 → runta_sdk-0.2.3}/src/runta/_internal/openapi/models/user_profile.py +0 -0
- {runta_sdk-0.2.2 → runta_sdk-0.2.3}/src/runta/_internal/openapi/models/user_profile_response.py +0 -0
- {runta_sdk-0.2.2 → runta_sdk-0.2.3}/src/runta/_internal/openapi/models/vnc_credential.py +0 -0
- {runta_sdk-0.2.2 → runta_sdk-0.2.3}/src/runta/_internal/openapi/models/vnc_credential_connection.py +0 -0
- {runta_sdk-0.2.2 → runta_sdk-0.2.3}/src/runta/_internal/openapi/models/vnc_credential_connection_security_type.py +0 -0
- {runta_sdk-0.2.2 → runta_sdk-0.2.3}/src/runta/_internal/openapi/models/vnc_credential_response.py +0 -0
- {runta_sdk-0.2.2 → runta_sdk-0.2.3}/src/runta/_internal/openapi/models/vnc_gateway_connection.py +0 -0
- {runta_sdk-0.2.2 → runta_sdk-0.2.3}/src/runta/_internal/openapi/models/vnc_gateway_connection_security_type.py +0 -0
- {runta_sdk-0.2.2 → runta_sdk-0.2.3}/src/runta/_internal/openapi/models/vnc_gateway_connection_username.py +0 -0
- {runta_sdk-0.2.2 → runta_sdk-0.2.3}/src/runta/_internal/openapi/types.py +0 -0
- {runta_sdk-0.2.2 → runta_sdk-0.2.3}/src/runta/_internal/pagination.py +0 -0
- {runta_sdk-0.2.2 → runta_sdk-0.2.3}/src/runta/_internal/rest_tls.py +0 -0
- {runta_sdk-0.2.2 → runta_sdk-0.2.3}/src/runta/_internal/retry.py +0 -0
- {runta_sdk-0.2.2 → runta_sdk-0.2.3}/src/runta/_internal/tls_resumption.py +0 -0
- {runta_sdk-0.2.2 → runta_sdk-0.2.3}/src/runta/_internal/transport.py +0 -0
- {runta_sdk-0.2.2 → runta_sdk-0.2.3}/src/runta/_internal/user_agent.py +0 -0
- {runta_sdk-0.2.2 → runta_sdk-0.2.3}/src/runta/py.typed +0 -0
- {runta_sdk-0.2.2 → runta_sdk-0.2.3}/tests/test_api_reference_generation.py +0 -0
- {runta_sdk-0.2.2 → runta_sdk-0.2.3}/tests/test_async_file_io.py +0 -0
- {runta_sdk-0.2.2 → runta_sdk-0.2.3}/tests/test_async_http_transport.py +0 -0
- {runta_sdk-0.2.2 → runta_sdk-0.2.3}/tests/test_checkpoint_metadata.py +0 -0
- {runta_sdk-0.2.2 → runta_sdk-0.2.3}/tests/test_config_and_helpers.py +0 -0
- {runta_sdk-0.2.2 → runta_sdk-0.2.3}/tests/test_connection_pool.py +0 -0
- {runta_sdk-0.2.2 → runta_sdk-0.2.3}/tests/test_delete_runtime_retry.py +0 -0
- {runta_sdk-0.2.2 → runta_sdk-0.2.3}/tests/test_directory_upload.py +0 -0
- {runta_sdk-0.2.2 → runta_sdk-0.2.3}/tests/test_directory_upload_concurrency.py +0 -0
- {runta_sdk-0.2.2 → runta_sdk-0.2.3}/tests/test_execution.py +0 -0
- {runta_sdk-0.2.2 → runta_sdk-0.2.3}/tests/test_execution_result_stream.py +0 -0
- {runta_sdk-0.2.2 → runta_sdk-0.2.3}/tests/test_fetch_openapi.py +0 -0
- {runta_sdk-0.2.2 → runta_sdk-0.2.3}/tests/test_get_runtime_retry.py +0 -0
- {runta_sdk-0.2.2 → runta_sdk-0.2.3}/tests/test_harbor_e2e.py +0 -0
- {runta_sdk-0.2.2 → runta_sdk-0.2.3}/tests/test_harbor_integration.py +0 -0
- {runta_sdk-0.2.2 → runta_sdk-0.2.3}/tests/test_harbor_runta_environment.py +0 -0
- {runta_sdk-0.2.2 → runta_sdk-0.2.3}/tests/test_live.py +0 -0
- {runta_sdk-0.2.2 → runta_sdk-0.2.3}/tests/test_openai_extra_packaging.py +0 -0
- {runta_sdk-0.2.2 → runta_sdk-0.2.3}/tests/test_openapi_contract.py +0 -0
- {runta_sdk-0.2.2 → runta_sdk-0.2.3}/tests/test_openapi_transport.py +0 -0
- {runta_sdk-0.2.2 → runta_sdk-0.2.3}/tests/test_read_retries.py +0 -0
- {runta_sdk-0.2.2 → runta_sdk-0.2.3}/tests/test_rest_deployment.py +0 -0
- {runta_sdk-0.2.2 → runta_sdk-0.2.3}/tests/test_rest_tls.py +0 -0
- {runta_sdk-0.2.2 → runta_sdk-0.2.3}/tests/test_retry_policy.py +0 -0
- {runta_sdk-0.2.2 → runta_sdk-0.2.3}/tests/test_runtime_readiness.py +0 -0
- {runta_sdk-0.2.2 → runta_sdk-0.2.3}/tests/test_streaming_transfer.py +0 -0
- {runta_sdk-0.2.2 → runta_sdk-0.2.3}/tests/test_user_agent.py +0 -0
- {runta_sdk-0.2.2 → runta_sdk-0.2.3}/tests/test_websocket_tls.py +0 -0
- {runta_sdk-0.2.2 → runta_sdk-0.2.3}/tests/test_websocket_tls_resumption.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: runta-sdk
|
|
3
|
-
Version: 0.2.
|
|
3
|
+
Version: 0.2.3
|
|
4
4
|
Summary: Python SDK for Runta runtime management
|
|
5
5
|
Author: Runta
|
|
6
6
|
License-Expression: MIT
|
|
@@ -134,6 +134,35 @@ runtime.files.upload("./project", "/workspace/project")
|
|
|
134
134
|
runtime.files.download("/workspace/dist", "./artifacts/")
|
|
135
135
|
```
|
|
136
136
|
|
|
137
|
+
To merge a directory's **contents** into an existing local directory, use:
|
|
138
|
+
|
|
139
|
+
```python
|
|
140
|
+
runtime.files.download_dir_contents("/workspace/dist", "./artifacts")
|
|
141
|
+
# AsyncRuntime exposes the same method:
|
|
142
|
+
await runtime.files.download_dir_contents("/workspace/dist", "./artifacts")
|
|
143
|
+
```
|
|
144
|
+
|
|
145
|
+
This creates the destination if needed, overwrites matching files, and preserves
|
|
146
|
+
unrelated files without appending `dist`. The source must be a directory (a
|
|
147
|
+
source directory symlink is followed). File/directory conflicts raise an error;
|
|
148
|
+
existing directories are never recursively removed. Empty sources preserve the
|
|
149
|
+
existing destination and its root metadata. The merge is **not transactional**:
|
|
150
|
+
failure or cancellation may leave partially merged files. Existing `download()`
|
|
151
|
+
path and replacement behavior is unchanged.
|
|
152
|
+
|
|
153
|
+
The new method reads the downloaded seekable archive directly, without a second
|
|
154
|
+
archive or a complete staging copy. It always applies safe tar data filtering,
|
|
155
|
+
including to members returned by an optional synchronous
|
|
156
|
+
`filter(member, destination)` callback. Return `None` to skip a member, for
|
|
157
|
+
example to ignore FIFOs and device nodes; by default these are rejected.
|
|
158
|
+
Permissions follow `tarfile.data_filter` (including removal of unsafe mode bits
|
|
159
|
+
and ownership). Safe links are preserved where supported; the standard library
|
|
160
|
+
copies archive referents when link creation is unavailable. Unresolvable dangling
|
|
161
|
+
symlinks are skipped on platforms that cannot create them. Use a current Python
|
|
162
|
+
security patch release with safe tar link fallback; missing safety support raises
|
|
163
|
+
an error rather than extracting unsafely. As with standard tar extraction, do not
|
|
164
|
+
allow another process to modify the destination concurrently during extraction.
|
|
165
|
+
|
|
137
166
|
Runtime, Checkpoint, and Secret queries, file reads, Runtime creation and deletion,
|
|
138
167
|
resource and egress updates, and streaming transfers retry transient failures
|
|
139
168
|
with exponential backoff and full jitter. The default is 16 total attempts,
|
|
@@ -106,6 +106,35 @@ runtime.files.upload("./project", "/workspace/project")
|
|
|
106
106
|
runtime.files.download("/workspace/dist", "./artifacts/")
|
|
107
107
|
```
|
|
108
108
|
|
|
109
|
+
To merge a directory's **contents** into an existing local directory, use:
|
|
110
|
+
|
|
111
|
+
```python
|
|
112
|
+
runtime.files.download_dir_contents("/workspace/dist", "./artifacts")
|
|
113
|
+
# AsyncRuntime exposes the same method:
|
|
114
|
+
await runtime.files.download_dir_contents("/workspace/dist", "./artifacts")
|
|
115
|
+
```
|
|
116
|
+
|
|
117
|
+
This creates the destination if needed, overwrites matching files, and preserves
|
|
118
|
+
unrelated files without appending `dist`. The source must be a directory (a
|
|
119
|
+
source directory symlink is followed). File/directory conflicts raise an error;
|
|
120
|
+
existing directories are never recursively removed. Empty sources preserve the
|
|
121
|
+
existing destination and its root metadata. The merge is **not transactional**:
|
|
122
|
+
failure or cancellation may leave partially merged files. Existing `download()`
|
|
123
|
+
path and replacement behavior is unchanged.
|
|
124
|
+
|
|
125
|
+
The new method reads the downloaded seekable archive directly, without a second
|
|
126
|
+
archive or a complete staging copy. It always applies safe tar data filtering,
|
|
127
|
+
including to members returned by an optional synchronous
|
|
128
|
+
`filter(member, destination)` callback. Return `None` to skip a member, for
|
|
129
|
+
example to ignore FIFOs and device nodes; by default these are rejected.
|
|
130
|
+
Permissions follow `tarfile.data_filter` (including removal of unsafe mode bits
|
|
131
|
+
and ownership). Safe links are preserved where supported; the standard library
|
|
132
|
+
copies archive referents when link creation is unavailable. Unresolvable dangling
|
|
133
|
+
symlinks are skipped on platforms that cannot create them. Use a current Python
|
|
134
|
+
security patch release with safe tar link fallback; missing safety support raises
|
|
135
|
+
an error rather than extracting unsafely. As with standard tar extraction, do not
|
|
136
|
+
allow another process to modify the destination concurrently during extraction.
|
|
137
|
+
|
|
109
138
|
Runtime, Checkpoint, and Secret queries, file reads, Runtime creation and deletion,
|
|
110
139
|
resource and egress updates, and streaming transfers retry transient failures
|
|
111
140
|
with exponential backoff and full jitter. The default is 16 total attempts,
|
|
@@ -6,7 +6,6 @@ import json
|
|
|
6
6
|
import os
|
|
7
7
|
import shlex
|
|
8
8
|
import tarfile
|
|
9
|
-
import tempfile
|
|
10
9
|
import time
|
|
11
10
|
import uuid
|
|
12
11
|
from abc import ABC, abstractmethod
|
|
@@ -51,6 +50,15 @@ _RUNTA_CONTAINER_CA_ENV = {
|
|
|
51
50
|
}
|
|
52
51
|
|
|
53
52
|
|
|
53
|
+
def transfer_tar_filter(
|
|
54
|
+
member: tarfile.TarInfo, destination: str
|
|
55
|
+
) -> tarfile.TarInfo | None:
|
|
56
|
+
"""Skip empty special nodes; supported Harbor releases may not export this."""
|
|
57
|
+
if member.isdev():
|
|
58
|
+
return None
|
|
59
|
+
return tarfile.data_filter(member, destination)
|
|
60
|
+
|
|
61
|
+
|
|
54
62
|
def _with_runta_container_ca_env(
|
|
55
63
|
env: dict[str, str] | None,
|
|
56
64
|
) -> dict[str, str]:
|
|
@@ -936,27 +944,11 @@ class RuntaEnvironment(BaseEnvironment):
|
|
|
936
944
|
async def _runtime_download_dir(
|
|
937
945
|
self, source_dir: str, target_dir: Path | str
|
|
938
946
|
) -> None:
|
|
939
|
-
|
|
940
|
-
|
|
941
|
-
|
|
942
|
-
|
|
947
|
+
await self._require_runtime().files.download_dir_contents(
|
|
948
|
+
source_dir,
|
|
949
|
+
str(target_dir),
|
|
950
|
+
filter=transfer_tar_filter,
|
|
943
951
|
)
|
|
944
|
-
self._check(result, "resolve download source directory")
|
|
945
|
-
source_dir = result.stdout.removesuffix("\n")
|
|
946
|
-
target = Path(target_dir)
|
|
947
|
-
target.mkdir(parents=True, exist_ok=True)
|
|
948
|
-
with tempfile.TemporaryDirectory() as tmp_dir:
|
|
949
|
-
source = Path(tmp_dir) / "contents"
|
|
950
|
-
await self._require_runtime().files.download(source_dir, str(source))
|
|
951
|
-
# Harbor downloads contents into an existing directory, whereas the
|
|
952
|
-
# SDK downloads the source directory itself to a staged destination.
|
|
953
|
-
# Retain Harbor's safe content merge, including existing destination
|
|
954
|
-
# symlink checks. This merge archive stays local.
|
|
955
|
-
archive_path = Path(tmp_dir) / "merge.tar"
|
|
956
|
-
with tarfile.open(archive_path, "w") as archive:
|
|
957
|
-
archive.add(source, arcname=".")
|
|
958
|
-
with tarfile.open(archive_path, "r") as archive:
|
|
959
|
-
archive.extractall(target, filter="data")
|
|
960
952
|
|
|
961
953
|
async def _runtime_ensure_dirs(self, dirs: list[str]) -> None:
|
|
962
954
|
if not dirs:
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: runta-sdk
|
|
3
|
-
Version: 0.2.
|
|
3
|
+
Version: 0.2.3
|
|
4
4
|
Summary: Python SDK for Runta runtime management
|
|
5
5
|
Author: Runta
|
|
6
6
|
License-Expression: MIT
|
|
@@ -134,6 +134,35 @@ runtime.files.upload("./project", "/workspace/project")
|
|
|
134
134
|
runtime.files.download("/workspace/dist", "./artifacts/")
|
|
135
135
|
```
|
|
136
136
|
|
|
137
|
+
To merge a directory's **contents** into an existing local directory, use:
|
|
138
|
+
|
|
139
|
+
```python
|
|
140
|
+
runtime.files.download_dir_contents("/workspace/dist", "./artifacts")
|
|
141
|
+
# AsyncRuntime exposes the same method:
|
|
142
|
+
await runtime.files.download_dir_contents("/workspace/dist", "./artifacts")
|
|
143
|
+
```
|
|
144
|
+
|
|
145
|
+
This creates the destination if needed, overwrites matching files, and preserves
|
|
146
|
+
unrelated files without appending `dist`. The source must be a directory (a
|
|
147
|
+
source directory symlink is followed). File/directory conflicts raise an error;
|
|
148
|
+
existing directories are never recursively removed. Empty sources preserve the
|
|
149
|
+
existing destination and its root metadata. The merge is **not transactional**:
|
|
150
|
+
failure or cancellation may leave partially merged files. Existing `download()`
|
|
151
|
+
path and replacement behavior is unchanged.
|
|
152
|
+
|
|
153
|
+
The new method reads the downloaded seekable archive directly, without a second
|
|
154
|
+
archive or a complete staging copy. It always applies safe tar data filtering,
|
|
155
|
+
including to members returned by an optional synchronous
|
|
156
|
+
`filter(member, destination)` callback. Return `None` to skip a member, for
|
|
157
|
+
example to ignore FIFOs and device nodes; by default these are rejected.
|
|
158
|
+
Permissions follow `tarfile.data_filter` (including removal of unsafe mode bits
|
|
159
|
+
and ownership). Safe links are preserved where supported; the standard library
|
|
160
|
+
copies archive referents when link creation is unavailable. Unresolvable dangling
|
|
161
|
+
symlinks are skipped on platforms that cannot create them. Use a current Python
|
|
162
|
+
security patch release with safe tar link fallback; missing safety support raises
|
|
163
|
+
an error rather than extracting unsafely. As with standard tar extraction, do not
|
|
164
|
+
allow another process to modify the destination concurrently during extraction.
|
|
165
|
+
|
|
137
166
|
Runtime, Checkpoint, and Secret queries, file reads, Runtime creation and deletion,
|
|
138
167
|
resource and egress updates, and streaming transfers retry transient failures
|
|
139
168
|
with exponential backoff and full jitter. The default is 16 total attempts,
|
|
@@ -336,6 +336,8 @@ tests/test_connection_pool.py
|
|
|
336
336
|
tests/test_delete_runtime_retry.py
|
|
337
337
|
tests/test_directory_upload.py
|
|
338
338
|
tests/test_directory_upload_concurrency.py
|
|
339
|
+
tests/test_download_dir_contents.py
|
|
340
|
+
tests/test_download_dir_contents_live.py
|
|
339
341
|
tests/test_execution.py
|
|
340
342
|
tests/test_execution_result_stream.py
|
|
341
343
|
tests/test_fetch_openapi.py
|
|
@@ -4,8 +4,9 @@ from __future__ import annotations
|
|
|
4
4
|
|
|
5
5
|
import asyncio
|
|
6
6
|
import time
|
|
7
|
+
import tarfile
|
|
7
8
|
import uuid
|
|
8
|
-
from collections.abc import Mapping, Sequence
|
|
9
|
+
from collections.abc import Callable, Mapping, Sequence
|
|
9
10
|
from concurrent.futures import Future, ThreadPoolExecutor
|
|
10
11
|
from dataclasses import dataclass, field
|
|
11
12
|
from enum import Enum
|
|
@@ -1588,6 +1589,41 @@ class FileManager(_SdkOwnedHandle):
|
|
|
1588
1589
|
destination_is_directory=destination_is_directory,
|
|
1589
1590
|
)
|
|
1590
1591
|
|
|
1592
|
+
def download_dir_contents(
|
|
1593
|
+
self,
|
|
1594
|
+
src: str,
|
|
1595
|
+
dst: str,
|
|
1596
|
+
*,
|
|
1597
|
+
filter: Callable[[tarfile.TarInfo, str], tarfile.TarInfo | None] | None = None,
|
|
1598
|
+
) -> None:
|
|
1599
|
+
"""Merge a runtime directory's contents into a local directory.
|
|
1600
|
+
|
|
1601
|
+
Existing unrelated files are preserved and matching files overwritten.
|
|
1602
|
+
Source directory links are followed; nested links are preserved when
|
|
1603
|
+
supported. Safe data filtering is always enforced, including after a
|
|
1604
|
+
custom tarfile-style filter. Special files are rejected unless skipped
|
|
1605
|
+
by that callback. Permissions follow tarfile.data_filter semantics.
|
|
1606
|
+
|
|
1607
|
+
This operation is not transactional: failures or cancellation can leave
|
|
1608
|
+
partially merged contents. A file/directory type conflict raises instead
|
|
1609
|
+
of deleting a directory. An empty source preserves existing contents.
|
|
1610
|
+
|
|
1611
|
+
Args:
|
|
1612
|
+
src: Source directory inside the runtime.
|
|
1613
|
+
dst: Local directory, created if absent; no source name is appended.
|
|
1614
|
+
filter: Optional synchronous (TarInfo, destination) callback. Return
|
|
1615
|
+
None to skip a member. Async callbacks are not supported.
|
|
1616
|
+
|
|
1617
|
+
Examples:
|
|
1618
|
+
>>> runtime.files.download_dir_contents("/workspace/dist", "./artifacts")
|
|
1619
|
+
"""
|
|
1620
|
+
self._runtime._client._http.download_dir_contents(
|
|
1621
|
+
self._runtime.id,
|
|
1622
|
+
src,
|
|
1623
|
+
Path(dst),
|
|
1624
|
+
filter=filter,
|
|
1625
|
+
)
|
|
1626
|
+
|
|
1591
1627
|
|
|
1592
1628
|
class AsyncFileManager(_SdkOwnedHandle):
|
|
1593
1629
|
"""Reads, writes, uploads, and downloads runtime files asynchronously."""
|
|
@@ -1662,6 +1698,41 @@ class AsyncFileManager(_SdkOwnedHandle):
|
|
|
1662
1698
|
destination_is_directory=destination_is_directory,
|
|
1663
1699
|
)
|
|
1664
1700
|
|
|
1701
|
+
async def download_dir_contents(
|
|
1702
|
+
self,
|
|
1703
|
+
src: str,
|
|
1704
|
+
dst: str,
|
|
1705
|
+
*,
|
|
1706
|
+
filter: Callable[[tarfile.TarInfo, str], tarfile.TarInfo | None] | None = None,
|
|
1707
|
+
) -> None:
|
|
1708
|
+
"""Merge a runtime directory's contents into a local directory.
|
|
1709
|
+
|
|
1710
|
+
Existing unrelated files are preserved and matching files overwritten.
|
|
1711
|
+
Source directory links are followed; nested links are preserved when
|
|
1712
|
+
supported. Safe data filtering is always enforced, including after a
|
|
1713
|
+
custom tarfile-style filter. Special files are rejected unless skipped
|
|
1714
|
+
by that callback. Permissions follow tarfile.data_filter semantics.
|
|
1715
|
+
|
|
1716
|
+
This operation is not transactional: failures or cancellation can leave
|
|
1717
|
+
partially merged contents. A file/directory type conflict raises instead
|
|
1718
|
+
of deleting a directory. An empty source preserves existing contents.
|
|
1719
|
+
|
|
1720
|
+
Args:
|
|
1721
|
+
src: Source directory inside the runtime.
|
|
1722
|
+
dst: Local directory, created if absent; no source name is appended.
|
|
1723
|
+
filter: Optional synchronous (TarInfo, destination) callback. Return
|
|
1724
|
+
None to skip a member. Async callbacks are not supported.
|
|
1725
|
+
|
|
1726
|
+
Examples:
|
|
1727
|
+
>>> await runtime.files.download_dir_contents("/workspace/dist", "./artifacts")
|
|
1728
|
+
"""
|
|
1729
|
+
await self._runtime._client._http.download_dir_contents(
|
|
1730
|
+
self._runtime.id,
|
|
1731
|
+
src,
|
|
1732
|
+
Path(dst),
|
|
1733
|
+
filter=filter,
|
|
1734
|
+
)
|
|
1735
|
+
|
|
1665
1736
|
|
|
1666
1737
|
class RuntimeCheckpointManager(_SdkOwnedHandle):
|
|
1667
1738
|
"""Creates, lists, and deletes checkpoints for a runtime."""
|
|
@@ -5,6 +5,7 @@ from __future__ import annotations
|
|
|
5
5
|
from collections.abc import Awaitable, Mapping, Sequence
|
|
6
6
|
from pathlib import Path
|
|
7
7
|
import time
|
|
8
|
+
import tarfile
|
|
8
9
|
from typing import Any, Callable
|
|
9
10
|
from uuid import uuid4
|
|
10
11
|
|
|
@@ -517,6 +518,29 @@ class _AsyncHttpClient:
|
|
|
517
518
|
_file_io=self._file_io,
|
|
518
519
|
)
|
|
519
520
|
|
|
521
|
+
async def download_dir_contents(
|
|
522
|
+
self,
|
|
523
|
+
runtime_id: str,
|
|
524
|
+
src: str,
|
|
525
|
+
dst: Path,
|
|
526
|
+
*,
|
|
527
|
+
filter: Callable[[tarfile.TarInfo, str], tarfile.TarInfo | None] | None = None,
|
|
528
|
+
) -> None:
|
|
529
|
+
from .streaming_transfer import async_download_dir_contents
|
|
530
|
+
|
|
531
|
+
await async_download_dir_contents(
|
|
532
|
+
self.endpoint,
|
|
533
|
+
self.token,
|
|
534
|
+
runtime_id,
|
|
535
|
+
src,
|
|
536
|
+
dst,
|
|
537
|
+
filter=filter,
|
|
538
|
+
timeout=self.timeout,
|
|
539
|
+
attempts=self.retry_max_attempts,
|
|
540
|
+
_tls=self._websocket_tls,
|
|
541
|
+
_file_io=self._file_io,
|
|
542
|
+
)
|
|
543
|
+
|
|
520
544
|
async def update_runtime_status(
|
|
521
545
|
self, runtime_id: str, action: str
|
|
522
546
|
) -> _public.RuntimeInfo:
|
|
@@ -63,6 +63,8 @@ class Runtime:
|
|
|
63
63
|
destination, bypassing secret injection, LLM capture, token saving, and model routing.
|
|
64
64
|
vnc_error_code (None | str | Unset): Bounded machine-readable VNC startup failure code.
|
|
65
65
|
error_code (None | str | Unset): Bounded machine-readable provisioning failure code.
|
|
66
|
+
error_message (None | str | Unset): Current runtime failure reason, bounded to 4096 UTF-8 bytes. Cleared when
|
|
67
|
+
the failure recovers.
|
|
66
68
|
"""
|
|
67
69
|
|
|
68
70
|
display_name: str
|
|
@@ -92,6 +94,7 @@ class Runtime:
|
|
|
92
94
|
tls_passthrough_hosts: list[str] | Unset = UNSET
|
|
93
95
|
vnc_error_code: None | str | Unset = UNSET
|
|
94
96
|
error_code: None | str | Unset = UNSET
|
|
97
|
+
error_message: None | str | Unset = UNSET
|
|
95
98
|
additional_properties: dict[str, Any] = _attrs_field(init=False, factory=dict)
|
|
96
99
|
|
|
97
100
|
def to_dict(self) -> dict[str, Any]:
|
|
@@ -181,6 +184,12 @@ class Runtime:
|
|
|
181
184
|
else:
|
|
182
185
|
error_code = self.error_code
|
|
183
186
|
|
|
187
|
+
error_message: None | str | Unset
|
|
188
|
+
if isinstance(self.error_message, Unset):
|
|
189
|
+
error_message = UNSET
|
|
190
|
+
else:
|
|
191
|
+
error_message = self.error_message
|
|
192
|
+
|
|
184
193
|
field_dict: dict[str, Any] = {}
|
|
185
194
|
field_dict.update(self.additional_properties)
|
|
186
195
|
field_dict.update(
|
|
@@ -218,6 +227,8 @@ class Runtime:
|
|
|
218
227
|
field_dict["vnc_error_code"] = vnc_error_code
|
|
219
228
|
if error_code is not UNSET:
|
|
220
229
|
field_dict["error_code"] = error_code
|
|
230
|
+
if error_message is not UNSET:
|
|
231
|
+
field_dict["error_message"] = error_message
|
|
221
232
|
|
|
222
233
|
return field_dict
|
|
223
234
|
|
|
@@ -379,6 +390,15 @@ class Runtime:
|
|
|
379
390
|
|
|
380
391
|
error_code = _parse_error_code(d.pop("error_code", UNSET))
|
|
381
392
|
|
|
393
|
+
def _parse_error_message(data: object) -> None | str | Unset:
|
|
394
|
+
if data is None:
|
|
395
|
+
return data
|
|
396
|
+
if isinstance(data, Unset):
|
|
397
|
+
return data
|
|
398
|
+
return cast(None | str | Unset, data)
|
|
399
|
+
|
|
400
|
+
error_message = _parse_error_message(d.pop("error_message", UNSET))
|
|
401
|
+
|
|
382
402
|
runtime = cls(
|
|
383
403
|
display_name=display_name,
|
|
384
404
|
egress_policy=egress_policy,
|
|
@@ -407,6 +427,7 @@ class Runtime:
|
|
|
407
427
|
tls_passthrough_hosts=tls_passthrough_hosts,
|
|
408
428
|
vnc_error_code=vnc_error_code,
|
|
409
429
|
error_code=error_code,
|
|
430
|
+
error_message=error_message,
|
|
410
431
|
)
|
|
411
432
|
|
|
412
433
|
runtime.additional_properties = d
|
|
@@ -4,6 +4,7 @@ from __future__ import annotations
|
|
|
4
4
|
|
|
5
5
|
import asyncio
|
|
6
6
|
import base64
|
|
7
|
+
import copy
|
|
7
8
|
import errno
|
|
8
9
|
from contextlib import asynccontextmanager, contextmanager
|
|
9
10
|
import json
|
|
@@ -17,7 +18,7 @@ import tempfile
|
|
|
17
18
|
import threading
|
|
18
19
|
import time
|
|
19
20
|
from collections.abc import Callable
|
|
20
|
-
from pathlib import Path
|
|
21
|
+
from pathlib import Path, PurePosixPath, PureWindowsPath
|
|
21
22
|
from typing import Any, BinaryIO
|
|
22
23
|
from urllib.parse import quote, urlsplit, urlunsplit
|
|
23
24
|
|
|
@@ -337,6 +338,77 @@ async def async_download_path(
|
|
|
337
338
|
pool.close()
|
|
338
339
|
|
|
339
340
|
|
|
341
|
+
def download_dir_contents(
|
|
342
|
+
endpoint: str,
|
|
343
|
+
token: str,
|
|
344
|
+
runtime_id: str,
|
|
345
|
+
src: str,
|
|
346
|
+
dst: Path,
|
|
347
|
+
*,
|
|
348
|
+
filter: Callable[[tarfile.TarInfo, str], tarfile.TarInfo | None] | None = None,
|
|
349
|
+
timeout: float,
|
|
350
|
+
attempts: int = _TRANSFER_ATTEMPTS,
|
|
351
|
+
_tls: _WebSocketTLS | None = None,
|
|
352
|
+
) -> None:
|
|
353
|
+
"""Download one seekable archive and merge its directory contents."""
|
|
354
|
+
with tempfile.TemporaryDirectory(prefix="runta-download-") as temp:
|
|
355
|
+
archive = Path(temp) / "payload.tar"
|
|
356
|
+
_retry_sync(
|
|
357
|
+
lambda: _sync_download_archive(
|
|
358
|
+
endpoint,
|
|
359
|
+
token,
|
|
360
|
+
runtime_id,
|
|
361
|
+
src,
|
|
362
|
+
archive,
|
|
363
|
+
timeout,
|
|
364
|
+
_tls=_tls,
|
|
365
|
+
directory_contents=True,
|
|
366
|
+
),
|
|
367
|
+
attempts=attempts,
|
|
368
|
+
)
|
|
369
|
+
_extract_dir_contents(archive, dst, filter)
|
|
370
|
+
|
|
371
|
+
|
|
372
|
+
async def async_download_dir_contents(
|
|
373
|
+
endpoint: str,
|
|
374
|
+
token: str,
|
|
375
|
+
runtime_id: str,
|
|
376
|
+
src: str,
|
|
377
|
+
dst: Path,
|
|
378
|
+
*,
|
|
379
|
+
filter: Callable[[tarfile.TarInfo, str], tarfile.TarInfo | None] | None = None,
|
|
380
|
+
timeout: float,
|
|
381
|
+
attempts: int = _TRANSFER_ATTEMPTS,
|
|
382
|
+
_tls: _WebSocketTLS | _AsyncWebSocketTLS | None = None,
|
|
383
|
+
_file_io: _AsyncFileIO | None = None,
|
|
384
|
+
) -> None:
|
|
385
|
+
"""Merge on the client's bounded, cancellation-safe file workers."""
|
|
386
|
+
owned_pool = _file_io is None
|
|
387
|
+
pool = _file_io or _AsyncFileIO(None, asyncio.get_running_loop)
|
|
388
|
+
try:
|
|
389
|
+
with pool.lease():
|
|
390
|
+
async with _async_download_workspace(pool) as temp:
|
|
391
|
+
archive = temp / "payload.tar"
|
|
392
|
+
await _retry_async(
|
|
393
|
+
lambda: _async_download_archive(
|
|
394
|
+
endpoint,
|
|
395
|
+
token,
|
|
396
|
+
runtime_id,
|
|
397
|
+
src,
|
|
398
|
+
archive,
|
|
399
|
+
timeout,
|
|
400
|
+
_tls=_tls,
|
|
401
|
+
_file_io=pool,
|
|
402
|
+
directory_contents=True,
|
|
403
|
+
),
|
|
404
|
+
attempts=attempts,
|
|
405
|
+
)
|
|
406
|
+
await pool.run(_extract_dir_contents, archive, dst, filter)
|
|
407
|
+
finally:
|
|
408
|
+
if owned_pool:
|
|
409
|
+
pool.close()
|
|
410
|
+
|
|
411
|
+
|
|
340
412
|
def execute(
|
|
341
413
|
endpoint: str,
|
|
342
414
|
token: str,
|
|
@@ -694,10 +766,11 @@ def _sync_download_archive(
|
|
|
694
766
|
timeout: float,
|
|
695
767
|
*,
|
|
696
768
|
_tls: _WebSocketTLS | None = None,
|
|
769
|
+
directory_contents: bool = False,
|
|
697
770
|
) -> None:
|
|
698
|
-
|
|
771
|
+
command, args = _download_archive_command(src, directory_contents)
|
|
699
772
|
with _sync_socket(endpoint, token, runtime_id, timeout, _tls=_tls) as socket:
|
|
700
|
-
_send_start(socket.send,
|
|
773
|
+
_send_start(socket.send, command, args)
|
|
701
774
|
_send_close_stdin(socket.send)
|
|
702
775
|
with archive.open("wb") as handle:
|
|
703
776
|
_receive_completion(socket.recv, stdout=handle)
|
|
@@ -713,10 +786,11 @@ async def _async_download_archive(
|
|
|
713
786
|
*,
|
|
714
787
|
_tls: _WebSocketTLS | _AsyncWebSocketTLS | None = None,
|
|
715
788
|
_file_io: _AsyncFileIO,
|
|
789
|
+
directory_contents: bool = False,
|
|
716
790
|
) -> None:
|
|
717
|
-
|
|
791
|
+
command, args = _download_archive_command(src, directory_contents)
|
|
718
792
|
async with _async_socket(endpoint, token, runtime_id, timeout, _tls=_tls) as socket:
|
|
719
|
-
await _async_send_start(socket.send,
|
|
793
|
+
await _async_send_start(socket.send, command, args)
|
|
720
794
|
await _async_send_close_stdin(socket.send)
|
|
721
795
|
writer = _AsyncDownloadWriter(_file_io, archive)
|
|
722
796
|
try:
|
|
@@ -1041,6 +1115,155 @@ async def _retry_async(
|
|
|
1041
1115
|
)
|
|
1042
1116
|
|
|
1043
1117
|
|
|
1118
|
+
def _download_archive_command(
|
|
1119
|
+
src: str, directory_contents: bool
|
|
1120
|
+
) -> tuple[str, list[str]]:
|
|
1121
|
+
if directory_contents:
|
|
1122
|
+
# cd follows only the source directory link; tar preserves nested links.
|
|
1123
|
+
# Positional arguments preserve arbitrary names without shell interpolation.
|
|
1124
|
+
return "sh", [
|
|
1125
|
+
"-c",
|
|
1126
|
+
'set -eu; CDPATH= cd -P -- "$1"; exec tar cf - .',
|
|
1127
|
+
"_",
|
|
1128
|
+
src,
|
|
1129
|
+
]
|
|
1130
|
+
parent, name = _remote_parent_and_name(src)
|
|
1131
|
+
return "tar", ["cf", "-", "-C", parent, name]
|
|
1132
|
+
|
|
1133
|
+
|
|
1134
|
+
def _safe_relative_name(name: str) -> None:
|
|
1135
|
+
# Archive names are POSIX paths even on Windows. Reject Windows aliases too,
|
|
1136
|
+
# so drive paths, separators and alternate data streams cannot bypass checks.
|
|
1137
|
+
if (
|
|
1138
|
+
not name
|
|
1139
|
+
or "\\" in name
|
|
1140
|
+
or ":" in name
|
|
1141
|
+
or "\x00" in name
|
|
1142
|
+
or PurePosixPath(name).is_absolute()
|
|
1143
|
+
or PureWindowsPath(name).drive
|
|
1144
|
+
or ".." in PurePosixPath(name).parts
|
|
1145
|
+
):
|
|
1146
|
+
raise tarfile.FilterError("download archive contains an unsafe path")
|
|
1147
|
+
|
|
1148
|
+
|
|
1149
|
+
class _DirectoryMergeTarFile(tarfile.TarFile):
|
|
1150
|
+
"""Replace file entries without writing through existing destination aliases."""
|
|
1151
|
+
|
|
1152
|
+
def makefile(self, tarinfo: tarfile.TarInfo, targetpath: str) -> None:
|
|
1153
|
+
# Do this at the actual write path, after filtering. A filter can also
|
|
1154
|
+
# run for a link fallback's referent, whose path must remain untouched.
|
|
1155
|
+
target = Path(targetpath)
|
|
1156
|
+
if target.is_dir():
|
|
1157
|
+
raise FileExistsError(
|
|
1158
|
+
f"download member conflicts with destination type: {target}"
|
|
1159
|
+
)
|
|
1160
|
+
target.unlink(missing_ok=True)
|
|
1161
|
+
super().makefile(tarinfo, targetpath)
|
|
1162
|
+
|
|
1163
|
+
|
|
1164
|
+
def _extract_dir_contents(
|
|
1165
|
+
archive_path: Path,
|
|
1166
|
+
dst: Path,
|
|
1167
|
+
filter: Callable[[tarfile.TarInfo, str], tarfile.TarInfo | None] | None = None,
|
|
1168
|
+
) -> None:
|
|
1169
|
+
data_filter = getattr(tarfile, "data_filter", None)
|
|
1170
|
+
if data_filter is None or not hasattr(tarfile.TarFile, "makelink_with_filter"):
|
|
1171
|
+
raise RuntimeError(
|
|
1172
|
+
"directory content downloads require a security-patched Python "
|
|
1173
|
+
"with tarfile.data_filter and filtered link fallback"
|
|
1174
|
+
)
|
|
1175
|
+
if dst.is_symlink():
|
|
1176
|
+
raise tarfile.FilterError("download destination must not be a symbolic link")
|
|
1177
|
+
with _DirectoryMergeTarFile.open(archive_path, "r:", errorlevel=1) as archive:
|
|
1178
|
+
members = archive.getmembers()
|
|
1179
|
+
if not members or members[0].name not in {".", "./"} or not members[0].isdir():
|
|
1180
|
+
raise _public.ApiError(
|
|
1181
|
+
"download archive did not contain a source directory"
|
|
1182
|
+
)
|
|
1183
|
+
# Rewrite the seekable archive's index as well as extraction members.
|
|
1184
|
+
# tarfile uses this index (and the original data offsets) for link fallback.
|
|
1185
|
+
for member in members:
|
|
1186
|
+
_safe_relative_name(member.name)
|
|
1187
|
+
if member.name in {".", "./"}:
|
|
1188
|
+
if not member.isdir():
|
|
1189
|
+
raise tarfile.FilterError("invalid source directory member")
|
|
1190
|
+
member.name = "."
|
|
1191
|
+
elif member.name.startswith("./"):
|
|
1192
|
+
member.name = member.name[2:]
|
|
1193
|
+
_safe_relative_name(member.name)
|
|
1194
|
+
else:
|
|
1195
|
+
raise tarfile.FilterError(
|
|
1196
|
+
"download archive member is outside the source directory"
|
|
1197
|
+
)
|
|
1198
|
+
if member.islnk():
|
|
1199
|
+
_safe_relative_name(member.linkname)
|
|
1200
|
+
if not member.linkname.startswith("./"):
|
|
1201
|
+
raise tarfile.FilterError(
|
|
1202
|
+
"hard link is outside the source directory"
|
|
1203
|
+
)
|
|
1204
|
+
member.linkname = member.linkname[2:]
|
|
1205
|
+
_safe_relative_name(member.linkname)
|
|
1206
|
+
|
|
1207
|
+
dst.mkdir(parents=True, exist_ok=True)
|
|
1208
|
+
|
|
1209
|
+
def safe_filter(
|
|
1210
|
+
member: tarfile.TarInfo, destination: str
|
|
1211
|
+
) -> tarfile.TarInfo | None:
|
|
1212
|
+
if member.name == ".":
|
|
1213
|
+
return None # Do not apply the source root's metadata to dst.
|
|
1214
|
+
_safe_relative_name(member.name)
|
|
1215
|
+
# Check boundaries before invoking user code, but allow the callback
|
|
1216
|
+
# to skip special files before data_filter rejects those file types.
|
|
1217
|
+
if member.issym() or member.islnk():
|
|
1218
|
+
link = member.linkname
|
|
1219
|
+
if (
|
|
1220
|
+
PurePosixPath(link).is_absolute()
|
|
1221
|
+
or PureWindowsPath(link).drive
|
|
1222
|
+
or "\\" in link
|
|
1223
|
+
or ":" in link
|
|
1224
|
+
or "\x00" in link
|
|
1225
|
+
):
|
|
1226
|
+
raise tarfile.FilterError(
|
|
1227
|
+
"download archive contains an unsafe link"
|
|
1228
|
+
)
|
|
1229
|
+
probe = copy.copy(member)
|
|
1230
|
+
if probe.isdev():
|
|
1231
|
+
probe.type = tarfile.REGTYPE
|
|
1232
|
+
data_filter(probe, destination)
|
|
1233
|
+
if filter is not None:
|
|
1234
|
+
member = filter(copy.copy(member), destination)
|
|
1235
|
+
if member is None:
|
|
1236
|
+
return None
|
|
1237
|
+
_safe_relative_name(member.name)
|
|
1238
|
+
if PurePosixPath(member.name) == PurePosixPath("."):
|
|
1239
|
+
raise tarfile.FilterError(
|
|
1240
|
+
"a filter cannot replace the destination root"
|
|
1241
|
+
)
|
|
1242
|
+
if member.issym() or member.islnk():
|
|
1243
|
+
link = member.linkname
|
|
1244
|
+
if (
|
|
1245
|
+
PurePosixPath(link).is_absolute()
|
|
1246
|
+
or PureWindowsPath(link).drive
|
|
1247
|
+
or "\\" in link
|
|
1248
|
+
or ":" in link
|
|
1249
|
+
or "\x00" in link
|
|
1250
|
+
):
|
|
1251
|
+
raise tarfile.FilterError(
|
|
1252
|
+
"download archive contains an unsafe link"
|
|
1253
|
+
)
|
|
1254
|
+
member = data_filter(member, destination)
|
|
1255
|
+
target = Path(destination) / member.name
|
|
1256
|
+
if target.exists() and target.is_dir() != member.isdir():
|
|
1257
|
+
raise FileExistsError(
|
|
1258
|
+
f"download member conflicts with destination type: {target}"
|
|
1259
|
+
)
|
|
1260
|
+
return member
|
|
1261
|
+
|
|
1262
|
+
# errorlevel=1 (the default) propagates security/I/O failures while
|
|
1263
|
+
# allowing stdlib's nonfatal unresolved-link fallback to skip a link.
|
|
1264
|
+
archive.extractall(dst, filter=safe_filter)
|
|
1265
|
+
|
|
1266
|
+
|
|
1044
1267
|
def _remote_parent_and_name(src: str) -> tuple[str, str]:
|
|
1045
1268
|
normalized = src.rstrip("/") or "/"
|
|
1046
1269
|
path = Path(normalized)
|