runta-sdk 0.2.3__tar.gz → 0.2.4__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.3 → runta_sdk-0.2.4}/PKG-INFO +5 -3
- {runta_sdk-0.2.3 → runta_sdk-0.2.4}/README.md +4 -2
- {runta_sdk-0.2.3 → runta_sdk-0.2.4}/pyproject.toml +1 -1
- {runta_sdk-0.2.3 → runta_sdk-0.2.4}/runta_sdk.egg-info/PKG-INFO +5 -3
- {runta_sdk-0.2.3 → runta_sdk-0.2.4}/src/runta/_internal/streaming_transfer.py +210 -47
- {runta_sdk-0.2.3 → runta_sdk-0.2.4}/tests/test_download_dir_contents.py +271 -2
- {runta_sdk-0.2.3 → runta_sdk-0.2.4}/integrations/harbor/runta_harbor/__init__.py +0 -0
- {runta_sdk-0.2.3 → runta_sdk-0.2.4}/integrations/harbor/runta_harbor/environment.py +0 -0
- {runta_sdk-0.2.3 → runta_sdk-0.2.4}/integrations/harbor/runta_harbor/py.typed +0 -0
- {runta_sdk-0.2.3 → runta_sdk-0.2.4}/integrations/openai-agents-runta/src/agents_runta/__init__.py +0 -0
- {runta_sdk-0.2.3 → runta_sdk-0.2.4}/integrations/openai-agents-runta/src/agents_runta/durable/__init__.py +0 -0
- {runta_sdk-0.2.3 → runta_sdk-0.2.4}/integrations/openai-agents-runta/src/agents_runta/durable/runner.py +0 -0
- {runta_sdk-0.2.3 → runta_sdk-0.2.4}/integrations/openai-agents-runta/src/agents_runta/durable/store.py +0 -0
- {runta_sdk-0.2.3 → runta_sdk-0.2.4}/integrations/openai-agents-runta/src/agents_runta/py.typed +0 -0
- {runta_sdk-0.2.3 → runta_sdk-0.2.4}/integrations/openai-agents-runta/src/agents_runta/sandbox.py +0 -0
- {runta_sdk-0.2.3 → runta_sdk-0.2.4}/runta_sdk.egg-info/SOURCES.txt +0 -0
- {runta_sdk-0.2.3 → runta_sdk-0.2.4}/runta_sdk.egg-info/dependency_links.txt +0 -0
- {runta_sdk-0.2.3 → runta_sdk-0.2.4}/runta_sdk.egg-info/requires.txt +0 -0
- {runta_sdk-0.2.3 → runta_sdk-0.2.4}/runta_sdk.egg-info/top_level.txt +0 -0
- {runta_sdk-0.2.3 → runta_sdk-0.2.4}/setup.cfg +0 -0
- {runta_sdk-0.2.3 → runta_sdk-0.2.4}/src/runta/__init__.py +0 -0
- {runta_sdk-0.2.3 → runta_sdk-0.2.4}/src/runta/_internal/__init__.py +0 -0
- {runta_sdk-0.2.3 → runta_sdk-0.2.4}/src/runta/_internal/async_file_io.py +0 -0
- {runta_sdk-0.2.3 → runta_sdk-0.2.4}/src/runta/_internal/async_http.py +0 -0
- {runta_sdk-0.2.3 → runta_sdk-0.2.4}/src/runta/_internal/byte_budget.py +0 -0
- {runta_sdk-0.2.3 → runta_sdk-0.2.4}/src/runta/_internal/config.py +0 -0
- {runta_sdk-0.2.3 → runta_sdk-0.2.4}/src/runta/_internal/execution.py +0 -0
- {runta_sdk-0.2.3 → runta_sdk-0.2.4}/src/runta/_internal/execution.sh +0 -0
- {runta_sdk-0.2.3 → runta_sdk-0.2.4}/src/runta/_internal/helpers.py +0 -0
- {runta_sdk-0.2.3 → runta_sdk-0.2.4}/src/runta/_internal/http_limits.py +0 -0
- {runta_sdk-0.2.3 → runta_sdk-0.2.4}/src/runta/_internal/openapi/__init__.py +0 -0
- {runta_sdk-0.2.3 → runta_sdk-0.2.4}/src/runta/_internal/openapi/api/__init__.py +0 -0
- {runta_sdk-0.2.3 → runta_sdk-0.2.4}/src/runta/_internal/openapi/api/auth/__init__.py +0 -0
- {runta_sdk-0.2.3 → runta_sdk-0.2.4}/src/runta/_internal/openapi/api/auth/begin_device_authorization.py +0 -0
- {runta_sdk-0.2.3 → runta_sdk-0.2.4}/src/runta/_internal/openapi/api/auth/exchange_device_token.py +0 -0
- {runta_sdk-0.2.3 → runta_sdk-0.2.4}/src/runta/_internal/openapi/api/auth/revoke_current_token.py +0 -0
- {runta_sdk-0.2.3 → runta_sdk-0.2.4}/src/runta/_internal/openapi/api/checkpoints/__init__.py +0 -0
- {runta_sdk-0.2.3 → runta_sdk-0.2.4}/src/runta/_internal/openapi/api/checkpoints/create_checkpoint.py +0 -0
- {runta_sdk-0.2.3 → runta_sdk-0.2.4}/src/runta/_internal/openapi/api/checkpoints/delete_checkpoint.py +0 -0
- {runta_sdk-0.2.3 → runta_sdk-0.2.4}/src/runta/_internal/openapi/api/checkpoints/get_checkpoint.py +0 -0
- {runta_sdk-0.2.3 → runta_sdk-0.2.4}/src/runta/_internal/openapi/api/checkpoints/list_checkpoints.py +0 -0
- {runta_sdk-0.2.3 → runta_sdk-0.2.4}/src/runta/_internal/openapi/api/cloud_agents/__init__.py +0 -0
- {runta_sdk-0.2.3 → runta_sdk-0.2.4}/src/runta/_internal/openapi/api/cloud_agents/cancel_cloud_agent_run.py +0 -0
- {runta_sdk-0.2.3 → runta_sdk-0.2.4}/src/runta/_internal/openapi/api/cloud_agents/create_cloud_agent.py +0 -0
- {runta_sdk-0.2.3 → runta_sdk-0.2.4}/src/runta/_internal/openapi/api/cloud_agents/create_cloud_agent_artifact.py +0 -0
- {runta_sdk-0.2.3 → runta_sdk-0.2.4}/src/runta/_internal/openapi/api/cloud_agents/create_cloud_agent_computer_session.py +0 -0
- {runta_sdk-0.2.3 → runta_sdk-0.2.4}/src/runta/_internal/openapi/api/cloud_agents/create_cloud_agent_run.py +0 -0
- {runta_sdk-0.2.3 → runta_sdk-0.2.4}/src/runta/_internal/openapi/api/cloud_agents/delete_cloud_agent.py +0 -0
- {runta_sdk-0.2.3 → runta_sdk-0.2.4}/src/runta/_internal/openapi/api/cloud_agents/delete_cloud_agent_artifact.py +0 -0
- {runta_sdk-0.2.3 → runta_sdk-0.2.4}/src/runta/_internal/openapi/api/cloud_agents/delete_cloud_agent_workspace_file.py +0 -0
- {runta_sdk-0.2.3 → runta_sdk-0.2.4}/src/runta/_internal/openapi/api/cloud_agents/execute_cloud_agent_workspace_operation.py +0 -0
- {runta_sdk-0.2.3 → runta_sdk-0.2.4}/src/runta/_internal/openapi/api/cloud_agents/follow_up_cloud_agent_run.py +0 -0
- {runta_sdk-0.2.3 → runta_sdk-0.2.4}/src/runta/_internal/openapi/api/cloud_agents/get_cloud_agent.py +0 -0
- {runta_sdk-0.2.3 → runta_sdk-0.2.4}/src/runta/_internal/openapi/api/cloud_agents/get_cloud_agent_artifact.py +0 -0
- {runta_sdk-0.2.3 → runta_sdk-0.2.4}/src/runta/_internal/openapi/api/cloud_agents/get_cloud_agent_run.py +0 -0
- {runta_sdk-0.2.3 → runta_sdk-0.2.4}/src/runta/_internal/openapi/api/cloud_agents/list_cloud_agent_artifacts.py +0 -0
- {runta_sdk-0.2.3 → runta_sdk-0.2.4}/src/runta/_internal/openapi/api/cloud_agents/list_cloud_agent_runs.py +0 -0
- {runta_sdk-0.2.3 → runta_sdk-0.2.4}/src/runta/_internal/openapi/api/cloud_agents/list_cloud_agent_session_events.py +0 -0
- {runta_sdk-0.2.3 → runta_sdk-0.2.4}/src/runta/_internal/openapi/api/cloud_agents/list_cloud_agents.py +0 -0
- {runta_sdk-0.2.3 → runta_sdk-0.2.4}/src/runta/_internal/openapi/api/cloud_agents/resume_cloud_agent_run.py +0 -0
- {runta_sdk-0.2.3 → runta_sdk-0.2.4}/src/runta/_internal/openapi/api/cloud_agents/stream_cloud_agent_run_events.py +0 -0
- {runta_sdk-0.2.3 → runta_sdk-0.2.4}/src/runta/_internal/openapi/api/cloud_agents/update_cloud_agent.py +0 -0
- {runta_sdk-0.2.3 → runta_sdk-0.2.4}/src/runta/_internal/openapi/api/cloud_agents/write_cloud_agent_workspace_file.py +0 -0
- {runta_sdk-0.2.3 → runta_sdk-0.2.4}/src/runta/_internal/openapi/api/events/__init__.py +0 -0
- {runta_sdk-0.2.3 → runta_sdk-0.2.4}/src/runta/_internal/openapi/api/events/get_organization_event.py +0 -0
- {runta_sdk-0.2.3 → runta_sdk-0.2.4}/src/runta/_internal/openapi/api/events/get_organization_token_analysis.py +0 -0
- {runta_sdk-0.2.3 → runta_sdk-0.2.4}/src/runta/_internal/openapi/api/events/list_organization_events.py +0 -0
- {runta_sdk-0.2.3 → runta_sdk-0.2.4}/src/runta/_internal/openapi/api/events/list_organization_token_analysis.py +0 -0
- {runta_sdk-0.2.3 → runta_sdk-0.2.4}/src/runta/_internal/openapi/api/events/list_organization_token_savings.py +0 -0
- {runta_sdk-0.2.3 → runta_sdk-0.2.4}/src/runta/_internal/openapi/api/files/__init__.py +0 -0
- {runta_sdk-0.2.3 → runta_sdk-0.2.4}/src/runta/_internal/openapi/api/files/read_runtime_file.py +0 -0
- {runta_sdk-0.2.3 → runta_sdk-0.2.4}/src/runta/_internal/openapi/api/files/write_runtime_file.py +0 -0
- {runta_sdk-0.2.3 → runta_sdk-0.2.4}/src/runta/_internal/openapi/api/git_hub/__init__.py +0 -0
- {runta_sdk-0.2.3 → runta_sdk-0.2.4}/src/runta/_internal/openapi/api/git_hub/create_git_hub_authorization_request.py +0 -0
- {runta_sdk-0.2.3 → runta_sdk-0.2.4}/src/runta/_internal/openapi/api/git_hub/create_git_hub_runtime_binding.py +0 -0
- {runta_sdk-0.2.3 → runta_sdk-0.2.4}/src/runta/_internal/openapi/api/git_hub/delete_git_hub_runtime_binding.py +0 -0
- {runta_sdk-0.2.3 → runta_sdk-0.2.4}/src/runta/_internal/openapi/api/git_hub/get_git_hub_authorization_request.py +0 -0
- {runta_sdk-0.2.3 → runta_sdk-0.2.4}/src/runta/_internal/openapi/api/git_hub/get_git_hub_runtime_binding.py +0 -0
- {runta_sdk-0.2.3 → runta_sdk-0.2.4}/src/runta/_internal/openapi/api/git_hub/list_git_hub_authorization_requests.py +0 -0
- {runta_sdk-0.2.3 → runta_sdk-0.2.4}/src/runta/_internal/openapi/api/git_hub/list_git_hub_branches.py +0 -0
- {runta_sdk-0.2.3 → runta_sdk-0.2.4}/src/runta/_internal/openapi/api/git_hub/list_git_hub_repositories.py +0 -0
- {runta_sdk-0.2.3 → runta_sdk-0.2.4}/src/runta/_internal/openapi/api/git_hub/replace_git_hub_runtime_bindings.py +0 -0
- {runta_sdk-0.2.3 → runta_sdk-0.2.4}/src/runta/_internal/openapi/api/health/__init__.py +0 -0
- {runta_sdk-0.2.3 → runta_sdk-0.2.4}/src/runta/_internal/openapi/api/health/head_healthz.py +0 -0
- {runta_sdk-0.2.3 → runta_sdk-0.2.4}/src/runta/_internal/openapi/api/health/healthz.py +0 -0
- {runta_sdk-0.2.3 → runta_sdk-0.2.4}/src/runta/_internal/openapi/api/identity/__init__.py +0 -0
- {runta_sdk-0.2.3 → runta_sdk-0.2.4}/src/runta/_internal/openapi/api/identity/get_me.py +0 -0
- {runta_sdk-0.2.3 → runta_sdk-0.2.4}/src/runta/_internal/openapi/api/managed_model_providers/__init__.py +0 -0
- {runta_sdk-0.2.3 → runta_sdk-0.2.4}/src/runta/_internal/openapi/api/managed_model_providers/list_managed_model_providers.py +0 -0
- {runta_sdk-0.2.3 → runta_sdk-0.2.4}/src/runta/_internal/openapi/api/managed_model_providers/update_managed_model_provider.py +0 -0
- {runta_sdk-0.2.3 → runta_sdk-0.2.4}/src/runta/_internal/openapi/api/runtimes/__init__.py +0 -0
- {runta_sdk-0.2.3 → runta_sdk-0.2.4}/src/runta/_internal/openapi/api/runtimes/cancel_runtime_image_build.py +0 -0
- {runta_sdk-0.2.3 → runta_sdk-0.2.4}/src/runta/_internal/openapi/api/runtimes/create_runtime.py +0 -0
- {runta_sdk-0.2.3 → runta_sdk-0.2.4}/src/runta/_internal/openapi/api/runtimes/create_runtime_image_build.py +0 -0
- {runta_sdk-0.2.3 → runta_sdk-0.2.4}/src/runta/_internal/openapi/api/runtimes/create_runtime_vnc_credential.py +0 -0
- {runta_sdk-0.2.3 → runta_sdk-0.2.4}/src/runta/_internal/openapi/api/runtimes/delete_runtime.py +0 -0
- {runta_sdk-0.2.3 → runta_sdk-0.2.4}/src/runta/_internal/openapi/api/runtimes/delete_runtime_image.py +0 -0
- {runta_sdk-0.2.3 → runta_sdk-0.2.4}/src/runta/_internal/openapi/api/runtimes/disable_runtime_vnc.py +0 -0
- {runta_sdk-0.2.3 → runta_sdk-0.2.4}/src/runta/_internal/openapi/api/runtimes/dismiss_runtime_image_build.py +0 -0
- {runta_sdk-0.2.3 → runta_sdk-0.2.4}/src/runta/_internal/openapi/api/runtimes/enable_runtime_vnc.py +0 -0
- {runta_sdk-0.2.3 → runta_sdk-0.2.4}/src/runta/_internal/openapi/api/runtimes/get_runtime.py +0 -0
- {runta_sdk-0.2.3 → runta_sdk-0.2.4}/src/runta/_internal/openapi/api/runtimes/get_runtime_image_build.py +0 -0
- {runta_sdk-0.2.3 → runta_sdk-0.2.4}/src/runta/_internal/openapi/api/runtimes/list_runtime_image_builds.py +0 -0
- {runta_sdk-0.2.3 → runta_sdk-0.2.4}/src/runta/_internal/openapi/api/runtimes/list_runtime_images.py +0 -0
- {runta_sdk-0.2.3 → runta_sdk-0.2.4}/src/runta/_internal/openapi/api/runtimes/list_runtime_vnc_credentials.py +0 -0
- {runta_sdk-0.2.3 → runta_sdk-0.2.4}/src/runta/_internal/openapi/api/runtimes/list_runtimes.py +0 -0
- {runta_sdk-0.2.3 → runta_sdk-0.2.4}/src/runta/_internal/openapi/api/runtimes/patch_runtime.py +0 -0
- {runta_sdk-0.2.3 → runta_sdk-0.2.4}/src/runta/_internal/openapi/api/runtimes/pause_runtime.py +0 -0
- {runta_sdk-0.2.3 → runta_sdk-0.2.4}/src/runta/_internal/openapi/api/runtimes/resume_runtime.py +0 -0
- {runta_sdk-0.2.3 → runta_sdk-0.2.4}/src/runta/_internal/openapi/api/runtimes/revoke_runtime_vnc_credential.py +0 -0
- {runta_sdk-0.2.3 → runta_sdk-0.2.4}/src/runta/_internal/openapi/api/runtimes/start_runtime.py +0 -0
- {runta_sdk-0.2.3 → runta_sdk-0.2.4}/src/runta/_internal/openapi/api/runtimes/stop_runtime.py +0 -0
- {runta_sdk-0.2.3 → runta_sdk-0.2.4}/src/runta/_internal/openapi/api/secrets/__init__.py +0 -0
- {runta_sdk-0.2.3 → runta_sdk-0.2.4}/src/runta/_internal/openapi/api/secrets/create_secret.py +0 -0
- {runta_sdk-0.2.3 → runta_sdk-0.2.4}/src/runta/_internal/openapi/api/secrets/delete_secret.py +0 -0
- {runta_sdk-0.2.3 → runta_sdk-0.2.4}/src/runta/_internal/openapi/api/secrets/get_secret.py +0 -0
- {runta_sdk-0.2.3 → runta_sdk-0.2.4}/src/runta/_internal/openapi/api/secrets/list_secrets.py +0 -0
- {runta_sdk-0.2.3 → runta_sdk-0.2.4}/src/runta/_internal/openapi/api/secrets/set_secret.py +0 -0
- {runta_sdk-0.2.3 → runta_sdk-0.2.4}/src/runta/_internal/openapi/api/ssh_keys/__init__.py +0 -0
- {runta_sdk-0.2.3 → runta_sdk-0.2.4}/src/runta/_internal/openapi/api/ssh_keys/attach_runtime_ssh_key.py +0 -0
- {runta_sdk-0.2.3 → runta_sdk-0.2.4}/src/runta/_internal/openapi/api/ssh_keys/create_ssh_key.py +0 -0
- {runta_sdk-0.2.3 → runta_sdk-0.2.4}/src/runta/_internal/openapi/api/ssh_keys/delete_ssh_key.py +0 -0
- {runta_sdk-0.2.3 → runta_sdk-0.2.4}/src/runta/_internal/openapi/api/ssh_keys/detach_runtime_ssh_key.py +0 -0
- {runta_sdk-0.2.3 → runta_sdk-0.2.4}/src/runta/_internal/openapi/api/ssh_keys/get_ssh_host_key.py +0 -0
- {runta_sdk-0.2.3 → runta_sdk-0.2.4}/src/runta/_internal/openapi/api/ssh_keys/list_runtime_ssh_keys.py +0 -0
- {runta_sdk-0.2.3 → runta_sdk-0.2.4}/src/runta/_internal/openapi/api/ssh_keys/list_ssh_keys.py +0 -0
- {runta_sdk-0.2.3 → runta_sdk-0.2.4}/src/runta/_internal/openapi/client.py +0 -0
- {runta_sdk-0.2.3 → runta_sdk-0.2.4}/src/runta/_internal/openapi/errors.py +0 -0
- {runta_sdk-0.2.3 → runta_sdk-0.2.4}/src/runta/_internal/openapi/models/__init__.py +0 -0
- {runta_sdk-0.2.3 → runta_sdk-0.2.4}/src/runta/_internal/openapi/models/allowlist_egress_policy.py +0 -0
- {runta_sdk-0.2.3 → runta_sdk-0.2.4}/src/runta/_internal/openapi/models/allowlist_egress_policy_mode.py +0 -0
- {runta_sdk-0.2.3 → runta_sdk-0.2.4}/src/runta/_internal/openapi/models/approved_git_hub_authorization.py +0 -0
- {runta_sdk-0.2.3 → runta_sdk-0.2.4}/src/runta/_internal/openapi/models/approved_git_hub_authorization_status.py +0 -0
- {runta_sdk-0.2.3 → runta_sdk-0.2.4}/src/runta/_internal/openapi/models/begin_device_authorization_request.py +0 -0
- {runta_sdk-0.2.3 → runta_sdk-0.2.4}/src/runta/_internal/openapi/models/begin_device_authorization_request_client_id.py +0 -0
- {runta_sdk-0.2.3 → runta_sdk-0.2.4}/src/runta/_internal/openapi/models/checkpoint.py +0 -0
- {runta_sdk-0.2.3 → runta_sdk-0.2.4}/src/runta/_internal/openapi/models/checkpoint_pagination.py +0 -0
- {runta_sdk-0.2.3 → runta_sdk-0.2.4}/src/runta/_internal/openapi/models/checkpoint_response.py +0 -0
- {runta_sdk-0.2.3 → runta_sdk-0.2.4}/src/runta/_internal/openapi/models/checkpoint_runtime_restore_request.py +0 -0
- {runta_sdk-0.2.3 → runta_sdk-0.2.4}/src/runta/_internal/openapi/models/checkpoint_source_runtime.py +0 -0
- {runta_sdk-0.2.3 → runta_sdk-0.2.4}/src/runta/_internal/openapi/models/cloud_agent.py +0 -0
- {runta_sdk-0.2.3 → runta_sdk-0.2.4}/src/runta/_internal/openapi/models/cloud_agent_artifact.py +0 -0
- {runta_sdk-0.2.3 → runta_sdk-0.2.4}/src/runta/_internal/openapi/models/cloud_agent_computer_session.py +0 -0
- {runta_sdk-0.2.3 → runta_sdk-0.2.4}/src/runta/_internal/openapi/models/cloud_agent_computer_session_channels.py +0 -0
- {runta_sdk-0.2.3 → runta_sdk-0.2.4}/src/runta/_internal/openapi/models/cloud_agent_event.py +0 -0
- {runta_sdk-0.2.3 → runta_sdk-0.2.4}/src/runta/_internal/openapi/models/cloud_agent_harness_request.py +0 -0
- {runta_sdk-0.2.3 → runta_sdk-0.2.4}/src/runta/_internal/openapi/models/cloud_agent_latest_reply.py +0 -0
- {runta_sdk-0.2.3 → runta_sdk-0.2.4}/src/runta/_internal/openapi/models/cloud_agent_list.py +0 -0
- {runta_sdk-0.2.3 → runta_sdk-0.2.4}/src/runta/_internal/openapi/models/cloud_agent_prompt_image.py +0 -0
- {runta_sdk-0.2.3 → runta_sdk-0.2.4}/src/runta/_internal/openapi/models/cloud_agent_prompt_image_mime_type.py +0 -0
- {runta_sdk-0.2.3 → runta_sdk-0.2.4}/src/runta/_internal/openapi/models/cloud_agent_prompt_image_type.py +0 -0
- {runta_sdk-0.2.3 → runta_sdk-0.2.4}/src/runta/_internal/openapi/models/cloud_agent_run.py +0 -0
- {runta_sdk-0.2.3 → runta_sdk-0.2.4}/src/runta/_internal/openapi/models/cloud_agent_runtime_reference.py +0 -0
- {runta_sdk-0.2.3 → runta_sdk-0.2.4}/src/runta/_internal/openapi/models/cloud_agent_runtime_reference_type.py +0 -0
- {runta_sdk-0.2.3 → runta_sdk-0.2.4}/src/runta/_internal/openapi/models/cloud_agent_session_events.py +0 -0
- {runta_sdk-0.2.3 → runta_sdk-0.2.4}/src/runta/_internal/openapi/models/cloud_agent_vnc_session_channel.py +0 -0
- {runta_sdk-0.2.3 → runta_sdk-0.2.4}/src/runta/_internal/openapi/models/cloud_agent_workspace_delete_request.py +0 -0
- {runta_sdk-0.2.3 → runta_sdk-0.2.4}/src/runta/_internal/openapi/models/cloud_agent_workspace_write_request.py +0 -0
- {runta_sdk-0.2.3 → runta_sdk-0.2.4}/src/runta/_internal/openapi/models/cloud_agent_workspace_write_result.py +0 -0
- {runta_sdk-0.2.3 → runta_sdk-0.2.4}/src/runta/_internal/openapi/models/cold_restore_resource_requests.py +0 -0
- {runta_sdk-0.2.3 → runta_sdk-0.2.4}/src/runta/_internal/openapi/models/cold_restore_resources.py +0 -0
- {runta_sdk-0.2.3 → runta_sdk-0.2.4}/src/runta/_internal/openapi/models/create_checkpoint_request.py +0 -0
- {runta_sdk-0.2.3 → runta_sdk-0.2.4}/src/runta/_internal/openapi/models/create_checkpoint_request_kind.py +0 -0
- {runta_sdk-0.2.3 → runta_sdk-0.2.4}/src/runta/_internal/openapi/models/create_cloud_agent_artifact_request.py +0 -0
- {runta_sdk-0.2.3 → runta_sdk-0.2.4}/src/runta/_internal/openapi/models/create_cloud_agent_request.py +0 -0
- {runta_sdk-0.2.3 → runta_sdk-0.2.4}/src/runta/_internal/openapi/models/create_cloud_agent_run_request.py +0 -0
- {runta_sdk-0.2.3 → runta_sdk-0.2.4}/src/runta/_internal/openapi/models/create_git_hub_authorization_request_request.py +0 -0
- {runta_sdk-0.2.3 → runta_sdk-0.2.4}/src/runta/_internal/openapi/models/create_git_hub_runtime_binding_request.py +0 -0
- {runta_sdk-0.2.3 → runta_sdk-0.2.4}/src/runta/_internal/openapi/models/create_llm_token_saving_policy.py +0 -0
- {runta_sdk-0.2.3 → runta_sdk-0.2.4}/src/runta/_internal/openapi/models/create_runtime_image_build_request.py +0 -0
- {runta_sdk-0.2.3 → runta_sdk-0.2.4}/src/runta/_internal/openapi/models/create_runtime_image_build_request_architecture.py +0 -0
- {runta_sdk-0.2.3 → runta_sdk-0.2.4}/src/runta/_internal/openapi/models/create_runtime_image_selection.py +0 -0
- {runta_sdk-0.2.3 → runta_sdk-0.2.4}/src/runta/_internal/openapi/models/create_runtime_resource_requests.py +0 -0
- {runta_sdk-0.2.3 → runta_sdk-0.2.4}/src/runta/_internal/openapi/models/create_runtime_resources.py +0 -0
- {runta_sdk-0.2.3 → runta_sdk-0.2.4}/src/runta/_internal/openapi/models/create_secret_request.py +0 -0
- {runta_sdk-0.2.3 → runta_sdk-0.2.4}/src/runta/_internal/openapi/models/create_ssh_key_request.py +0 -0
- {runta_sdk-0.2.3 → runta_sdk-0.2.4}/src/runta/_internal/openapi/models/create_vnc_credential_request.py +0 -0
- {runta_sdk-0.2.3 → runta_sdk-0.2.4}/src/runta/_internal/openapi/models/create_vnc_credential_response.py +0 -0
- {runta_sdk-0.2.3 → runta_sdk-0.2.4}/src/runta/_internal/openapi/models/denied_git_hub_authorization.py +0 -0
- {runta_sdk-0.2.3 → runta_sdk-0.2.4}/src/runta/_internal/openapi/models/denied_git_hub_authorization_status.py +0 -0
- {runta_sdk-0.2.3 → runta_sdk-0.2.4}/src/runta/_internal/openapi/models/denylist_egress_policy.py +0 -0
- {runta_sdk-0.2.3 → runta_sdk-0.2.4}/src/runta/_internal/openapi/models/denylist_egress_policy_mode.py +0 -0
- {runta_sdk-0.2.3 → runta_sdk-0.2.4}/src/runta/_internal/openapi/models/device_authorization_start.py +0 -0
- {runta_sdk-0.2.3 → runta_sdk-0.2.4}/src/runta/_internal/openapi/models/device_authorization_start_response.py +0 -0
- {runta_sdk-0.2.3 → runta_sdk-0.2.4}/src/runta/_internal/openapi/models/device_token_error.py +0 -0
- {runta_sdk-0.2.3 → runta_sdk-0.2.4}/src/runta/_internal/openapi/models/device_token_response.py +0 -0
- {runta_sdk-0.2.3 → runta_sdk-0.2.4}/src/runta/_internal/openapi/models/disabled_idle_policy.py +0 -0
- {runta_sdk-0.2.3 → runta_sdk-0.2.4}/src/runta/_internal/openapi/models/disabled_idle_policy_mode.py +0 -0
- {runta_sdk-0.2.3 → runta_sdk-0.2.4}/src/runta/_internal/openapi/models/empty_object.py +0 -0
- {runta_sdk-0.2.3 → runta_sdk-0.2.4}/src/runta/_internal/openapi/models/empty_response.py +0 -0
- {runta_sdk-0.2.3 → runta_sdk-0.2.4}/src/runta/_internal/openapi/models/error_body.py +0 -0
- {runta_sdk-0.2.3 → runta_sdk-0.2.4}/src/runta/_internal/openapi/models/error_envelope.py +0 -0
- {runta_sdk-0.2.3 → runta_sdk-0.2.4}/src/runta/_internal/openapi/models/event.py +0 -0
- {runta_sdk-0.2.3 → runta_sdk-0.2.4}/src/runta/_internal/openapi/models/event_list.py +0 -0
- {runta_sdk-0.2.3 → runta_sdk-0.2.4}/src/runta/_internal/openapi/models/event_list_response.py +0 -0
- {runta_sdk-0.2.3 → runta_sdk-0.2.4}/src/runta/_internal/openapi/models/event_response.py +0 -0
- {runta_sdk-0.2.3 → runta_sdk-0.2.4}/src/runta/_internal/openapi/models/exchange_device_token_request.py +0 -0
- {runta_sdk-0.2.3 → runta_sdk-0.2.4}/src/runta/_internal/openapi/models/expired_git_hub_authorization.py +0 -0
- {runta_sdk-0.2.3 → runta_sdk-0.2.4}/src/runta/_internal/openapi/models/expired_git_hub_authorization_status.py +0 -0
- {runta_sdk-0.2.3 → runta_sdk-0.2.4}/src/runta/_internal/openapi/models/fresh_runtime_create_request.py +0 -0
- {runta_sdk-0.2.3 → runta_sdk-0.2.4}/src/runta/_internal/openapi/models/fresh_runtime_create_request_environment_variables.py +0 -0
- {runta_sdk-0.2.3 → runta_sdk-0.2.4}/src/runta/_internal/openapi/models/git_hub_authorization_decision_metadata.py +0 -0
- {runta_sdk-0.2.3 → runta_sdk-0.2.4}/src/runta/_internal/openapi/models/git_hub_authorization_request.py +0 -0
- {runta_sdk-0.2.3 → runta_sdk-0.2.4}/src/runta/_internal/openapi/models/git_hub_authorization_request_list.py +0 -0
- {runta_sdk-0.2.3 → runta_sdk-0.2.4}/src/runta/_internal/openapi/models/git_hub_authorization_request_list_response.py +0 -0
- {runta_sdk-0.2.3 → runta_sdk-0.2.4}/src/runta/_internal/openapi/models/git_hub_authorization_request_response.py +0 -0
- {runta_sdk-0.2.3 → runta_sdk-0.2.4}/src/runta/_internal/openapi/models/git_hub_branch.py +0 -0
- {runta_sdk-0.2.3 → runta_sdk-0.2.4}/src/runta/_internal/openapi/models/git_hub_branch_list.py +0 -0
- {runta_sdk-0.2.3 → runta_sdk-0.2.4}/src/runta/_internal/openapi/models/git_hub_branch_list_response.py +0 -0
- {runta_sdk-0.2.3 → runta_sdk-0.2.4}/src/runta/_internal/openapi/models/git_hub_installation.py +0 -0
- {runta_sdk-0.2.3 → runta_sdk-0.2.4}/src/runta/_internal/openapi/models/git_hub_repository.py +0 -0
- {runta_sdk-0.2.3 → runta_sdk-0.2.4}/src/runta/_internal/openapi/models/git_hub_repository_list.py +0 -0
- {runta_sdk-0.2.3 → runta_sdk-0.2.4}/src/runta/_internal/openapi/models/git_hub_repository_list_response.py +0 -0
- {runta_sdk-0.2.3 → runta_sdk-0.2.4}/src/runta/_internal/openapi/models/git_hub_runtime_binding.py +0 -0
- {runta_sdk-0.2.3 → runta_sdk-0.2.4}/src/runta/_internal/openapi/models/git_hub_runtime_binding_list.py +0 -0
- {runta_sdk-0.2.3 → runta_sdk-0.2.4}/src/runta/_internal/openapi/models/git_hub_runtime_binding_list_response.py +0 -0
- {runta_sdk-0.2.3 → runta_sdk-0.2.4}/src/runta/_internal/openapi/models/git_hub_runtime_binding_response.py +0 -0
- {runta_sdk-0.2.3 → runta_sdk-0.2.4}/src/runta/_internal/openapi/models/installed_git_hub_authorization.py +0 -0
- {runta_sdk-0.2.3 → runta_sdk-0.2.4}/src/runta/_internal/openapi/models/installed_git_hub_authorization_status.py +0 -0
- {runta_sdk-0.2.3 → runta_sdk-0.2.4}/src/runta/_internal/openapi/models/list_checkpoints_response.py +0 -0
- {runta_sdk-0.2.3 → runta_sdk-0.2.4}/src/runta/_internal/openapi/models/list_runtime_image_builds_response.py +0 -0
- {runta_sdk-0.2.3 → runta_sdk-0.2.4}/src/runta/_internal/openapi/models/list_runtime_images_response.py +0 -0
- {runta_sdk-0.2.3 → runta_sdk-0.2.4}/src/runta/_internal/openapi/models/list_runtimes_response.py +0 -0
- {runta_sdk-0.2.3 → runta_sdk-0.2.4}/src/runta/_internal/openapi/models/list_secrets_response.py +0 -0
- {runta_sdk-0.2.3 → runta_sdk-0.2.4}/src/runta/_internal/openapi/models/list_ssh_keys_response.py +0 -0
- {runta_sdk-0.2.3 → runta_sdk-0.2.4}/src/runta/_internal/openapi/models/list_vnc_credentials_response.py +0 -0
- {runta_sdk-0.2.3 → runta_sdk-0.2.4}/src/runta/_internal/openapi/models/llm_token_saving_policy.py +0 -0
- {runta_sdk-0.2.3 → runta_sdk-0.2.4}/src/runta/_internal/openapi/models/managed_model_provider.py +0 -0
- {runta_sdk-0.2.3 → runta_sdk-0.2.4}/src/runta/_internal/openapi/models/managed_model_provider_list.py +0 -0
- {runta_sdk-0.2.3 → runta_sdk-0.2.4}/src/runta/_internal/openapi/models/managed_model_provider_reference.py +0 -0
- {runta_sdk-0.2.3 → runta_sdk-0.2.4}/src/runta/_internal/openapi/models/managed_model_provider_reference_type.py +0 -0
- {runta_sdk-0.2.3 → runta_sdk-0.2.4}/src/runta/_internal/openapi/models/patch_llm_token_saving_policy.py +0 -0
- {runta_sdk-0.2.3 → runta_sdk-0.2.4}/src/runta/_internal/openapi/models/patch_runtime_request.py +0 -0
- {runta_sdk-0.2.3 → runta_sdk-0.2.4}/src/runta/_internal/openapi/models/patch_runtime_request_environment_variables.py +0 -0
- {runta_sdk-0.2.3 → runta_sdk-0.2.4}/src/runta/_internal/openapi/models/patch_runtime_resource_requests.py +0 -0
- {runta_sdk-0.2.3 → runta_sdk-0.2.4}/src/runta/_internal/openapi/models/patch_runtime_resources.py +0 -0
- {runta_sdk-0.2.3 → runta_sdk-0.2.4}/src/runta/_internal/openapi/models/pending_git_hub_authorization.py +0 -0
- {runta_sdk-0.2.3 → runta_sdk-0.2.4}/src/runta/_internal/openapi/models/pending_git_hub_authorization_status.py +0 -0
- {runta_sdk-0.2.3 → runta_sdk-0.2.4}/src/runta/_internal/openapi/models/public_checkpoint_state.py +0 -0
- {runta_sdk-0.2.3 → runta_sdk-0.2.4}/src/runta/_internal/openapi/models/public_error_code.py +0 -0
- {runta_sdk-0.2.3 → runta_sdk-0.2.4}/src/runta/_internal/openapi/models/public_ingress_protocol.py +0 -0
- {runta_sdk-0.2.3 → runta_sdk-0.2.4}/src/runta/_internal/openapi/models/public_ingress_spec.py +0 -0
- {runta_sdk-0.2.3 → runta_sdk-0.2.4}/src/runta/_internal/openapi/models/public_runtime_status.py +0 -0
- {runta_sdk-0.2.3 → runta_sdk-0.2.4}/src/runta/_internal/openapi/models/replace_git_hub_runtime_bindings_request.py +0 -0
- {runta_sdk-0.2.3 → runta_sdk-0.2.4}/src/runta/_internal/openapi/models/replace_git_hub_runtime_bindings_request_repositories_item.py +0 -0
- {runta_sdk-0.2.3 → runta_sdk-0.2.4}/src/runta/_internal/openapi/models/runtime.py +0 -0
- {runta_sdk-0.2.3 → runta_sdk-0.2.4}/src/runta/_internal/openapi/models/runtime_desired_status.py +0 -0
- {runta_sdk-0.2.3 → runta_sdk-0.2.4}/src/runta/_internal/openapi/models/runtime_environment_variables.py +0 -0
- {runta_sdk-0.2.3 → runta_sdk-0.2.4}/src/runta/_internal/openapi/models/runtime_image.py +0 -0
- {runta_sdk-0.2.3 → runta_sdk-0.2.4}/src/runta/_internal/openapi/models/runtime_image_architectures_item.py +0 -0
- {runta_sdk-0.2.3 → runta_sdk-0.2.4}/src/runta/_internal/openapi/models/runtime_image_build.py +0 -0
- {runta_sdk-0.2.3 → runta_sdk-0.2.4}/src/runta/_internal/openapi/models/runtime_image_build_architecture.py +0 -0
- {runta_sdk-0.2.3 → runta_sdk-0.2.4}/src/runta/_internal/openapi/models/runtime_image_build_attempt.py +0 -0
- {runta_sdk-0.2.3 → runta_sdk-0.2.4}/src/runta/_internal/openapi/models/runtime_image_build_attempt_outcome.py +0 -0
- {runta_sdk-0.2.3 → runta_sdk-0.2.4}/src/runta/_internal/openapi/models/runtime_image_build_response.py +0 -0
- {runta_sdk-0.2.3 → runta_sdk-0.2.4}/src/runta/_internal/openapi/models/runtime_image_build_status.py +0 -0
- {runta_sdk-0.2.3 → runta_sdk-0.2.4}/src/runta/_internal/openapi/models/runtime_image_disk_capability.py +0 -0
- {runta_sdk-0.2.3 → runta_sdk-0.2.4}/src/runta/_internal/openapi/models/runtime_image_model_provider.py +0 -0
- {runta_sdk-0.2.3 → runta_sdk-0.2.4}/src/runta/_internal/openapi/models/runtime_image_protocol_binding.py +0 -0
- {runta_sdk-0.2.3 → runta_sdk-0.2.4}/src/runta/_internal/openapi/models/runtime_image_recommended_resources.py +0 -0
- {runta_sdk-0.2.3 → runta_sdk-0.2.4}/src/runta/_internal/openapi/models/runtime_image_subscription_option.py +0 -0
- {runta_sdk-0.2.3 → runta_sdk-0.2.4}/src/runta/_internal/openapi/models/runtime_image_web_ui.py +0 -0
- {runta_sdk-0.2.3 → runta_sdk-0.2.4}/src/runta/_internal/openapi/models/runtime_pagination.py +0 -0
- {runta_sdk-0.2.3 → runta_sdk-0.2.4}/src/runta/_internal/openapi/models/runtime_repository_selection.py +0 -0
- {runta_sdk-0.2.3 → runta_sdk-0.2.4}/src/runta/_internal/openapi/models/runtime_resource_current.py +0 -0
- {runta_sdk-0.2.3 → runta_sdk-0.2.4}/src/runta/_internal/openapi/models/runtime_resource_limits.py +0 -0
- {runta_sdk-0.2.3 → runta_sdk-0.2.4}/src/runta/_internal/openapi/models/runtime_resource_requests.py +0 -0
- {runta_sdk-0.2.3 → runta_sdk-0.2.4}/src/runta/_internal/openapi/models/runtime_resources.py +0 -0
- {runta_sdk-0.2.3 → runta_sdk-0.2.4}/src/runta/_internal/openapi/models/runtime_response.py +0 -0
- {runta_sdk-0.2.3 → runta_sdk-0.2.4}/src/runta/_internal/openapi/models/runtime_secret_configuration.py +0 -0
- {runta_sdk-0.2.3 → runta_sdk-0.2.4}/src/runta/_internal/openapi/models/runtime_workspace_file_entry.py +0 -0
- {runta_sdk-0.2.3 → runta_sdk-0.2.4}/src/runta/_internal/openapi/models/runtime_workspace_file_kind.py +0 -0
- {runta_sdk-0.2.3 → runta_sdk-0.2.4}/src/runta/_internal/openapi/models/runtime_workspace_operation_kind.py +0 -0
- {runta_sdk-0.2.3 → runta_sdk-0.2.4}/src/runta/_internal/openapi/models/runtime_workspace_operation_request.py +0 -0
- {runta_sdk-0.2.3 → runta_sdk-0.2.4}/src/runta/_internal/openapi/models/runtime_workspace_operation_result.py +0 -0
- {runta_sdk-0.2.3 → runta_sdk-0.2.4}/src/runta/_internal/openapi/models/runtime_workspace_port.py +0 -0
- {runta_sdk-0.2.3 → runta_sdk-0.2.4}/src/runta/_internal/openapi/models/runtime_workspace_search_match.py +0 -0
- {runta_sdk-0.2.3 → runta_sdk-0.2.4}/src/runta/_internal/openapi/models/secret.py +0 -0
- {runta_sdk-0.2.3 → runta_sdk-0.2.4}/src/runta/_internal/openapi/models/secret_egress_injection.py +0 -0
- {runta_sdk-0.2.3 → runta_sdk-0.2.4}/src/runta/_internal/openapi/models/secret_environment_injection.py +0 -0
- {runta_sdk-0.2.3 → runta_sdk-0.2.4}/src/runta/_internal/openapi/models/secret_file_injection.py +0 -0
- {runta_sdk-0.2.3 → runta_sdk-0.2.4}/src/runta/_internal/openapi/models/secret_injection_action.py +0 -0
- {runta_sdk-0.2.3 → runta_sdk-0.2.4}/src/runta/_internal/openapi/models/secret_response.py +0 -0
- {runta_sdk-0.2.3 → runta_sdk-0.2.4}/src/runta/_internal/openapi/models/set_secret_request.py +0 -0
- {runta_sdk-0.2.3 → runta_sdk-0.2.4}/src/runta/_internal/openapi/models/ssh_host_key.py +0 -0
- {runta_sdk-0.2.3 → runta_sdk-0.2.4}/src/runta/_internal/openapi/models/ssh_host_key_response.py +0 -0
- {runta_sdk-0.2.3 → runta_sdk-0.2.4}/src/runta/_internal/openapi/models/ssh_key.py +0 -0
- {runta_sdk-0.2.3 → runta_sdk-0.2.4}/src/runta/_internal/openapi/models/ssh_key_response.py +0 -0
- {runta_sdk-0.2.3 → runta_sdk-0.2.4}/src/runta/_internal/openapi/models/suspend_and_wakeup_idle_policy.py +0 -0
- {runta_sdk-0.2.3 → runta_sdk-0.2.4}/src/runta/_internal/openapi/models/suspend_and_wakeup_idle_policy_mode.py +0 -0
- {runta_sdk-0.2.3 → runta_sdk-0.2.4}/src/runta/_internal/openapi/models/suspend_only_idle_policy.py +0 -0
- {runta_sdk-0.2.3 → runta_sdk-0.2.4}/src/runta/_internal/openapi/models/suspend_only_idle_policy_mode.py +0 -0
- {runta_sdk-0.2.3 → runta_sdk-0.2.4}/src/runta/_internal/openapi/models/token_analysis_detail.py +0 -0
- {runta_sdk-0.2.3 → runta_sdk-0.2.4}/src/runta/_internal/openapi/models/token_analysis_detail_response.py +0 -0
- {runta_sdk-0.2.3 → runta_sdk-0.2.4}/src/runta/_internal/openapi/models/token_analysis_finding.py +0 -0
- {runta_sdk-0.2.3 → runta_sdk-0.2.4}/src/runta/_internal/openapi/models/token_analysis_finding_confidence.py +0 -0
- {runta_sdk-0.2.3 → runta_sdk-0.2.4}/src/runta/_internal/openapi/models/token_analysis_finding_kind.py +0 -0
- {runta_sdk-0.2.3 → runta_sdk-0.2.4}/src/runta/_internal/openapi/models/token_analysis_finding_severity.py +0 -0
- {runta_sdk-0.2.3 → runta_sdk-0.2.4}/src/runta/_internal/openapi/models/token_analysis_issue.py +0 -0
- {runta_sdk-0.2.3 → runta_sdk-0.2.4}/src/runta/_internal/openapi/models/token_analysis_issue_confidence.py +0 -0
- {runta_sdk-0.2.3 → runta_sdk-0.2.4}/src/runta/_internal/openapi/models/token_analysis_issue_kind.py +0 -0
- {runta_sdk-0.2.3 → runta_sdk-0.2.4}/src/runta/_internal/openapi/models/token_analysis_issue_severity.py +0 -0
- {runta_sdk-0.2.3 → runta_sdk-0.2.4}/src/runta/_internal/openapi/models/token_analysis_list.py +0 -0
- {runta_sdk-0.2.3 → runta_sdk-0.2.4}/src/runta/_internal/openapi/models/token_analysis_list_response.py +0 -0
- {runta_sdk-0.2.3 → runta_sdk-0.2.4}/src/runta/_internal/openapi/models/token_analysis_summary.py +0 -0
- {runta_sdk-0.2.3 → runta_sdk-0.2.4}/src/runta/_internal/openapi/models/token_analysis_tool_call.py +0 -0
- {runta_sdk-0.2.3 → runta_sdk-0.2.4}/src/runta/_internal/openapi/models/token_saving_event.py +0 -0
- {runta_sdk-0.2.3 → runta_sdk-0.2.4}/src/runta/_internal/openapi/models/token_saving_method.py +0 -0
- {runta_sdk-0.2.3 → runta_sdk-0.2.4}/src/runta/_internal/openapi/models/token_saving_method_method.py +0 -0
- {runta_sdk-0.2.3 → runta_sdk-0.2.4}/src/runta/_internal/openapi/models/token_savings_list.py +0 -0
- {runta_sdk-0.2.3 → runta_sdk-0.2.4}/src/runta/_internal/openapi/models/token_savings_list_response.py +0 -0
- {runta_sdk-0.2.3 → runta_sdk-0.2.4}/src/runta/_internal/openapi/models/token_savings_summary.py +0 -0
- {runta_sdk-0.2.3 → runta_sdk-0.2.4}/src/runta/_internal/openapi/models/update_cloud_agent_request.py +0 -0
- {runta_sdk-0.2.3 → runta_sdk-0.2.4}/src/runta/_internal/openapi/models/update_managed_model_provider_request.py +0 -0
- {runta_sdk-0.2.3 → runta_sdk-0.2.4}/src/runta/_internal/openapi/models/user_profile.py +0 -0
- {runta_sdk-0.2.3 → runta_sdk-0.2.4}/src/runta/_internal/openapi/models/user_profile_response.py +0 -0
- {runta_sdk-0.2.3 → runta_sdk-0.2.4}/src/runta/_internal/openapi/models/vnc_credential.py +0 -0
- {runta_sdk-0.2.3 → runta_sdk-0.2.4}/src/runta/_internal/openapi/models/vnc_credential_connection.py +0 -0
- {runta_sdk-0.2.3 → runta_sdk-0.2.4}/src/runta/_internal/openapi/models/vnc_credential_connection_security_type.py +0 -0
- {runta_sdk-0.2.3 → runta_sdk-0.2.4}/src/runta/_internal/openapi/models/vnc_credential_response.py +0 -0
- {runta_sdk-0.2.3 → runta_sdk-0.2.4}/src/runta/_internal/openapi/models/vnc_gateway_connection.py +0 -0
- {runta_sdk-0.2.3 → runta_sdk-0.2.4}/src/runta/_internal/openapi/models/vnc_gateway_connection_security_type.py +0 -0
- {runta_sdk-0.2.3 → runta_sdk-0.2.4}/src/runta/_internal/openapi/models/vnc_gateway_connection_username.py +0 -0
- {runta_sdk-0.2.3 → runta_sdk-0.2.4}/src/runta/_internal/openapi/types.py +0 -0
- {runta_sdk-0.2.3 → runta_sdk-0.2.4}/src/runta/_internal/pagination.py +0 -0
- {runta_sdk-0.2.3 → runta_sdk-0.2.4}/src/runta/_internal/rest_tls.py +0 -0
- {runta_sdk-0.2.3 → runta_sdk-0.2.4}/src/runta/_internal/retry.py +0 -0
- {runta_sdk-0.2.3 → runta_sdk-0.2.4}/src/runta/_internal/sync_http.py +0 -0
- {runta_sdk-0.2.3 → runta_sdk-0.2.4}/src/runta/_internal/tls_resumption.py +0 -0
- {runta_sdk-0.2.3 → runta_sdk-0.2.4}/src/runta/_internal/transport.py +0 -0
- {runta_sdk-0.2.3 → runta_sdk-0.2.4}/src/runta/_internal/user_agent.py +0 -0
- {runta_sdk-0.2.3 → runta_sdk-0.2.4}/src/runta/py.typed +0 -0
- {runta_sdk-0.2.3 → runta_sdk-0.2.4}/tests/test_api_reference_generation.py +0 -0
- {runta_sdk-0.2.3 → runta_sdk-0.2.4}/tests/test_async_file_io.py +0 -0
- {runta_sdk-0.2.3 → runta_sdk-0.2.4}/tests/test_async_http_transport.py +0 -0
- {runta_sdk-0.2.3 → runta_sdk-0.2.4}/tests/test_checkpoint_metadata.py +0 -0
- {runta_sdk-0.2.3 → runta_sdk-0.2.4}/tests/test_config_and_helpers.py +0 -0
- {runta_sdk-0.2.3 → runta_sdk-0.2.4}/tests/test_connection_pool.py +0 -0
- {runta_sdk-0.2.3 → runta_sdk-0.2.4}/tests/test_delete_runtime_retry.py +0 -0
- {runta_sdk-0.2.3 → runta_sdk-0.2.4}/tests/test_directory_upload.py +0 -0
- {runta_sdk-0.2.3 → runta_sdk-0.2.4}/tests/test_directory_upload_concurrency.py +0 -0
- {runta_sdk-0.2.3 → runta_sdk-0.2.4}/tests/test_download_dir_contents_live.py +0 -0
- {runta_sdk-0.2.3 → runta_sdk-0.2.4}/tests/test_execution.py +0 -0
- {runta_sdk-0.2.3 → runta_sdk-0.2.4}/tests/test_execution_result_stream.py +0 -0
- {runta_sdk-0.2.3 → runta_sdk-0.2.4}/tests/test_fetch_openapi.py +0 -0
- {runta_sdk-0.2.3 → runta_sdk-0.2.4}/tests/test_get_runtime_retry.py +0 -0
- {runta_sdk-0.2.3 → runta_sdk-0.2.4}/tests/test_harbor_directory_download.py +0 -0
- {runta_sdk-0.2.3 → runta_sdk-0.2.4}/tests/test_harbor_e2e.py +0 -0
- {runta_sdk-0.2.3 → runta_sdk-0.2.4}/tests/test_harbor_integration.py +0 -0
- {runta_sdk-0.2.3 → runta_sdk-0.2.4}/tests/test_harbor_runta_environment.py +0 -0
- {runta_sdk-0.2.3 → runta_sdk-0.2.4}/tests/test_live.py +0 -0
- {runta_sdk-0.2.3 → runta_sdk-0.2.4}/tests/test_openai_extra_packaging.py +0 -0
- {runta_sdk-0.2.3 → runta_sdk-0.2.4}/tests/test_openapi_contract.py +0 -0
- {runta_sdk-0.2.3 → runta_sdk-0.2.4}/tests/test_openapi_transport.py +0 -0
- {runta_sdk-0.2.3 → runta_sdk-0.2.4}/tests/test_read_retries.py +0 -0
- {runta_sdk-0.2.3 → runta_sdk-0.2.4}/tests/test_rest_deployment.py +0 -0
- {runta_sdk-0.2.3 → runta_sdk-0.2.4}/tests/test_rest_tls.py +0 -0
- {runta_sdk-0.2.3 → runta_sdk-0.2.4}/tests/test_retry_policy.py +0 -0
- {runta_sdk-0.2.3 → runta_sdk-0.2.4}/tests/test_runtime_readiness.py +0 -0
- {runta_sdk-0.2.3 → runta_sdk-0.2.4}/tests/test_streaming_transfer.py +0 -0
- {runta_sdk-0.2.3 → runta_sdk-0.2.4}/tests/test_user_agent.py +0 -0
- {runta_sdk-0.2.3 → runta_sdk-0.2.4}/tests/test_websocket_tls.py +0 -0
- {runta_sdk-0.2.3 → runta_sdk-0.2.4}/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.4
|
|
4
4
|
Summary: Python SDK for Runta runtime management
|
|
5
5
|
Author: Runta
|
|
6
6
|
License-Expression: MIT
|
|
@@ -158,8 +158,10 @@ example to ignore FIFOs and device nodes; by default these are rejected.
|
|
|
158
158
|
Permissions follow `tarfile.data_filter` (including removal of unsafe mode bits
|
|
159
159
|
and ownership). Safe links are preserved where supported; the standard library
|
|
160
160
|
copies archive referents when link creation is unavailable. Unresolvable dangling
|
|
161
|
-
symlinks are skipped on platforms that cannot create them
|
|
162
|
-
|
|
161
|
+
symlinks are skipped on platforms that cannot create them, preserving any
|
|
162
|
+
existing entry at that destination. The SDK uses native
|
|
163
|
+
filtered link fallback when available and provides a safe compatibility path on
|
|
164
|
+
older Python patch releases. A build without `tarfile.data_filter` still raises
|
|
163
165
|
an error rather than extracting unsafely. As with standard tar extraction, do not
|
|
164
166
|
allow another process to modify the destination concurrently during extraction.
|
|
165
167
|
|
|
@@ -130,8 +130,10 @@ example to ignore FIFOs and device nodes; by default these are rejected.
|
|
|
130
130
|
Permissions follow `tarfile.data_filter` (including removal of unsafe mode bits
|
|
131
131
|
and ownership). Safe links are preserved where supported; the standard library
|
|
132
132
|
copies archive referents when link creation is unavailable. Unresolvable dangling
|
|
133
|
-
symlinks are skipped on platforms that cannot create them
|
|
134
|
-
|
|
133
|
+
symlinks are skipped on platforms that cannot create them, preserving any
|
|
134
|
+
existing entry at that destination. The SDK uses native
|
|
135
|
+
filtered link fallback when available and provides a safe compatibility path on
|
|
136
|
+
older Python patch releases. A build without `tarfile.data_filter` still raises
|
|
135
137
|
an error rather than extracting unsafely. As with standard tar extraction, do not
|
|
136
138
|
allow another process to modify the destination concurrently during extraction.
|
|
137
139
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: runta-sdk
|
|
3
|
-
Version: 0.2.
|
|
3
|
+
Version: 0.2.4
|
|
4
4
|
Summary: Python SDK for Runta runtime management
|
|
5
5
|
Author: Runta
|
|
6
6
|
License-Expression: MIT
|
|
@@ -158,8 +158,10 @@ example to ignore FIFOs and device nodes; by default these are rejected.
|
|
|
158
158
|
Permissions follow `tarfile.data_filter` (including removal of unsafe mode bits
|
|
159
159
|
and ownership). Safe links are preserved where supported; the standard library
|
|
160
160
|
copies archive referents when link creation is unavailable. Unresolvable dangling
|
|
161
|
-
symlinks are skipped on platforms that cannot create them
|
|
162
|
-
|
|
161
|
+
symlinks are skipped on platforms that cannot create them, preserving any
|
|
162
|
+
existing entry at that destination. The SDK uses native
|
|
163
|
+
filtered link fallback when available and provides a safe compatibility path on
|
|
164
|
+
older Python patch releases. A build without `tarfile.data_filter` still raises
|
|
163
165
|
an error rather than extracting unsafely. As with standard tar extraction, do not
|
|
164
166
|
allow another process to modify the destination concurrently during extraction.
|
|
165
167
|
|
|
@@ -9,6 +9,7 @@ import errno
|
|
|
9
9
|
from contextlib import asynccontextmanager, contextmanager
|
|
10
10
|
import json
|
|
11
11
|
import os
|
|
12
|
+
import posixpath
|
|
12
13
|
import queue
|
|
13
14
|
import socket
|
|
14
15
|
import ssl
|
|
@@ -1146,9 +1147,82 @@ def _safe_relative_name(name: str) -> None:
|
|
|
1146
1147
|
raise tarfile.FilterError("download archive contains an unsafe path")
|
|
1147
1148
|
|
|
1148
1149
|
|
|
1150
|
+
@contextmanager
|
|
1151
|
+
def _preserve_link_destination(targetpath: str):
|
|
1152
|
+
"""Keep an existing entry when link creation/fallback produces no output."""
|
|
1153
|
+
target = Path(targetpath)
|
|
1154
|
+
if not os.path.lexists(target):
|
|
1155
|
+
yield
|
|
1156
|
+
return
|
|
1157
|
+
if target.is_dir():
|
|
1158
|
+
raise FileExistsError(
|
|
1159
|
+
f"download member conflicts with destination type: {target}"
|
|
1160
|
+
)
|
|
1161
|
+
# Move the entry, never copy its contents. The backup remains on the same
|
|
1162
|
+
# filesystem, and is restored before a skipped/failed link returns to tarfile.
|
|
1163
|
+
with tempfile.TemporaryDirectory(prefix=".runta-link-", dir=target.parent) as temp:
|
|
1164
|
+
original = Path(temp) / "original"
|
|
1165
|
+
os.replace(target, original)
|
|
1166
|
+
try:
|
|
1167
|
+
yield
|
|
1168
|
+
except BaseException:
|
|
1169
|
+
if not os.path.lexists(target):
|
|
1170
|
+
os.replace(original, target)
|
|
1171
|
+
raise
|
|
1172
|
+
if not os.path.lexists(target):
|
|
1173
|
+
os.replace(original, target)
|
|
1174
|
+
# Avoid tarfile applying hard-link attributes to the restored file
|
|
1175
|
+
# after a referent was excluded by the filter.
|
|
1176
|
+
raise tarfile.ExtractError("link fallback was skipped")
|
|
1177
|
+
|
|
1178
|
+
|
|
1149
1179
|
class _DirectoryMergeTarFile(tarfile.TarFile):
|
|
1150
1180
|
"""Replace file entries without writing through existing destination aliases."""
|
|
1151
1181
|
|
|
1182
|
+
merge_filter: Callable[[tarfile.TarInfo, str], tarfile.TarInfo | None]
|
|
1183
|
+
merge_root: str
|
|
1184
|
+
|
|
1185
|
+
def makelink_with_filter(
|
|
1186
|
+
self,
|
|
1187
|
+
tarinfo: tarfile.TarInfo,
|
|
1188
|
+
targetpath: str,
|
|
1189
|
+
filter_function=None,
|
|
1190
|
+
extraction_root=None,
|
|
1191
|
+
) -> None:
|
|
1192
|
+
if tarinfo.issym():
|
|
1193
|
+
# Windows symlink targets need native separators when stored in the
|
|
1194
|
+
# reparse point; archive references remain in POSIX form elsewhere.
|
|
1195
|
+
tarinfo = tarinfo.replace(
|
|
1196
|
+
linkname=os.path.normpath(tarinfo.linkname), deep=False
|
|
1197
|
+
)
|
|
1198
|
+
# Backports with this method differ: some filter the referent only,
|
|
1199
|
+
# while others also check its metadata at the copy destination.
|
|
1200
|
+
# Enforce both checks independently of the native implementation.
|
|
1201
|
+
filter_function = (
|
|
1202
|
+
self.merge_filter if filter_function is None else filter_function
|
|
1203
|
+
)
|
|
1204
|
+
extraction_root = (
|
|
1205
|
+
self.merge_root if extraction_root is None else extraction_root
|
|
1206
|
+
)
|
|
1207
|
+
actual_name = os.path.relpath(targetpath, extraction_root).replace(os.sep, "/")
|
|
1208
|
+
|
|
1209
|
+
def guarded_filter(member, destination):
|
|
1210
|
+
filtered = filter_function(member, destination)
|
|
1211
|
+
if filtered is not None:
|
|
1212
|
+
_filter_contents_member(
|
|
1213
|
+
filtered.replace(name=actual_name, deep=False),
|
|
1214
|
+
destination,
|
|
1215
|
+
)
|
|
1216
|
+
return filtered
|
|
1217
|
+
|
|
1218
|
+
with _preserve_link_destination(targetpath):
|
|
1219
|
+
super().makelink_with_filter(
|
|
1220
|
+
tarinfo,
|
|
1221
|
+
targetpath,
|
|
1222
|
+
guarded_filter,
|
|
1223
|
+
extraction_root,
|
|
1224
|
+
)
|
|
1225
|
+
|
|
1152
1226
|
def makefile(self, tarinfo: tarfile.TarInfo, targetpath: str) -> None:
|
|
1153
1227
|
# Do this at the actual write path, after filtering. A filter can also
|
|
1154
1228
|
# run for a link fallback's referent, whose path must remain untouched.
|
|
@@ -1161,20 +1235,145 @@ class _DirectoryMergeTarFile(tarfile.TarFile):
|
|
|
1161
1235
|
super().makefile(tarinfo, targetpath)
|
|
1162
1236
|
|
|
1163
1237
|
|
|
1238
|
+
class _LegacyDirectoryMergeTarFile(_DirectoryMergeTarFile):
|
|
1239
|
+
"""Supply filtered link fallback when the interpreter does not provide it."""
|
|
1240
|
+
|
|
1241
|
+
def makelink(self, tarinfo: tarfile.TarInfo, targetpath: str) -> None:
|
|
1242
|
+
with _preserve_link_destination(targetpath):
|
|
1243
|
+
self._make_compat_link(tarinfo, targetpath)
|
|
1244
|
+
|
|
1245
|
+
def _make_compat_link(self, tarinfo: tarfile.TarInfo, targetpath: str) -> None:
|
|
1246
|
+
try:
|
|
1247
|
+
if tarinfo.issym():
|
|
1248
|
+
Path(targetpath).unlink(missing_ok=True)
|
|
1249
|
+
os.symlink(os.path.normpath(tarinfo.linkname), targetpath)
|
|
1250
|
+
return
|
|
1251
|
+
source = os.path.join(self.merge_root, tarinfo.linkname)
|
|
1252
|
+
if os.path.exists(source):
|
|
1253
|
+
Path(targetpath).unlink(missing_ok=True)
|
|
1254
|
+
os.link(source, targetpath)
|
|
1255
|
+
return
|
|
1256
|
+
except (AttributeError, NotImplementedError, OSError):
|
|
1257
|
+
pass
|
|
1258
|
+
|
|
1259
|
+
try:
|
|
1260
|
+
referent = self._find_link_target(tarinfo)
|
|
1261
|
+
except KeyError:
|
|
1262
|
+
if tarinfo.issym():
|
|
1263
|
+
# Match tarfile's nonfatal treatment of an unsupported dangling
|
|
1264
|
+
# symlink, without suppressing filter or I/O errors.
|
|
1265
|
+
raise tarfile.ExtractError(
|
|
1266
|
+
"unable to resolve link inside archive"
|
|
1267
|
+
) from None
|
|
1268
|
+
raise tarfile.FilterError(
|
|
1269
|
+
"hard link target is missing from the archive"
|
|
1270
|
+
) from None
|
|
1271
|
+
|
|
1272
|
+
# The original archive name is needed for further link lookup. Validate
|
|
1273
|
+
# that location through the user filter, then independently validate the
|
|
1274
|
+
# filtered metadata at the actual write path without invoking user code.
|
|
1275
|
+
filtered = self.merge_filter(referent, self.merge_root)
|
|
1276
|
+
if filtered is None:
|
|
1277
|
+
return
|
|
1278
|
+
actual_name = os.path.relpath(targetpath, self.merge_root).replace(os.sep, "/")
|
|
1279
|
+
relocated = _filter_contents_member(
|
|
1280
|
+
filtered.replace(name=actual_name, deep=False),
|
|
1281
|
+
self.merge_root,
|
|
1282
|
+
)
|
|
1283
|
+
filtered = relocated.replace(name=filtered.name, deep=False)
|
|
1284
|
+
|
|
1285
|
+
# Recursive aliases can otherwise recurse indefinitely on old tarfile.
|
|
1286
|
+
active = getattr(self, "_active_link_fallbacks", set())
|
|
1287
|
+
key = (referent.offset, os.path.abspath(targetpath))
|
|
1288
|
+
if key in active:
|
|
1289
|
+
raise tarfile.FilterError(
|
|
1290
|
+
"download archive contains a cyclic link fallback"
|
|
1291
|
+
)
|
|
1292
|
+
self._active_link_fallbacks = active
|
|
1293
|
+
active.add(key)
|
|
1294
|
+
try:
|
|
1295
|
+
# Reuse the seekable tar's file reader and the existing makefile
|
|
1296
|
+
# replacement semantics; no separate link-copy implementation.
|
|
1297
|
+
self._extract_member(filtered, targetpath)
|
|
1298
|
+
finally:
|
|
1299
|
+
active.remove(key)
|
|
1300
|
+
|
|
1301
|
+
def makelink_with_filter(
|
|
1302
|
+
self,
|
|
1303
|
+
tarinfo: tarfile.TarInfo,
|
|
1304
|
+
targetpath: str,
|
|
1305
|
+
filter_function=None,
|
|
1306
|
+
extraction_root=None,
|
|
1307
|
+
) -> None:
|
|
1308
|
+
# Some vendor builds use the newer dispatcher without a usable native
|
|
1309
|
+
# implementation. Both dispatchers must enter the same guarded path.
|
|
1310
|
+
self.makelink(tarinfo, targetpath)
|
|
1311
|
+
|
|
1312
|
+
|
|
1313
|
+
def _filter_contents_member(
|
|
1314
|
+
member: tarfile.TarInfo,
|
|
1315
|
+
destination: str,
|
|
1316
|
+
*,
|
|
1317
|
+
allow_special: bool = False,
|
|
1318
|
+
) -> tarfile.TarInfo:
|
|
1319
|
+
"""Mandatory checks, also applied at the physical link-copy destination."""
|
|
1320
|
+
_safe_relative_name(member.name)
|
|
1321
|
+
if PurePosixPath(member.name) == PurePosixPath("."):
|
|
1322
|
+
raise tarfile.FilterError("a filter cannot replace the destination root")
|
|
1323
|
+
if member.issym() or member.islnk():
|
|
1324
|
+
link = member.linkname.replace(os.sep, "/")
|
|
1325
|
+
if (
|
|
1326
|
+
PurePosixPath(link).is_absolute()
|
|
1327
|
+
or PureWindowsPath(link).drive
|
|
1328
|
+
or "\\" in link
|
|
1329
|
+
or ":" in link
|
|
1330
|
+
or "\x00" in link
|
|
1331
|
+
):
|
|
1332
|
+
raise tarfile.FilterError("download archive contains an unsafe link")
|
|
1333
|
+
# Match patched data_filter: collapse internal '..' components before
|
|
1334
|
+
# checking/creating a link. Otherwise a later archive symlink can change
|
|
1335
|
+
# the meaning of a previously accepted dangling link on old Python.
|
|
1336
|
+
member = member.replace(linkname=posixpath.normpath(link), deep=False)
|
|
1337
|
+
if member.isdev() and allow_special:
|
|
1338
|
+
member = copy.copy(member)
|
|
1339
|
+
member.type = tarfile.REGTYPE
|
|
1340
|
+
elif not (member.isreg() or member.isdir() or member.issym() or member.islnk()):
|
|
1341
|
+
# Older data_filter implementations can overlook special files with
|
|
1342
|
+
# mode=None. A callback must not be able to bypass this boundary.
|
|
1343
|
+
raise tarfile.SpecialFileError(member)
|
|
1344
|
+
member = tarfile.data_filter(member, destination)
|
|
1345
|
+
if (member.issym() or member.islnk()) and os.sep != "/":
|
|
1346
|
+
# Keep archive link references in POSIX form even when a native filter
|
|
1347
|
+
# returns Windows separators, so a later fallback can validate them too.
|
|
1348
|
+
member = member.replace(
|
|
1349
|
+
linkname=member.linkname.replace(os.sep, "/"), deep=False
|
|
1350
|
+
)
|
|
1351
|
+
target = Path(destination) / member.name
|
|
1352
|
+
if not allow_special and target.exists() and target.is_dir() != member.isdir():
|
|
1353
|
+
raise FileExistsError(
|
|
1354
|
+
f"download member conflicts with destination type: {target}"
|
|
1355
|
+
)
|
|
1356
|
+
return member
|
|
1357
|
+
|
|
1358
|
+
|
|
1164
1359
|
def _extract_dir_contents(
|
|
1165
1360
|
archive_path: Path,
|
|
1166
1361
|
dst: Path,
|
|
1167
1362
|
filter: Callable[[tarfile.TarInfo, str], tarfile.TarInfo | None] | None = None,
|
|
1168
1363
|
) -> None:
|
|
1169
1364
|
data_filter = getattr(tarfile, "data_filter", None)
|
|
1170
|
-
if data_filter is None
|
|
1365
|
+
if data_filter is None:
|
|
1171
1366
|
raise RuntimeError(
|
|
1172
|
-
"directory content downloads require a
|
|
1173
|
-
"with tarfile.data_filter and filtered link fallback"
|
|
1367
|
+
"directory content downloads require a Python build with tarfile.data_filter"
|
|
1174
1368
|
)
|
|
1175
1369
|
if dst.is_symlink():
|
|
1176
1370
|
raise tarfile.FilterError("download destination must not be a symbolic link")
|
|
1177
|
-
|
|
1371
|
+
archive_type = (
|
|
1372
|
+
_DirectoryMergeTarFile
|
|
1373
|
+
if callable(getattr(tarfile.TarFile, "makelink_with_filter", None))
|
|
1374
|
+
else _LegacyDirectoryMergeTarFile
|
|
1375
|
+
)
|
|
1376
|
+
with archive_type.open(archive_path, "r:", errorlevel=1) as archive:
|
|
1178
1377
|
members = archive.getmembers()
|
|
1179
1378
|
if not members or members[0].name not in {".", "./"} or not members[0].isdir():
|
|
1180
1379
|
raise _public.ApiError(
|
|
@@ -1211,53 +1410,17 @@ def _extract_dir_contents(
|
|
|
1211
1410
|
) -> tarfile.TarInfo | None:
|
|
1212
1411
|
if member.name == ".":
|
|
1213
1412
|
return None # Do not apply the source root's metadata to dst.
|
|
1214
|
-
|
|
1215
|
-
#
|
|
1216
|
-
|
|
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)
|
|
1413
|
+
# Allow callbacks to skip special files, but validate all paths
|
|
1414
|
+
# and link targets before and after user code.
|
|
1415
|
+
_filter_contents_member(member, destination, allow_special=True)
|
|
1233
1416
|
if filter is not None:
|
|
1234
1417
|
member = filter(copy.copy(member), destination)
|
|
1235
1418
|
if member is None:
|
|
1236
1419
|
return None
|
|
1237
|
-
|
|
1238
|
-
|
|
1239
|
-
|
|
1240
|
-
|
|
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
|
|
1420
|
+
return _filter_contents_member(member, destination)
|
|
1421
|
+
|
|
1422
|
+
archive.merge_filter = safe_filter
|
|
1423
|
+
archive.merge_root = os.fspath(dst)
|
|
1261
1424
|
|
|
1262
1425
|
# errorlevel=1 (the default) propagates security/I/O failures while
|
|
1263
1426
|
# allowing stdlib's nonfatal unresolved-link fallback to skip a link.
|
|
@@ -16,6 +16,23 @@ from runta._internal import streaming_transfer as transfer
|
|
|
16
16
|
from runta._internal.async_file_io import _AsyncFileIO
|
|
17
17
|
|
|
18
18
|
|
|
19
|
+
@pytest.fixture(
|
|
20
|
+
autouse=True,
|
|
21
|
+
params=(
|
|
22
|
+
["native", "compat"]
|
|
23
|
+
if callable(getattr(tarfile.TarFile, "makelink_with_filter", None))
|
|
24
|
+
else ["compat"]
|
|
25
|
+
),
|
|
26
|
+
)
|
|
27
|
+
def link_fallback_capability(request, monkeypatch):
|
|
28
|
+
"""Exercise fallback selection on patched hosts as well as real old Python."""
|
|
29
|
+
if request.param == "compat":
|
|
30
|
+
monkeypatch.setattr(
|
|
31
|
+
tarfile.TarFile, "makelink_with_filter", None, raising=False
|
|
32
|
+
)
|
|
33
|
+
return request.param
|
|
34
|
+
|
|
35
|
+
|
|
19
36
|
def make_archive(path, entries=()):
|
|
20
37
|
"""Entries are (name, data/type, linkname), rooted at the remote tar's '.'."""
|
|
21
38
|
with tarfile.open(path, "w") as archive:
|
|
@@ -98,7 +115,8 @@ async def test_transfer_merges_and_cleans(tmp_path, monkeypatch, asynchronous, e
|
|
|
98
115
|
assert all(not path.parent.exists() for path in paths)
|
|
99
116
|
|
|
100
117
|
|
|
101
|
-
|
|
118
|
+
@pytest.mark.parametrize("filter", [None, tarfile.data_filter])
|
|
119
|
+
def test_permissions_and_links(tmp_path, filter):
|
|
102
120
|
target = extract(
|
|
103
121
|
tmp_path,
|
|
104
122
|
[
|
|
@@ -107,6 +125,7 @@ def test_permissions_and_links(tmp_path):
|
|
|
107
125
|
("./nested/sym", tarfile.SYMTYPE, "../data"),
|
|
108
126
|
("./hard", tarfile.LNKTYPE, "./data"),
|
|
109
127
|
],
|
|
128
|
+
filter,
|
|
110
129
|
)
|
|
111
130
|
assert (target / "nested/sym").is_symlink()
|
|
112
131
|
assert (target / "nested/sym").read_bytes() == b"payload"
|
|
@@ -385,7 +404,7 @@ def test_remote_command_resolves_top_directory_and_quotes(tmp_path, symlink):
|
|
|
385
404
|
|
|
386
405
|
def test_missing_security_support_fails_closed(tmp_path, monkeypatch):
|
|
387
406
|
monkeypatch.delattr(tarfile, "data_filter")
|
|
388
|
-
with pytest.raises(RuntimeError, match="
|
|
407
|
+
with pytest.raises(RuntimeError, match="tarfile.data_filter"):
|
|
389
408
|
extract(tmp_path, [("./data", b"payload", "")])
|
|
390
409
|
assert not (tmp_path / "target").exists()
|
|
391
410
|
|
|
@@ -539,3 +558,253 @@ def test_skipped_member_preserves_existing_alias(tmp_path):
|
|
|
539
558
|
extract(tmp_path, [("./replace", b"new", "")], skip)
|
|
540
559
|
assert (target / "replace").is_symlink()
|
|
541
560
|
assert (target / "keep").read_bytes() == b"original"
|
|
561
|
+
|
|
562
|
+
|
|
563
|
+
@pytest.mark.parametrize("rename_referent", [False, True])
|
|
564
|
+
def test_link_fallback_filters_referent_at_actual_destination(
|
|
565
|
+
tmp_path, monkeypatch, rename_referent
|
|
566
|
+
):
|
|
567
|
+
outside = tmp_path / "safe"
|
|
568
|
+
outside.write_text("outside")
|
|
569
|
+
real_symlink = os.symlink
|
|
570
|
+
|
|
571
|
+
def fail_alias(link, destination, *args, **kwargs):
|
|
572
|
+
if os.path.normpath(link) == os.path.normpath("deep/ref"):
|
|
573
|
+
raise OSError("force alias to copy its referent")
|
|
574
|
+
return real_symlink(link, destination, *args, **kwargs)
|
|
575
|
+
|
|
576
|
+
def callback(member, destination):
|
|
577
|
+
if rename_referent and member.name == "deep/ref":
|
|
578
|
+
return member.replace(name="deep/renamed")
|
|
579
|
+
return member
|
|
580
|
+
|
|
581
|
+
monkeypatch.setattr(os, "symlink", fail_alias)
|
|
582
|
+
with pytest.raises(tarfile.FilterError):
|
|
583
|
+
extract(
|
|
584
|
+
tmp_path,
|
|
585
|
+
[
|
|
586
|
+
("./safe", b"inside", ""),
|
|
587
|
+
("./deep/ref", tarfile.SYMTYPE, "../safe"),
|
|
588
|
+
("./alias", tarfile.SYMTYPE, "deep/ref"),
|
|
589
|
+
],
|
|
590
|
+
callback,
|
|
591
|
+
)
|
|
592
|
+
assert outside.read_text() == "outside"
|
|
593
|
+
assert not os.path.lexists(tmp_path / "target/alias")
|
|
594
|
+
|
|
595
|
+
|
|
596
|
+
def test_later_link_cannot_turn_an_accepted_link_into_an_escape(tmp_path):
|
|
597
|
+
target = extract(
|
|
598
|
+
tmp_path,
|
|
599
|
+
[
|
|
600
|
+
("./alias", tarfile.SYMTYPE, "directory/../outside"),
|
|
601
|
+
("./directory", tarfile.SYMTYPE, "."),
|
|
602
|
+
],
|
|
603
|
+
)
|
|
604
|
+
assert (target / "alias").is_symlink()
|
|
605
|
+
assert (target / "alias").resolve() == target / "outside"
|
|
606
|
+
|
|
607
|
+
|
|
608
|
+
def test_callback_cannot_enable_special_files_with_missing_mode(tmp_path):
|
|
609
|
+
def callback(member, destination):
|
|
610
|
+
member.mode = None
|
|
611
|
+
return member
|
|
612
|
+
|
|
613
|
+
with pytest.raises(tarfile.SpecialFileError):
|
|
614
|
+
extract(tmp_path, [("./fifo", tarfile.FIFOTYPE, "")], callback)
|
|
615
|
+
assert not (tmp_path / "target/fifo").exists()
|
|
616
|
+
|
|
617
|
+
|
|
618
|
+
def test_compat_rejects_cyclic_link_copy(tmp_path, monkeypatch):
|
|
619
|
+
monkeypatch.setattr(tarfile.TarFile, "makelink_with_filter", None, raising=False)
|
|
620
|
+
|
|
621
|
+
def unavailable(*args, **kwargs):
|
|
622
|
+
raise OSError("links prohibited")
|
|
623
|
+
|
|
624
|
+
monkeypatch.setattr(os, "symlink", unavailable)
|
|
625
|
+
with pytest.raises(tarfile.FilterError, match="cyclic"):
|
|
626
|
+
extract(
|
|
627
|
+
tmp_path,
|
|
628
|
+
[
|
|
629
|
+
("./a", tarfile.SYMTYPE, "b"),
|
|
630
|
+
("./b", tarfile.SYMTYPE, "a"),
|
|
631
|
+
],
|
|
632
|
+
)
|
|
633
|
+
assert not (tmp_path / "target/a").exists()
|
|
634
|
+
assert not (tmp_path / "target/b").exists()
|
|
635
|
+
|
|
636
|
+
|
|
637
|
+
@pytest.mark.parametrize("alias", ["file", "symlink", "hardlink", "dangling"])
|
|
638
|
+
def test_unsupported_dangling_link_preserves_existing_destination(
|
|
639
|
+
tmp_path, monkeypatch, alias
|
|
640
|
+
):
|
|
641
|
+
target = tmp_path / "target"
|
|
642
|
+
target.mkdir()
|
|
643
|
+
keep = target / "keep"
|
|
644
|
+
keep.write_bytes(b"keep")
|
|
645
|
+
report = target / "report"
|
|
646
|
+
if alias == "file":
|
|
647
|
+
report.write_bytes(b"original")
|
|
648
|
+
elif alias == "hardlink":
|
|
649
|
+
os.link(keep, report)
|
|
650
|
+
else:
|
|
651
|
+
report.symlink_to("old-missing" if alias == "dangling" else "keep")
|
|
652
|
+
original_stat = report.lstat()
|
|
653
|
+
|
|
654
|
+
def unavailable(*args, **kwargs):
|
|
655
|
+
raise OSError("links prohibited")
|
|
656
|
+
|
|
657
|
+
monkeypatch.setattr(os, "symlink", unavailable)
|
|
658
|
+
extract(
|
|
659
|
+
tmp_path,
|
|
660
|
+
[
|
|
661
|
+
("./report", tarfile.SYMTYPE, "new-missing"),
|
|
662
|
+
("./last", b"last", ""),
|
|
663
|
+
],
|
|
664
|
+
)
|
|
665
|
+
assert os.path.lexists(report)
|
|
666
|
+
assert report.lstat().st_mode == original_stat.st_mode
|
|
667
|
+
assert keep.read_bytes() == b"keep"
|
|
668
|
+
if alias == "file":
|
|
669
|
+
assert report.read_bytes() == b"original"
|
|
670
|
+
elif alias == "hardlink":
|
|
671
|
+
assert os.path.samefile(keep, report)
|
|
672
|
+
else:
|
|
673
|
+
assert os.readlink(report) == ("old-missing" if alias == "dangling" else "keep")
|
|
674
|
+
assert (target / "last").read_bytes() == b"last"
|
|
675
|
+
assert not list(target.glob(".runta-link-*"))
|
|
676
|
+
|
|
677
|
+
|
|
678
|
+
def test_filtered_fallback_preserves_existing_destination_metadata(
|
|
679
|
+
tmp_path, monkeypatch
|
|
680
|
+
):
|
|
681
|
+
target = tmp_path / "target"
|
|
682
|
+
target.mkdir()
|
|
683
|
+
report = target / "report"
|
|
684
|
+
report.write_bytes(b"original")
|
|
685
|
+
report.chmod(0o600)
|
|
686
|
+
before = report.stat()
|
|
687
|
+
|
|
688
|
+
def unavailable(*args, **kwargs):
|
|
689
|
+
raise OSError("links prohibited")
|
|
690
|
+
|
|
691
|
+
def skip_referent(member, destination):
|
|
692
|
+
return None if member.name == "data" else member
|
|
693
|
+
|
|
694
|
+
monkeypatch.setattr(os, "link", unavailable)
|
|
695
|
+
extract(
|
|
696
|
+
tmp_path,
|
|
697
|
+
[
|
|
698
|
+
("./data", b"new", ""),
|
|
699
|
+
("./report", tarfile.LNKTYPE, "./data"),
|
|
700
|
+
("./last", b"last", ""),
|
|
701
|
+
],
|
|
702
|
+
skip_referent,
|
|
703
|
+
)
|
|
704
|
+
assert report.read_bytes() == b"original"
|
|
705
|
+
assert report.stat().st_mode == before.st_mode
|
|
706
|
+
assert report.stat().st_mtime_ns == before.st_mtime_ns
|
|
707
|
+
assert (target / "last").read_bytes() == b"last"
|
|
708
|
+
assert not list(target.glob(".runta-link-*"))
|
|
709
|
+
|
|
710
|
+
|
|
711
|
+
@pytest.mark.parametrize("fault", ["filter", "copy"])
|
|
712
|
+
def test_link_fallback_failure_restores_existing_destination(
|
|
713
|
+
tmp_path, monkeypatch, fault
|
|
714
|
+
):
|
|
715
|
+
target = tmp_path / "target"
|
|
716
|
+
target.mkdir()
|
|
717
|
+
report = target / "report"
|
|
718
|
+
report.write_bytes(b"original")
|
|
719
|
+
|
|
720
|
+
def unavailable(*args, **kwargs):
|
|
721
|
+
raise OSError("links prohibited")
|
|
722
|
+
|
|
723
|
+
def callback(member, destination):
|
|
724
|
+
if fault == "filter" and member.name == "data":
|
|
725
|
+
raise ValueError("injected failure")
|
|
726
|
+
return member
|
|
727
|
+
|
|
728
|
+
def failed_copy(*args, **kwargs):
|
|
729
|
+
raise OSError("injected failure")
|
|
730
|
+
|
|
731
|
+
monkeypatch.setattr(os, "symlink", unavailable)
|
|
732
|
+
if fault == "copy":
|
|
733
|
+
monkeypatch.setattr(transfer._DirectoryMergeTarFile, "makefile", failed_copy)
|
|
734
|
+
with pytest.raises(
|
|
735
|
+
ValueError if fault == "filter" else OSError, match="injected failure"
|
|
736
|
+
):
|
|
737
|
+
extract(
|
|
738
|
+
tmp_path,
|
|
739
|
+
[
|
|
740
|
+
("./report", tarfile.SYMTYPE, "data"),
|
|
741
|
+
("./data", b"new", ""),
|
|
742
|
+
],
|
|
743
|
+
callback,
|
|
744
|
+
)
|
|
745
|
+
assert report.read_bytes() == b"original"
|
|
746
|
+
assert not list(target.glob(".runta-link-*"))
|
|
747
|
+
|
|
748
|
+
|
|
749
|
+
@pytest.mark.asyncio
|
|
750
|
+
async def test_cancel_drains_link_replacement_before_restoring_and_cleaning(
|
|
751
|
+
tmp_path, monkeypatch
|
|
752
|
+
):
|
|
753
|
+
target = tmp_path / "target"
|
|
754
|
+
target.mkdir()
|
|
755
|
+
report = target / "report"
|
|
756
|
+
report.write_bytes(b"original")
|
|
757
|
+
entered = threading.Event()
|
|
758
|
+
release = threading.Event()
|
|
759
|
+
archives = []
|
|
760
|
+
|
|
761
|
+
async def download(*args, **kwargs):
|
|
762
|
+
archives.append(args[4])
|
|
763
|
+
await kwargs["_file_io"].run(
|
|
764
|
+
make_archive,
|
|
765
|
+
args[4],
|
|
766
|
+
[
|
|
767
|
+
("./report", tarfile.SYMTYPE, "missing"),
|
|
768
|
+
("./data", b"payload", ""),
|
|
769
|
+
],
|
|
770
|
+
)
|
|
771
|
+
|
|
772
|
+
def unavailable(*args, **kwargs):
|
|
773
|
+
entered.set()
|
|
774
|
+
assert release.wait(5)
|
|
775
|
+
raise OSError("links prohibited")
|
|
776
|
+
|
|
777
|
+
monkeypatch.setattr(transfer, "_async_download_archive", download)
|
|
778
|
+
monkeypatch.setattr(os, "symlink", unavailable)
|
|
779
|
+
task = asyncio.create_task(
|
|
780
|
+
transfer.async_download_dir_contents(
|
|
781
|
+
"http://test",
|
|
782
|
+
"token",
|
|
783
|
+
"runtime",
|
|
784
|
+
"/src",
|
|
785
|
+
target,
|
|
786
|
+
timeout=1,
|
|
787
|
+
)
|
|
788
|
+
)
|
|
789
|
+
try:
|
|
790
|
+
|
|
791
|
+
async def wait_entered():
|
|
792
|
+
while not entered.is_set():
|
|
793
|
+
await asyncio.sleep(0)
|
|
794
|
+
|
|
795
|
+
await asyncio.wait_for(wait_entered(), 5)
|
|
796
|
+
task.cancel()
|
|
797
|
+
await asyncio.sleep(0)
|
|
798
|
+
task.cancel()
|
|
799
|
+
await asyncio.sleep(0)
|
|
800
|
+
assert not task.done()
|
|
801
|
+
assert archives[0].exists()
|
|
802
|
+
assert list(target.glob(".runta-link-*"))
|
|
803
|
+
finally:
|
|
804
|
+
release.set()
|
|
805
|
+
with pytest.raises(asyncio.CancelledError):
|
|
806
|
+
await task
|
|
807
|
+
assert report.read_bytes() == b"original"
|
|
808
|
+
assert (target / "data").read_bytes() == b"payload"
|
|
809
|
+
assert not list(target.glob(".runta-link-*"))
|
|
810
|
+
assert not archives[0].parent.exists()
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{runta_sdk-0.2.3 → runta_sdk-0.2.4}/integrations/openai-agents-runta/src/agents_runta/__init__.py
RENAMED
|
File without changes
|
|
File without changes
|