runloop-api-client 0.60.0__tar.gz → 0.60.1__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.
- runloop_api_client-0.60.1/.release-please-manifest.json +3 -0
- {runloop_api_client-0.60.0 → runloop_api_client-0.60.1}/CHANGELOG.md +4 -0
- {runloop_api_client-0.60.0 → runloop_api_client-0.60.1}/PKG-INFO +8 -8
- {runloop_api_client-0.60.0 → runloop_api_client-0.60.1}/pyproject.toml +10 -8
- {runloop_api_client-0.60.0 → runloop_api_client-0.60.1}/requirements-dev.lock +4 -2
- {runloop_api_client-0.60.0 → runloop_api_client-0.60.1}/requirements.lock +2 -0
- {runloop_api_client-0.60.0 → runloop_api_client-0.60.1}/src/runloop_api_client/_models.py +1 -1
- {runloop_api_client-0.60.0 → runloop_api_client-0.60.1}/src/runloop_api_client/_version.py +1 -1
- {runloop_api_client-0.60.0 → runloop_api_client-0.60.1}/src/runloop_api_client/resources/devboxes/devboxes.py +110 -0
- {runloop_api_client-0.60.0 → runloop_api_client-0.60.1}/tests/smoketests/README.md +5 -4
- runloop_api_client-0.60.1/tests/smoketests/conftest.py +38 -0
- {runloop_api_client-0.60.0 → runloop_api_client-0.60.1}/tests/smoketests/test_blueprints.py +18 -14
- {runloop_api_client-0.60.0 → runloop_api_client-0.60.1}/tests/smoketests/test_devboxes.py +23 -9
- runloop_api_client-0.60.1/tests/smoketests/test_executions.py +101 -0
- {runloop_api_client-0.60.0 → runloop_api_client-0.60.1}/tests/smoketests/test_scenarios_benchmarks.py +19 -15
- {runloop_api_client-0.60.0 → runloop_api_client-0.60.1}/tests/smoketests/test_snapshots.py +17 -4
- runloop_api_client-0.60.1/tests/smoketests/utils.py +128 -0
- runloop_api_client-0.60.1/uv.lock +943 -0
- runloop_api_client-0.60.0/.release-please-manifest.json +0 -3
- runloop_api_client-0.60.0/tests/smoketests/test_executions.py +0 -63
- runloop_api_client-0.60.0/tests/smoketests/utils.py +0 -34
- runloop_api_client-0.60.0/uv.lock +0 -1533
- {runloop_api_client-0.60.0 → runloop_api_client-0.60.1}/.gitignore +0 -0
- {runloop_api_client-0.60.0 → runloop_api_client-0.60.1}/CONTRIBUTING.md +0 -0
- {runloop_api_client-0.60.0 → runloop_api_client-0.60.1}/LICENSE +0 -0
- {runloop_api_client-0.60.0 → runloop_api_client-0.60.1}/README.md +0 -0
- {runloop_api_client-0.60.0 → runloop_api_client-0.60.1}/SECURITY.md +0 -0
- {runloop_api_client-0.60.0 → runloop_api_client-0.60.1}/api.md +0 -0
- {runloop_api_client-0.60.0 → runloop_api_client-0.60.1}/bin/check-release-environment +0 -0
- {runloop_api_client-0.60.0 → runloop_api_client-0.60.1}/bin/publish-pypi +0 -0
- {runloop_api_client-0.60.0 → runloop_api_client-0.60.1}/examples/.keep +0 -0
- {runloop_api_client-0.60.0 → runloop_api_client-0.60.1}/noxfile.py +0 -0
- {runloop_api_client-0.60.0 → runloop_api_client-0.60.1}/release-please-config.json +0 -0
- {runloop_api_client-0.60.0 → runloop_api_client-0.60.1}/src/runloop/lib/.keep +0 -0
- {runloop_api_client-0.60.0 → runloop_api_client-0.60.1}/src/runloop_api_client/__init__.py +0 -0
- {runloop_api_client-0.60.0 → runloop_api_client-0.60.1}/src/runloop_api_client/_base_client.py +0 -0
- {runloop_api_client-0.60.0 → runloop_api_client-0.60.1}/src/runloop_api_client/_client.py +0 -0
- {runloop_api_client-0.60.0 → runloop_api_client-0.60.1}/src/runloop_api_client/_compat.py +0 -0
- {runloop_api_client-0.60.0 → runloop_api_client-0.60.1}/src/runloop_api_client/_constants.py +0 -0
- {runloop_api_client-0.60.0 → runloop_api_client-0.60.1}/src/runloop_api_client/_exceptions.py +0 -0
- {runloop_api_client-0.60.0 → runloop_api_client-0.60.1}/src/runloop_api_client/_files.py +0 -0
- {runloop_api_client-0.60.0 → runloop_api_client-0.60.1}/src/runloop_api_client/_qs.py +0 -0
- {runloop_api_client-0.60.0 → runloop_api_client-0.60.1}/src/runloop_api_client/_resource.py +0 -0
- {runloop_api_client-0.60.0 → runloop_api_client-0.60.1}/src/runloop_api_client/_response.py +0 -0
- {runloop_api_client-0.60.0 → runloop_api_client-0.60.1}/src/runloop_api_client/_streaming.py +0 -0
- {runloop_api_client-0.60.0 → runloop_api_client-0.60.1}/src/runloop_api_client/_types.py +0 -0
- {runloop_api_client-0.60.0 → runloop_api_client-0.60.1}/src/runloop_api_client/_utils/__init__.py +0 -0
- {runloop_api_client-0.60.0 → runloop_api_client-0.60.1}/src/runloop_api_client/_utils/_compat.py +0 -0
- {runloop_api_client-0.60.0 → runloop_api_client-0.60.1}/src/runloop_api_client/_utils/_datetime_parse.py +0 -0
- {runloop_api_client-0.60.0 → runloop_api_client-0.60.1}/src/runloop_api_client/_utils/_logs.py +0 -0
- {runloop_api_client-0.60.0 → runloop_api_client-0.60.1}/src/runloop_api_client/_utils/_proxy.py +0 -0
- {runloop_api_client-0.60.0 → runloop_api_client-0.60.1}/src/runloop_api_client/_utils/_reflection.py +0 -0
- {runloop_api_client-0.60.0 → runloop_api_client-0.60.1}/src/runloop_api_client/_utils/_resources_proxy.py +0 -0
- {runloop_api_client-0.60.0 → runloop_api_client-0.60.1}/src/runloop_api_client/_utils/_streams.py +0 -0
- {runloop_api_client-0.60.0 → runloop_api_client-0.60.1}/src/runloop_api_client/_utils/_sync.py +0 -0
- {runloop_api_client-0.60.0 → runloop_api_client-0.60.1}/src/runloop_api_client/_utils/_transform.py +0 -0
- {runloop_api_client-0.60.0 → runloop_api_client-0.60.1}/src/runloop_api_client/_utils/_typing.py +0 -0
- {runloop_api_client-0.60.0 → runloop_api_client-0.60.1}/src/runloop_api_client/_utils/_utils.py +0 -0
- {runloop_api_client-0.60.0 → runloop_api_client-0.60.1}/src/runloop_api_client/lib/.keep +0 -0
- {runloop_api_client-0.60.0 → runloop_api_client-0.60.1}/src/runloop_api_client/lib/polling.py +0 -0
- {runloop_api_client-0.60.0 → runloop_api_client-0.60.1}/src/runloop_api_client/lib/polling_async.py +0 -0
- {runloop_api_client-0.60.0 → runloop_api_client-0.60.1}/src/runloop_api_client/pagination.py +0 -0
- {runloop_api_client-0.60.0 → runloop_api_client-0.60.1}/src/runloop_api_client/py.typed +0 -0
- {runloop_api_client-0.60.0 → runloop_api_client-0.60.1}/src/runloop_api_client/resources/__init__.py +0 -0
- {runloop_api_client-0.60.0 → runloop_api_client-0.60.1}/src/runloop_api_client/resources/benchmarks/__init__.py +0 -0
- {runloop_api_client-0.60.0 → runloop_api_client-0.60.1}/src/runloop_api_client/resources/benchmarks/benchmarks.py +0 -0
- {runloop_api_client-0.60.0 → runloop_api_client-0.60.1}/src/runloop_api_client/resources/benchmarks/runs.py +0 -0
- {runloop_api_client-0.60.0 → runloop_api_client-0.60.1}/src/runloop_api_client/resources/blueprints.py +0 -0
- {runloop_api_client-0.60.0 → runloop_api_client-0.60.1}/src/runloop_api_client/resources/devboxes/__init__.py +0 -0
- {runloop_api_client-0.60.0 → runloop_api_client-0.60.1}/src/runloop_api_client/resources/devboxes/browsers.py +0 -0
- {runloop_api_client-0.60.0 → runloop_api_client-0.60.1}/src/runloop_api_client/resources/devboxes/computers.py +0 -0
- {runloop_api_client-0.60.0 → runloop_api_client-0.60.1}/src/runloop_api_client/resources/devboxes/disk_snapshots.py +0 -0
- {runloop_api_client-0.60.0 → runloop_api_client-0.60.1}/src/runloop_api_client/resources/devboxes/executions.py +0 -0
- {runloop_api_client-0.60.0 → runloop_api_client-0.60.1}/src/runloop_api_client/resources/devboxes/logs.py +0 -0
- {runloop_api_client-0.60.0 → runloop_api_client-0.60.1}/src/runloop_api_client/resources/devboxes/lsp.py +0 -0
- {runloop_api_client-0.60.0 → runloop_api_client-0.60.1}/src/runloop_api_client/resources/objects.py +0 -0
- {runloop_api_client-0.60.0 → runloop_api_client-0.60.1}/src/runloop_api_client/resources/repositories.py +0 -0
- {runloop_api_client-0.60.0 → runloop_api_client-0.60.1}/src/runloop_api_client/resources/scenarios/__init__.py +0 -0
- {runloop_api_client-0.60.0 → runloop_api_client-0.60.1}/src/runloop_api_client/resources/scenarios/runs.py +0 -0
- {runloop_api_client-0.60.0 → runloop_api_client-0.60.1}/src/runloop_api_client/resources/scenarios/scenarios.py +0 -0
- {runloop_api_client-0.60.0 → runloop_api_client-0.60.1}/src/runloop_api_client/resources/scenarios/scorers.py +0 -0
- {runloop_api_client-0.60.0 → runloop_api_client-0.60.1}/src/runloop_api_client/resources/secrets.py +0 -0
- {runloop_api_client-0.60.0 → runloop_api_client-0.60.1}/src/runloop_api_client/types/__init__.py +0 -0
- {runloop_api_client-0.60.0 → runloop_api_client-0.60.1}/src/runloop_api_client/types/benchmark_create_params.py +0 -0
- {runloop_api_client-0.60.0 → runloop_api_client-0.60.1}/src/runloop_api_client/types/benchmark_definitions_params.py +0 -0
- {runloop_api_client-0.60.0 → runloop_api_client-0.60.1}/src/runloop_api_client/types/benchmark_list_params.py +0 -0
- {runloop_api_client-0.60.0 → runloop_api_client-0.60.1}/src/runloop_api_client/types/benchmark_list_public_params.py +0 -0
- {runloop_api_client-0.60.0 → runloop_api_client-0.60.1}/src/runloop_api_client/types/benchmark_run_list_view.py +0 -0
- {runloop_api_client-0.60.0 → runloop_api_client-0.60.1}/src/runloop_api_client/types/benchmark_run_view.py +0 -0
- {runloop_api_client-0.60.0 → runloop_api_client-0.60.1}/src/runloop_api_client/types/benchmark_start_run_params.py +0 -0
- {runloop_api_client-0.60.0 → runloop_api_client-0.60.1}/src/runloop_api_client/types/benchmark_update_params.py +0 -0
- {runloop_api_client-0.60.0 → runloop_api_client-0.60.1}/src/runloop_api_client/types/benchmark_view.py +0 -0
- {runloop_api_client-0.60.0 → runloop_api_client-0.60.1}/src/runloop_api_client/types/benchmarks/__init__.py +0 -0
- {runloop_api_client-0.60.0 → runloop_api_client-0.60.1}/src/runloop_api_client/types/benchmarks/run_list_params.py +0 -0
- {runloop_api_client-0.60.0 → runloop_api_client-0.60.1}/src/runloop_api_client/types/benchmarks/run_list_scenario_runs_params.py +0 -0
- {runloop_api_client-0.60.0 → runloop_api_client-0.60.1}/src/runloop_api_client/types/blueprint_build_log.py +0 -0
- {runloop_api_client-0.60.0 → runloop_api_client-0.60.1}/src/runloop_api_client/types/blueprint_build_logs_list_view.py +0 -0
- {runloop_api_client-0.60.0 → runloop_api_client-0.60.1}/src/runloop_api_client/types/blueprint_build_parameters.py +0 -0
- {runloop_api_client-0.60.0 → runloop_api_client-0.60.1}/src/runloop_api_client/types/blueprint_create_params.py +0 -0
- {runloop_api_client-0.60.0 → runloop_api_client-0.60.1}/src/runloop_api_client/types/blueprint_list_params.py +0 -0
- {runloop_api_client-0.60.0 → runloop_api_client-0.60.1}/src/runloop_api_client/types/blueprint_list_public_params.py +0 -0
- {runloop_api_client-0.60.0 → runloop_api_client-0.60.1}/src/runloop_api_client/types/blueprint_list_view.py +0 -0
- {runloop_api_client-0.60.0 → runloop_api_client-0.60.1}/src/runloop_api_client/types/blueprint_preview_params.py +0 -0
- {runloop_api_client-0.60.0 → runloop_api_client-0.60.1}/src/runloop_api_client/types/blueprint_preview_view.py +0 -0
- {runloop_api_client-0.60.0 → runloop_api_client-0.60.1}/src/runloop_api_client/types/blueprint_view.py +0 -0
- {runloop_api_client-0.60.0 → runloop_api_client-0.60.1}/src/runloop_api_client/types/devbox_async_execution_detail_view.py +0 -0
- {runloop_api_client-0.60.0 → runloop_api_client-0.60.1}/src/runloop_api_client/types/devbox_create_params.py +0 -0
- {runloop_api_client-0.60.0 → runloop_api_client-0.60.1}/src/runloop_api_client/types/devbox_create_ssh_key_response.py +0 -0
- {runloop_api_client-0.60.0 → runloop_api_client-0.60.1}/src/runloop_api_client/types/devbox_create_tunnel_params.py +0 -0
- {runloop_api_client-0.60.0 → runloop_api_client-0.60.1}/src/runloop_api_client/types/devbox_download_file_params.py +0 -0
- {runloop_api_client-0.60.0 → runloop_api_client-0.60.1}/src/runloop_api_client/types/devbox_execute_async_params.py +0 -0
- {runloop_api_client-0.60.0 → runloop_api_client-0.60.1}/src/runloop_api_client/types/devbox_execute_params.py +0 -0
- {runloop_api_client-0.60.0 → runloop_api_client-0.60.1}/src/runloop_api_client/types/devbox_execute_sync_params.py +0 -0
- {runloop_api_client-0.60.0 → runloop_api_client-0.60.1}/src/runloop_api_client/types/devbox_execution_detail_view.py +0 -0
- {runloop_api_client-0.60.0 → runloop_api_client-0.60.1}/src/runloop_api_client/types/devbox_list_disk_snapshots_params.py +0 -0
- {runloop_api_client-0.60.0 → runloop_api_client-0.60.1}/src/runloop_api_client/types/devbox_list_params.py +0 -0
- {runloop_api_client-0.60.0 → runloop_api_client-0.60.1}/src/runloop_api_client/types/devbox_list_view.py +0 -0
- {runloop_api_client-0.60.0 → runloop_api_client-0.60.1}/src/runloop_api_client/types/devbox_read_file_contents_params.py +0 -0
- {runloop_api_client-0.60.0 → runloop_api_client-0.60.1}/src/runloop_api_client/types/devbox_read_file_contents_response.py +0 -0
- {runloop_api_client-0.60.0 → runloop_api_client-0.60.1}/src/runloop_api_client/types/devbox_remove_tunnel_params.py +0 -0
- {runloop_api_client-0.60.0 → runloop_api_client-0.60.1}/src/runloop_api_client/types/devbox_snapshot_disk_async_params.py +0 -0
- {runloop_api_client-0.60.0 → runloop_api_client-0.60.1}/src/runloop_api_client/types/devbox_snapshot_disk_params.py +0 -0
- {runloop_api_client-0.60.0 → runloop_api_client-0.60.1}/src/runloop_api_client/types/devbox_snapshot_list_view.py +0 -0
- {runloop_api_client-0.60.0 → runloop_api_client-0.60.1}/src/runloop_api_client/types/devbox_snapshot_view.py +0 -0
- {runloop_api_client-0.60.0 → runloop_api_client-0.60.1}/src/runloop_api_client/types/devbox_tunnel_view.py +0 -0
- {runloop_api_client-0.60.0 → runloop_api_client-0.60.1}/src/runloop_api_client/types/devbox_update_params.py +0 -0
- {runloop_api_client-0.60.0 → runloop_api_client-0.60.1}/src/runloop_api_client/types/devbox_upload_file_params.py +0 -0
- {runloop_api_client-0.60.0 → runloop_api_client-0.60.1}/src/runloop_api_client/types/devbox_view.py +0 -0
- {runloop_api_client-0.60.0 → runloop_api_client-0.60.1}/src/runloop_api_client/types/devbox_wait_for_command_params.py +0 -0
- {runloop_api_client-0.60.0 → runloop_api_client-0.60.1}/src/runloop_api_client/types/devbox_write_file_contents_params.py +0 -0
- {runloop_api_client-0.60.0 → runloop_api_client-0.60.1}/src/runloop_api_client/types/devboxes/__init__.py +0 -0
- {runloop_api_client-0.60.0 → runloop_api_client-0.60.1}/src/runloop_api_client/types/devboxes/base_code_action.py +0 -0
- {runloop_api_client-0.60.0 → runloop_api_client-0.60.1}/src/runloop_api_client/types/devboxes/base_command.py +0 -0
- {runloop_api_client-0.60.0 → runloop_api_client-0.60.1}/src/runloop_api_client/types/devboxes/base_command_param.py +0 -0
- {runloop_api_client-0.60.0 → runloop_api_client-0.60.1}/src/runloop_api_client/types/devboxes/base_diagnostic.py +0 -0
- {runloop_api_client-0.60.0 → runloop_api_client-0.60.1}/src/runloop_api_client/types/devboxes/base_diagnostic_param.py +0 -0
- {runloop_api_client-0.60.0 → runloop_api_client-0.60.1}/src/runloop_api_client/types/devboxes/base_location.py +0 -0
- {runloop_api_client-0.60.0 → runloop_api_client-0.60.1}/src/runloop_api_client/types/devboxes/base_markup_content.py +0 -0
- {runloop_api_client-0.60.0 → runloop_api_client-0.60.1}/src/runloop_api_client/types/devboxes/base_parameter_information.py +0 -0
- {runloop_api_client-0.60.0 → runloop_api_client-0.60.1}/src/runloop_api_client/types/devboxes/base_range.py +0 -0
- {runloop_api_client-0.60.0 → runloop_api_client-0.60.1}/src/runloop_api_client/types/devboxes/base_range_param.py +0 -0
- {runloop_api_client-0.60.0 → runloop_api_client-0.60.1}/src/runloop_api_client/types/devboxes/base_signature.py +0 -0
- {runloop_api_client-0.60.0 → runloop_api_client-0.60.1}/src/runloop_api_client/types/devboxes/base_workspace_edit.py +0 -0
- {runloop_api_client-0.60.0 → runloop_api_client-0.60.1}/src/runloop_api_client/types/devboxes/base_workspace_edit_param.py +0 -0
- {runloop_api_client-0.60.0 → runloop_api_client-0.60.1}/src/runloop_api_client/types/devboxes/browser_create_params.py +0 -0
- {runloop_api_client-0.60.0 → runloop_api_client-0.60.1}/src/runloop_api_client/types/devboxes/browser_view.py +0 -0
- {runloop_api_client-0.60.0 → runloop_api_client-0.60.1}/src/runloop_api_client/types/devboxes/code_action_application_result.py +0 -0
- {runloop_api_client-0.60.0 → runloop_api_client-0.60.1}/src/runloop_api_client/types/devboxes/code_action_context_param.py +0 -0
- {runloop_api_client-0.60.0 → runloop_api_client-0.60.1}/src/runloop_api_client/types/devboxes/code_action_kind.py +0 -0
- {runloop_api_client-0.60.0 → runloop_api_client-0.60.1}/src/runloop_api_client/types/devboxes/code_action_trigger_kind.py +0 -0
- {runloop_api_client-0.60.0 → runloop_api_client-0.60.1}/src/runloop_api_client/types/devboxes/code_actions_response.py +0 -0
- {runloop_api_client-0.60.0 → runloop_api_client-0.60.1}/src/runloop_api_client/types/devboxes/code_description_param.py +0 -0
- {runloop_api_client-0.60.0 → runloop_api_client-0.60.1}/src/runloop_api_client/types/devboxes/code_segment_info_response.py +0 -0
- {runloop_api_client-0.60.0 → runloop_api_client-0.60.1}/src/runloop_api_client/types/devboxes/computer_create_params.py +0 -0
- {runloop_api_client-0.60.0 → runloop_api_client-0.60.1}/src/runloop_api_client/types/devboxes/computer_keyboard_interaction_params.py +0 -0
- {runloop_api_client-0.60.0 → runloop_api_client-0.60.1}/src/runloop_api_client/types/devboxes/computer_keyboard_interaction_response.py +0 -0
- {runloop_api_client-0.60.0 → runloop_api_client-0.60.1}/src/runloop_api_client/types/devboxes/computer_mouse_interaction_params.py +0 -0
- {runloop_api_client-0.60.0 → runloop_api_client-0.60.1}/src/runloop_api_client/types/devboxes/computer_mouse_interaction_response.py +0 -0
- {runloop_api_client-0.60.0 → runloop_api_client-0.60.1}/src/runloop_api_client/types/devboxes/computer_screen_interaction_params.py +0 -0
- {runloop_api_client-0.60.0 → runloop_api_client-0.60.1}/src/runloop_api_client/types/devboxes/computer_screen_interaction_response.py +0 -0
- {runloop_api_client-0.60.0 → runloop_api_client-0.60.1}/src/runloop_api_client/types/devboxes/computer_view.py +0 -0
- {runloop_api_client-0.60.0 → runloop_api_client-0.60.1}/src/runloop_api_client/types/devboxes/devbox_logs_list_view.py +0 -0
- {runloop_api_client-0.60.0 → runloop_api_client-0.60.1}/src/runloop_api_client/types/devboxes/devbox_snapshot_async_status_view.py +0 -0
- {runloop_api_client-0.60.0 → runloop_api_client-0.60.1}/src/runloop_api_client/types/devboxes/diagnostic_param.py +0 -0
- {runloop_api_client-0.60.0 → runloop_api_client-0.60.1}/src/runloop_api_client/types/devboxes/diagnostic_related_information_param.py +0 -0
- {runloop_api_client-0.60.0 → runloop_api_client-0.60.1}/src/runloop_api_client/types/devboxes/diagnostic_severity.py +0 -0
- {runloop_api_client-0.60.0 → runloop_api_client-0.60.1}/src/runloop_api_client/types/devboxes/diagnostic_tag.py +0 -0
- {runloop_api_client-0.60.0 → runloop_api_client-0.60.1}/src/runloop_api_client/types/devboxes/diagnostics_response.py +0 -0
- {runloop_api_client-0.60.0 → runloop_api_client-0.60.1}/src/runloop_api_client/types/devboxes/disk_snapshot_list_params.py +0 -0
- {runloop_api_client-0.60.0 → runloop_api_client-0.60.1}/src/runloop_api_client/types/devboxes/disk_snapshot_update_params.py +0 -0
- {runloop_api_client-0.60.0 → runloop_api_client-0.60.1}/src/runloop_api_client/types/devboxes/document_symbol.py +0 -0
- {runloop_api_client-0.60.0 → runloop_api_client-0.60.1}/src/runloop_api_client/types/devboxes/document_symbol_response.py +0 -0
- {runloop_api_client-0.60.0 → runloop_api_client-0.60.1}/src/runloop_api_client/types/devboxes/document_uri.py +0 -0
- {runloop_api_client-0.60.0 → runloop_api_client-0.60.1}/src/runloop_api_client/types/devboxes/execution_execute_async_params.py +0 -0
- {runloop_api_client-0.60.0 → runloop_api_client-0.60.1}/src/runloop_api_client/types/devboxes/execution_execute_sync_params.py +0 -0
- {runloop_api_client-0.60.0 → runloop_api_client-0.60.1}/src/runloop_api_client/types/devboxes/execution_kill_params.py +0 -0
- {runloop_api_client-0.60.0 → runloop_api_client-0.60.1}/src/runloop_api_client/types/devboxes/execution_retrieve_params.py +0 -0
- {runloop_api_client-0.60.0 → runloop_api_client-0.60.1}/src/runloop_api_client/types/devboxes/execution_stream_stderr_updates_params.py +0 -0
- {runloop_api_client-0.60.0 → runloop_api_client-0.60.1}/src/runloop_api_client/types/devboxes/execution_stream_stdout_updates_params.py +0 -0
- {runloop_api_client-0.60.0 → runloop_api_client-0.60.1}/src/runloop_api_client/types/devboxes/execution_update_chunk.py +0 -0
- {runloop_api_client-0.60.0 → runloop_api_client-0.60.1}/src/runloop_api_client/types/devboxes/file_contents_response.py +0 -0
- {runloop_api_client-0.60.0 → runloop_api_client-0.60.1}/src/runloop_api_client/types/devboxes/file_definition_response.py +0 -0
- {runloop_api_client-0.60.0 → runloop_api_client-0.60.1}/src/runloop_api_client/types/devboxes/file_path.py +0 -0
- {runloop_api_client-0.60.0 → runloop_api_client-0.60.1}/src/runloop_api_client/types/devboxes/file_uri.py +0 -0
- {runloop_api_client-0.60.0 → runloop_api_client-0.60.1}/src/runloop_api_client/types/devboxes/formatting_response.py +0 -0
- {runloop_api_client-0.60.0 → runloop_api_client-0.60.1}/src/runloop_api_client/types/devboxes/health_status_response.py +0 -0
- {runloop_api_client-0.60.0 → runloop_api_client-0.60.1}/src/runloop_api_client/types/devboxes/integer.py +0 -0
- {runloop_api_client-0.60.0 → runloop_api_client-0.60.1}/src/runloop_api_client/types/devboxes/l_sp_any_param.py +0 -0
- {runloop_api_client-0.60.0 → runloop_api_client-0.60.1}/src/runloop_api_client/types/devboxes/location_param.py +0 -0
- {runloop_api_client-0.60.0 → runloop_api_client-0.60.1}/src/runloop_api_client/types/devboxes/log_list_params.py +0 -0
- {runloop_api_client-0.60.0 → runloop_api_client-0.60.1}/src/runloop_api_client/types/devboxes/lsp_apply_code_action_params.py +0 -0
- {runloop_api_client-0.60.0 → runloop_api_client-0.60.1}/src/runloop_api_client/types/devboxes/lsp_code_actions_params.py +0 -0
- {runloop_api_client-0.60.0 → runloop_api_client-0.60.1}/src/runloop_api_client/types/devboxes/lsp_diagnostics_params.py +0 -0
- {runloop_api_client-0.60.0 → runloop_api_client-0.60.1}/src/runloop_api_client/types/devboxes/lsp_document_symbols_params.py +0 -0
- {runloop_api_client-0.60.0 → runloop_api_client-0.60.1}/src/runloop_api_client/types/devboxes/lsp_file_definition_params.py +0 -0
- {runloop_api_client-0.60.0 → runloop_api_client-0.60.1}/src/runloop_api_client/types/devboxes/lsp_file_params.py +0 -0
- {runloop_api_client-0.60.0 → runloop_api_client-0.60.1}/src/runloop_api_client/types/devboxes/lsp_files_response.py +0 -0
- {runloop_api_client-0.60.0 → runloop_api_client-0.60.1}/src/runloop_api_client/types/devboxes/lsp_formatting_params.py +0 -0
- {runloop_api_client-0.60.0 → runloop_api_client-0.60.1}/src/runloop_api_client/types/devboxes/lsp_get_code_actions_for_diagnostic_params.py +0 -0
- {runloop_api_client-0.60.0 → runloop_api_client-0.60.1}/src/runloop_api_client/types/devboxes/lsp_get_code_actions_for_diagnostic_response.py +0 -0
- {runloop_api_client-0.60.0 → runloop_api_client-0.60.1}/src/runloop_api_client/types/devboxes/lsp_get_code_segment_info_params.py +0 -0
- {runloop_api_client-0.60.0 → runloop_api_client-0.60.1}/src/runloop_api_client/types/devboxes/lsp_get_signature_help_params.py +0 -0
- {runloop_api_client-0.60.0 → runloop_api_client-0.60.1}/src/runloop_api_client/types/devboxes/lsp_references_params.py +0 -0
- {runloop_api_client-0.60.0 → runloop_api_client-0.60.1}/src/runloop_api_client/types/devboxes/lsp_set_watch_directory_params.py +0 -0
- {runloop_api_client-0.60.0 → runloop_api_client-0.60.1}/src/runloop_api_client/types/devboxes/lsp_set_watch_directory_response.py +0 -0
- {runloop_api_client-0.60.0 → runloop_api_client-0.60.1}/src/runloop_api_client/types/devboxes/position.py +0 -0
- {runloop_api_client-0.60.0 → runloop_api_client-0.60.1}/src/runloop_api_client/types/devboxes/position_param.py +0 -0
- {runloop_api_client-0.60.0 → runloop_api_client-0.60.1}/src/runloop_api_client/types/devboxes/range.py +0 -0
- {runloop_api_client-0.60.0 → runloop_api_client-0.60.1}/src/runloop_api_client/types/devboxes/range_param.py +0 -0
- {runloop_api_client-0.60.0 → runloop_api_client-0.60.1}/src/runloop_api_client/types/devboxes/record_string_text_edit_array.py +0 -0
- {runloop_api_client-0.60.0 → runloop_api_client-0.60.1}/src/runloop_api_client/types/devboxes/record_string_text_edit_array_param.py +0 -0
- {runloop_api_client-0.60.0 → runloop_api_client-0.60.1}/src/runloop_api_client/types/devboxes/references_response.py +0 -0
- {runloop_api_client-0.60.0 → runloop_api_client-0.60.1}/src/runloop_api_client/types/devboxes/signature_help_response.py +0 -0
- {runloop_api_client-0.60.0 → runloop_api_client-0.60.1}/src/runloop_api_client/types/devboxes/symbol_kind.py +0 -0
- {runloop_api_client-0.60.0 → runloop_api_client-0.60.1}/src/runloop_api_client/types/devboxes/symbol_tag.py +0 -0
- {runloop_api_client-0.60.0 → runloop_api_client-0.60.1}/src/runloop_api_client/types/devboxes/symbol_type.py +0 -0
- {runloop_api_client-0.60.0 → runloop_api_client-0.60.1}/src/runloop_api_client/types/devboxes/text_edit.py +0 -0
- {runloop_api_client-0.60.0 → runloop_api_client-0.60.1}/src/runloop_api_client/types/devboxes/text_edit_param.py +0 -0
- {runloop_api_client-0.60.0 → runloop_api_client-0.60.1}/src/runloop_api_client/types/devboxes/u_ri.py +0 -0
- {runloop_api_client-0.60.0 → runloop_api_client-0.60.1}/src/runloop_api_client/types/devboxes/uinteger.py +0 -0
- {runloop_api_client-0.60.0 → runloop_api_client-0.60.1}/src/runloop_api_client/types/devboxes/watched_file_response.py +0 -0
- {runloop_api_client-0.60.0 → runloop_api_client-0.60.1}/src/runloop_api_client/types/input_context.py +0 -0
- {runloop_api_client-0.60.0 → runloop_api_client-0.60.1}/src/runloop_api_client/types/input_context_param.py +0 -0
- {runloop_api_client-0.60.0 → runloop_api_client-0.60.1}/src/runloop_api_client/types/input_context_update_param.py +0 -0
- {runloop_api_client-0.60.0 → runloop_api_client-0.60.1}/src/runloop_api_client/types/object_create_params.py +0 -0
- {runloop_api_client-0.60.0 → runloop_api_client-0.60.1}/src/runloop_api_client/types/object_download_params.py +0 -0
- {runloop_api_client-0.60.0 → runloop_api_client-0.60.1}/src/runloop_api_client/types/object_download_url_view.py +0 -0
- {runloop_api_client-0.60.0 → runloop_api_client-0.60.1}/src/runloop_api_client/types/object_list_params.py +0 -0
- {runloop_api_client-0.60.0 → runloop_api_client-0.60.1}/src/runloop_api_client/types/object_list_public_params.py +0 -0
- {runloop_api_client-0.60.0 → runloop_api_client-0.60.1}/src/runloop_api_client/types/object_list_view.py +0 -0
- {runloop_api_client-0.60.0 → runloop_api_client-0.60.1}/src/runloop_api_client/types/object_view.py +0 -0
- {runloop_api_client-0.60.0 → runloop_api_client-0.60.1}/src/runloop_api_client/types/repository_connection_list_view.py +0 -0
- {runloop_api_client-0.60.0 → runloop_api_client-0.60.1}/src/runloop_api_client/types/repository_connection_view.py +0 -0
- {runloop_api_client-0.60.0 → runloop_api_client-0.60.1}/src/runloop_api_client/types/repository_create_params.py +0 -0
- {runloop_api_client-0.60.0 → runloop_api_client-0.60.1}/src/runloop_api_client/types/repository_inspection_details.py +0 -0
- {runloop_api_client-0.60.0 → runloop_api_client-0.60.1}/src/runloop_api_client/types/repository_inspection_list_view.py +0 -0
- {runloop_api_client-0.60.0 → runloop_api_client-0.60.1}/src/runloop_api_client/types/repository_list_params.py +0 -0
- {runloop_api_client-0.60.0 → runloop_api_client-0.60.1}/src/runloop_api_client/types/repository_manifest_view.py +0 -0
- {runloop_api_client-0.60.0 → runloop_api_client-0.60.1}/src/runloop_api_client/types/repository_refresh_params.py +0 -0
- {runloop_api_client-0.60.0 → runloop_api_client-0.60.1}/src/runloop_api_client/types/scenario_create_params.py +0 -0
- {runloop_api_client-0.60.0 → runloop_api_client-0.60.1}/src/runloop_api_client/types/scenario_definition_list_view.py +0 -0
- {runloop_api_client-0.60.0 → runloop_api_client-0.60.1}/src/runloop_api_client/types/scenario_environment.py +0 -0
- {runloop_api_client-0.60.0 → runloop_api_client-0.60.1}/src/runloop_api_client/types/scenario_environment_param.py +0 -0
- {runloop_api_client-0.60.0 → runloop_api_client-0.60.1}/src/runloop_api_client/types/scenario_list_params.py +0 -0
- {runloop_api_client-0.60.0 → runloop_api_client-0.60.1}/src/runloop_api_client/types/scenario_list_public_params.py +0 -0
- {runloop_api_client-0.60.0 → runloop_api_client-0.60.1}/src/runloop_api_client/types/scenario_run_list_view.py +0 -0
- {runloop_api_client-0.60.0 → runloop_api_client-0.60.1}/src/runloop_api_client/types/scenario_run_view.py +0 -0
- {runloop_api_client-0.60.0 → runloop_api_client-0.60.1}/src/runloop_api_client/types/scenario_start_run_params.py +0 -0
- {runloop_api_client-0.60.0 → runloop_api_client-0.60.1}/src/runloop_api_client/types/scenario_update_params.py +0 -0
- {runloop_api_client-0.60.0 → runloop_api_client-0.60.1}/src/runloop_api_client/types/scenario_view.py +0 -0
- {runloop_api_client-0.60.0 → runloop_api_client-0.60.1}/src/runloop_api_client/types/scenarios/__init__.py +0 -0
- {runloop_api_client-0.60.0 → runloop_api_client-0.60.1}/src/runloop_api_client/types/scenarios/run_list_params.py +0 -0
- {runloop_api_client-0.60.0 → runloop_api_client-0.60.1}/src/runloop_api_client/types/scenarios/scorer_create_params.py +0 -0
- {runloop_api_client-0.60.0 → runloop_api_client-0.60.1}/src/runloop_api_client/types/scenarios/scorer_create_response.py +0 -0
- {runloop_api_client-0.60.0 → runloop_api_client-0.60.1}/src/runloop_api_client/types/scenarios/scorer_list_params.py +0 -0
- {runloop_api_client-0.60.0 → runloop_api_client-0.60.1}/src/runloop_api_client/types/scenarios/scorer_list_response.py +0 -0
- {runloop_api_client-0.60.0 → runloop_api_client-0.60.1}/src/runloop_api_client/types/scenarios/scorer_retrieve_response.py +0 -0
- {runloop_api_client-0.60.0 → runloop_api_client-0.60.1}/src/runloop_api_client/types/scenarios/scorer_update_params.py +0 -0
- {runloop_api_client-0.60.0 → runloop_api_client-0.60.1}/src/runloop_api_client/types/scenarios/scorer_update_response.py +0 -0
- {runloop_api_client-0.60.0 → runloop_api_client-0.60.1}/src/runloop_api_client/types/scenarios/scorer_validate_params.py +0 -0
- {runloop_api_client-0.60.0 → runloop_api_client-0.60.1}/src/runloop_api_client/types/scenarios/scorer_validate_response.py +0 -0
- {runloop_api_client-0.60.0 → runloop_api_client-0.60.1}/src/runloop_api_client/types/scoring_contract.py +0 -0
- {runloop_api_client-0.60.0 → runloop_api_client-0.60.1}/src/runloop_api_client/types/scoring_contract_param.py +0 -0
- {runloop_api_client-0.60.0 → runloop_api_client-0.60.1}/src/runloop_api_client/types/scoring_contract_result_view.py +0 -0
- {runloop_api_client-0.60.0 → runloop_api_client-0.60.1}/src/runloop_api_client/types/scoring_contract_update_param.py +0 -0
- {runloop_api_client-0.60.0 → runloop_api_client-0.60.1}/src/runloop_api_client/types/scoring_function.py +0 -0
- {runloop_api_client-0.60.0 → runloop_api_client-0.60.1}/src/runloop_api_client/types/scoring_function_param.py +0 -0
- {runloop_api_client-0.60.0 → runloop_api_client-0.60.1}/src/runloop_api_client/types/scoring_function_result_view.py +0 -0
- {runloop_api_client-0.60.0 → runloop_api_client-0.60.1}/src/runloop_api_client/types/secret_create_params.py +0 -0
- {runloop_api_client-0.60.0 → runloop_api_client-0.60.1}/src/runloop_api_client/types/secret_list_params.py +0 -0
- {runloop_api_client-0.60.0 → runloop_api_client-0.60.1}/src/runloop_api_client/types/secret_list_view.py +0 -0
- {runloop_api_client-0.60.0 → runloop_api_client-0.60.1}/src/runloop_api_client/types/secret_update_params.py +0 -0
- {runloop_api_client-0.60.0 → runloop_api_client-0.60.1}/src/runloop_api_client/types/secret_view.py +0 -0
- {runloop_api_client-0.60.0 → runloop_api_client-0.60.1}/src/runloop_api_client/types/shared/__init__.py +0 -0
- {runloop_api_client-0.60.0 → runloop_api_client-0.60.1}/src/runloop_api_client/types/shared/after_idle.py +0 -0
- {runloop_api_client-0.60.0 → runloop_api_client-0.60.1}/src/runloop_api_client/types/shared/code_mount_parameters.py +0 -0
- {runloop_api_client-0.60.0 → runloop_api_client-0.60.1}/src/runloop_api_client/types/shared/launch_parameters.py +0 -0
- {runloop_api_client-0.60.0 → runloop_api_client-0.60.1}/src/runloop_api_client/types/shared/run_profile.py +0 -0
- {runloop_api_client-0.60.0 → runloop_api_client-0.60.1}/src/runloop_api_client/types/shared_params/__init__.py +0 -0
- {runloop_api_client-0.60.0 → runloop_api_client-0.60.1}/src/runloop_api_client/types/shared_params/after_idle.py +0 -0
- {runloop_api_client-0.60.0 → runloop_api_client-0.60.1}/src/runloop_api_client/types/shared_params/code_mount_parameters.py +0 -0
- {runloop_api_client-0.60.0 → runloop_api_client-0.60.1}/src/runloop_api_client/types/shared_params/launch_parameters.py +0 -0
- {runloop_api_client-0.60.0 → runloop_api_client-0.60.1}/src/runloop_api_client/types/shared_params/run_profile.py +0 -0
- {runloop_api_client-0.60.0 → runloop_api_client-0.60.1}/tests/__init__.py +0 -0
- {runloop_api_client-0.60.0 → runloop_api_client-0.60.1}/tests/api_resources/__init__.py +0 -0
- {runloop_api_client-0.60.0 → runloop_api_client-0.60.1}/tests/api_resources/benchmarks/__init__.py +0 -0
- {runloop_api_client-0.60.0 → runloop_api_client-0.60.1}/tests/api_resources/benchmarks/test_runs.py +0 -0
- {runloop_api_client-0.60.0 → runloop_api_client-0.60.1}/tests/api_resources/devboxes/__init__.py +0 -0
- {runloop_api_client-0.60.0 → runloop_api_client-0.60.1}/tests/api_resources/devboxes/test_browsers.py +0 -0
- {runloop_api_client-0.60.0 → runloop_api_client-0.60.1}/tests/api_resources/devboxes/test_computers.py +0 -0
- {runloop_api_client-0.60.0 → runloop_api_client-0.60.1}/tests/api_resources/devboxes/test_disk_snapshots.py +0 -0
- {runloop_api_client-0.60.0 → runloop_api_client-0.60.1}/tests/api_resources/devboxes/test_executions.py +0 -0
- {runloop_api_client-0.60.0 → runloop_api_client-0.60.1}/tests/api_resources/devboxes/test_logs.py +0 -0
- {runloop_api_client-0.60.0 → runloop_api_client-0.60.1}/tests/api_resources/devboxes/test_lsp.py +0 -0
- {runloop_api_client-0.60.0 → runloop_api_client-0.60.1}/tests/api_resources/scenarios/__init__.py +0 -0
- {runloop_api_client-0.60.0 → runloop_api_client-0.60.1}/tests/api_resources/scenarios/test_runs.py +0 -0
- {runloop_api_client-0.60.0 → runloop_api_client-0.60.1}/tests/api_resources/scenarios/test_scorers.py +0 -0
- {runloop_api_client-0.60.0 → runloop_api_client-0.60.1}/tests/api_resources/test_benchmarks.py +0 -0
- {runloop_api_client-0.60.0 → runloop_api_client-0.60.1}/tests/api_resources/test_blueprints.py +0 -0
- {runloop_api_client-0.60.0 → runloop_api_client-0.60.1}/tests/api_resources/test_devboxes.py +0 -0
- {runloop_api_client-0.60.0 → runloop_api_client-0.60.1}/tests/api_resources/test_objects.py +0 -0
- {runloop_api_client-0.60.0 → runloop_api_client-0.60.1}/tests/api_resources/test_repositories.py +0 -0
- {runloop_api_client-0.60.0 → runloop_api_client-0.60.1}/tests/api_resources/test_scenarios.py +0 -0
- {runloop_api_client-0.60.0 → runloop_api_client-0.60.1}/tests/api_resources/test_secrets.py +0 -0
- {runloop_api_client-0.60.0 → runloop_api_client-0.60.1}/tests/conftest.py +0 -0
- {runloop_api_client-0.60.0 → runloop_api_client-0.60.1}/tests/sample_file.txt +0 -0
- {runloop_api_client-0.60.0 → runloop_api_client-0.60.1}/tests/smoketests/__init__.py +0 -0
- {runloop_api_client-0.60.0 → runloop_api_client-0.60.1}/tests/test_client.py +0 -0
- {runloop_api_client-0.60.0 → runloop_api_client-0.60.1}/tests/test_deepcopy.py +0 -0
- {runloop_api_client-0.60.0 → runloop_api_client-0.60.1}/tests/test_extract_files.py +0 -0
- {runloop_api_client-0.60.0 → runloop_api_client-0.60.1}/tests/test_files.py +0 -0
- {runloop_api_client-0.60.0 → runloop_api_client-0.60.1}/tests/test_models.py +0 -0
- {runloop_api_client-0.60.0 → runloop_api_client-0.60.1}/tests/test_polling.py +0 -0
- {runloop_api_client-0.60.0 → runloop_api_client-0.60.1}/tests/test_qs.py +0 -0
- {runloop_api_client-0.60.0 → runloop_api_client-0.60.1}/tests/test_required_args.py +0 -0
- {runloop_api_client-0.60.0 → runloop_api_client-0.60.1}/tests/test_response.py +0 -0
- {runloop_api_client-0.60.0 → runloop_api_client-0.60.1}/tests/test_streaming.py +0 -0
- {runloop_api_client-0.60.0 → runloop_api_client-0.60.1}/tests/test_transform.py +0 -0
- {runloop_api_client-0.60.0 → runloop_api_client-0.60.1}/tests/test_utils/test_datetime_parse.py +0 -0
- {runloop_api_client-0.60.0 → runloop_api_client-0.60.1}/tests/test_utils/test_proxy.py +0 -0
- {runloop_api_client-0.60.0 → runloop_api_client-0.60.1}/tests/test_utils/test_typing.py +0 -0
- {runloop_api_client-0.60.0 → runloop_api_client-0.60.1}/tests/utils.py +0 -0
|
@@ -1,5 +1,9 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 0.60.1 (2025-09-11)
|
|
4
|
+
|
|
5
|
+
Full Changelog: [v0.60.0...v0.60.1](https://github.com/runloopai/api-client-python/compare/v0.60.0...v0.60.1)
|
|
6
|
+
|
|
3
7
|
## 0.60.0 (2025-09-10)
|
|
4
8
|
|
|
5
9
|
Full Changelog: [v0.59.0...v0.60.0](https://github.com/runloopai/api-client-python/compare/v0.59.0...v0.60.0)
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.3
|
|
2
2
|
Name: runloop_api_client
|
|
3
|
-
Version: 0.60.
|
|
3
|
+
Version: 0.60.1
|
|
4
4
|
Summary: The official Python library for the runloop API
|
|
5
5
|
Project-URL: Homepage, https://github.com/runloopai/api-client-python
|
|
6
6
|
Project-URL: Repository, https://github.com/runloopai/api-client-python
|
|
@@ -13,7 +13,6 @@ Classifier: Operating System :: Microsoft :: Windows
|
|
|
13
13
|
Classifier: Operating System :: OS Independent
|
|
14
14
|
Classifier: Operating System :: POSIX
|
|
15
15
|
Classifier: Operating System :: POSIX :: Linux
|
|
16
|
-
Classifier: Programming Language :: Python :: 3.8
|
|
17
16
|
Classifier: Programming Language :: Python :: 3.9
|
|
18
17
|
Classifier: Programming Language :: Python :: 3.10
|
|
19
18
|
Classifier: Programming Language :: Python :: 3.11
|
|
@@ -21,13 +20,14 @@ Classifier: Programming Language :: Python :: 3.12
|
|
|
21
20
|
Classifier: Programming Language :: Python :: 3.13
|
|
22
21
|
Classifier: Topic :: Software Development :: Libraries :: Python Modules
|
|
23
22
|
Classifier: Typing :: Typed
|
|
24
|
-
Requires-Python: >=3.
|
|
23
|
+
Requires-Python: >=3.9
|
|
25
24
|
Requires-Dist: anyio<5,>=3.5.0
|
|
26
25
|
Requires-Dist: distro<2,>=1.7.0
|
|
27
26
|
Requires-Dist: httpx<1,>=0.23.0
|
|
28
|
-
Requires-Dist: pydantic<
|
|
27
|
+
Requires-Dist: pydantic<2.11,>=1.9.0
|
|
29
28
|
Requires-Dist: sniffio
|
|
30
29
|
Requires-Dist: typing-extensions<5,>=4.10
|
|
30
|
+
Requires-Dist: uuid-utils>=0.11.0
|
|
31
31
|
Provides-Extra: aiohttp
|
|
32
32
|
Requires-Dist: aiohttp; extra == 'aiohttp'
|
|
33
33
|
Requires-Dist: httpx-aiohttp>=0.1.8; extra == 'aiohttp'
|
|
@@ -46,7 +46,7 @@ It is generated with [Stainless](https://www.stainless.com/).
|
|
|
46
46
|
|
|
47
47
|
## Documentation
|
|
48
48
|
|
|
49
|
-
The REST API documentation can be found on [runloop.ai](https://runloop.ai). The full API of this library can be found in [api.md](
|
|
49
|
+
The REST API documentation can be found on [runloop.ai](https://runloop.ai). The full API of this library can be found in [api.md](api.md).
|
|
50
50
|
|
|
51
51
|
## Installation
|
|
52
52
|
|
|
@@ -57,7 +57,7 @@ pip install runloop_api_client
|
|
|
57
57
|
|
|
58
58
|
## Usage
|
|
59
59
|
|
|
60
|
-
The full API of this library can be found in [api.md](
|
|
60
|
+
The full API of this library can be found in [api.md](api.md).
|
|
61
61
|
|
|
62
62
|
```python
|
|
63
63
|
import os
|
|
@@ -325,7 +325,7 @@ client.with_options(timeout=5.0).devboxes.create()
|
|
|
325
325
|
|
|
326
326
|
On timeout, an `APITimeoutError` is thrown.
|
|
327
327
|
|
|
328
|
-
Note that requests that time out are [retried twice by default](
|
|
328
|
+
Note that requests that time out are [retried twice by default](#retries).
|
|
329
329
|
|
|
330
330
|
## Advanced
|
|
331
331
|
|
|
@@ -493,4 +493,4 @@ Python 3.8 or higher.
|
|
|
493
493
|
|
|
494
494
|
## Contributing
|
|
495
495
|
|
|
496
|
-
See [the contributing documentation](
|
|
496
|
+
See [the contributing documentation](./CONTRIBUTING.md).
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
[project]
|
|
2
2
|
name = "runloop_api_client"
|
|
3
|
-
version = "0.60.
|
|
3
|
+
version = "0.60.1"
|
|
4
4
|
description = "The official Python library for the runloop API"
|
|
5
5
|
dynamic = ["readme"]
|
|
6
6
|
license = "MIT"
|
|
@@ -9,18 +9,18 @@ authors = [
|
|
|
9
9
|
]
|
|
10
10
|
dependencies = [
|
|
11
11
|
"httpx>=0.23.0, <1",
|
|
12
|
-
"pydantic>=1.9.0, <
|
|
12
|
+
"pydantic>=1.9.0, <2.11",
|
|
13
13
|
"typing-extensions>=4.10, <5",
|
|
14
14
|
"anyio>=3.5.0, <5",
|
|
15
15
|
"distro>=1.7.0, <2",
|
|
16
16
|
"sniffio",
|
|
17
|
+
"uuid-utils>=0.11.0",
|
|
17
18
|
]
|
|
18
19
|
|
|
19
|
-
requires-python = ">= 3.
|
|
20
|
+
requires-python = ">= 3.9"
|
|
20
21
|
classifiers = [
|
|
21
22
|
"Typing :: Typed",
|
|
22
23
|
"Intended Audience :: Developers",
|
|
23
|
-
"Programming Language :: Python :: 3.8",
|
|
24
24
|
"Programming Language :: Python :: 3.9",
|
|
25
25
|
"Programming Language :: Python :: 3.10",
|
|
26
26
|
"Programming Language :: Python :: 3.11",
|
|
@@ -59,6 +59,7 @@ dev-dependencies = [
|
|
|
59
59
|
"importlib-metadata>=6.7.0",
|
|
60
60
|
"rich>=13.7.1",
|
|
61
61
|
"pytest-xdist>=3.6.1",
|
|
62
|
+
"uuid-utils>=0.11.0"
|
|
62
63
|
]
|
|
63
64
|
|
|
64
65
|
[tool.rye.scripts]
|
|
@@ -86,6 +87,7 @@ typecheck = { chain = [
|
|
|
86
87
|
"typecheck:pyright",
|
|
87
88
|
"typecheck:mypy"
|
|
88
89
|
]}
|
|
90
|
+
|
|
89
91
|
"typecheck:pyright" = "pyright"
|
|
90
92
|
"typecheck:verify-types" = "pyright --verifytypes runloop_api_client --ignoreexternal"
|
|
91
93
|
"typecheck:mypy" = "mypy ."
|
|
@@ -130,8 +132,8 @@ path = "README.md"
|
|
|
130
132
|
|
|
131
133
|
[[tool.hatch.metadata.hooks.fancy-pypi-readme.substitutions]]
|
|
132
134
|
# replace relative links with absolute links
|
|
133
|
-
pattern = '
|
|
134
|
-
replacement = '[
|
|
135
|
+
pattern = '\\[(.+?)\\]\\(((?!https?://)\\S+?)\\)'
|
|
136
|
+
replacement = '[\\1](https://github.com/runloopai/api-client-python/tree/main/\\g<2>)'
|
|
135
137
|
|
|
136
138
|
[tool.pytest.ini_options]
|
|
137
139
|
testpaths = ["tests"]
|
|
@@ -153,7 +155,7 @@ markers = [
|
|
|
153
155
|
# there are a couple of flags that are still disabled by
|
|
154
156
|
# default in strict mode as they are experimental and niche.
|
|
155
157
|
typeCheckingMode = "strict"
|
|
156
|
-
pythonVersion = "3.
|
|
158
|
+
pythonVersion = "3.9"
|
|
157
159
|
|
|
158
160
|
exclude = [
|
|
159
161
|
"_dev",
|
|
@@ -223,7 +225,7 @@ ignore_missing_imports = true
|
|
|
223
225
|
[tool.ruff]
|
|
224
226
|
line-length = 120
|
|
225
227
|
output-format = "grouped"
|
|
226
|
-
target-version = "
|
|
228
|
+
target-version = "py39"
|
|
227
229
|
|
|
228
230
|
[tool.ruff.format]
|
|
229
231
|
docstring-code-format = true
|
|
@@ -97,10 +97,10 @@ pygments==2.18.0
|
|
|
97
97
|
pyright==1.1.399
|
|
98
98
|
pytest==8.3.3
|
|
99
99
|
# via pytest-asyncio
|
|
100
|
+
# via pytest-timeout
|
|
100
101
|
# via pytest-xdist
|
|
101
|
-
pytest-timeout==2.3.1
|
|
102
|
-
# via runloop-api-client (dev)
|
|
103
102
|
pytest-asyncio==0.24.0
|
|
103
|
+
pytest-timeout==2.3.1
|
|
104
104
|
pytest-xdist==3.7.0
|
|
105
105
|
python-dateutil==2.8.2
|
|
106
106
|
# via time-machine
|
|
@@ -128,6 +128,8 @@ typing-extensions==4.12.2
|
|
|
128
128
|
# via pydantic-core
|
|
129
129
|
# via pyright
|
|
130
130
|
# via runloop-api-client
|
|
131
|
+
uuid-utils==0.11.0
|
|
132
|
+
# via runloop-api-client
|
|
131
133
|
virtualenv==20.24.5
|
|
132
134
|
# via nox
|
|
133
135
|
yarl==1.20.0
|
|
@@ -179,7 +179,7 @@ class BaseModel(pydantic.BaseModel):
|
|
|
179
179
|
@classmethod
|
|
180
180
|
@override
|
|
181
181
|
def construct( # pyright: ignore[reportIncompatibleMethodOverride]
|
|
182
|
-
__cls: Type[ModelT],
|
|
182
|
+
__cls: Type[ModelT], # type: ignore
|
|
183
183
|
_fields_set: set[str] | None = None,
|
|
184
184
|
**values: object,
|
|
185
185
|
) -> ModelT:
|
|
@@ -7,6 +7,9 @@ from typing_extensions import Literal
|
|
|
7
7
|
|
|
8
8
|
import httpx
|
|
9
9
|
|
|
10
|
+
# uuid_utils is not typed
|
|
11
|
+
from uuid_utils import uuid7 # type: ignore
|
|
12
|
+
|
|
10
13
|
from .lsp import (
|
|
11
14
|
LspResource,
|
|
12
15
|
AsyncLspResource,
|
|
@@ -787,6 +790,59 @@ class DevboxesResource(SyncAPIResource):
|
|
|
787
790
|
cast_to=DevboxAsyncExecutionDetailView,
|
|
788
791
|
)
|
|
789
792
|
|
|
793
|
+
def execute_and_await_completion(
|
|
794
|
+
self,
|
|
795
|
+
devbox_id: str,
|
|
796
|
+
*,
|
|
797
|
+
command: str,
|
|
798
|
+
shell_name: Optional[str] | NotGiven = NOT_GIVEN,
|
|
799
|
+
polling_config: PollingConfig | None = None,
|
|
800
|
+
# The following are forwarded to the initial execute request
|
|
801
|
+
extra_headers: Headers | None = None,
|
|
802
|
+
extra_query: Query | None = None,
|
|
803
|
+
extra_body: Body | None = None,
|
|
804
|
+
timeout: float | httpx.Timeout | None | NotGiven = NOT_GIVEN,
|
|
805
|
+
idempotency_key: str | None = None,
|
|
806
|
+
) -> DevboxAsyncExecutionDetailView:
|
|
807
|
+
"""
|
|
808
|
+
Execute a command and wait for it to complete with optimal latency for long running commands.
|
|
809
|
+
|
|
810
|
+
This method launches an execution with a generated command_id and first attempts to
|
|
811
|
+
return the result within the initial request's timeout. If the execution is not yet
|
|
812
|
+
complete, it switches to using wait_for_command to minimize latency while waiting.
|
|
813
|
+
"""
|
|
814
|
+
command_id = str(uuid7()) # type: ignore
|
|
815
|
+
execution = self.execute(
|
|
816
|
+
devbox_id,
|
|
817
|
+
command=command,
|
|
818
|
+
command_id=command_id,
|
|
819
|
+
shell_name=shell_name,
|
|
820
|
+
extra_headers=extra_headers,
|
|
821
|
+
extra_query=extra_query,
|
|
822
|
+
extra_body=extra_body,
|
|
823
|
+
timeout=timeout,
|
|
824
|
+
idempotency_key=idempotency_key,
|
|
825
|
+
)
|
|
826
|
+
if execution.status == "completed":
|
|
827
|
+
return execution
|
|
828
|
+
|
|
829
|
+
def handle_timeout_error(error: Exception) -> DevboxAsyncExecutionDetailView:
|
|
830
|
+
if isinstance(error, APITimeoutError) or (
|
|
831
|
+
isinstance(error, APIStatusError) and error.response.status_code == 408
|
|
832
|
+
):
|
|
833
|
+
return execution
|
|
834
|
+
raise error
|
|
835
|
+
|
|
836
|
+
def is_done(result: DevboxAsyncExecutionDetailView) -> bool:
|
|
837
|
+
return result.status == "completed"
|
|
838
|
+
|
|
839
|
+
return poll_until(
|
|
840
|
+
lambda: self.wait_for_command(execution.execution_id, devbox_id=devbox_id, statuses=["completed"]),
|
|
841
|
+
is_done,
|
|
842
|
+
polling_config,
|
|
843
|
+
handle_timeout_error,
|
|
844
|
+
)
|
|
845
|
+
|
|
790
846
|
def execute_async(
|
|
791
847
|
self,
|
|
792
848
|
id: str,
|
|
@@ -2175,6 +2231,60 @@ class AsyncDevboxesResource(AsyncAPIResource):
|
|
|
2175
2231
|
cast_to=DevboxAsyncExecutionDetailView,
|
|
2176
2232
|
)
|
|
2177
2233
|
|
|
2234
|
+
async def execute_and_await_completion(
|
|
2235
|
+
self,
|
|
2236
|
+
devbox_id: str,
|
|
2237
|
+
*,
|
|
2238
|
+
command: str,
|
|
2239
|
+
shell_name: Optional[str] | NotGiven = NOT_GIVEN,
|
|
2240
|
+
polling_config: PollingConfig | None = None,
|
|
2241
|
+
# The following are forwarded to the initial execute request
|
|
2242
|
+
extra_headers: Headers | None = None,
|
|
2243
|
+
extra_query: Query | None = None,
|
|
2244
|
+
extra_body: Body | None = None,
|
|
2245
|
+
timeout: float | httpx.Timeout | None | NotGiven = NOT_GIVEN,
|
|
2246
|
+
idempotency_key: str | None = None,
|
|
2247
|
+
) -> DevboxAsyncExecutionDetailView:
|
|
2248
|
+
"""
|
|
2249
|
+
Execute a command and wait for it to complete with optimal latency for long running commands.
|
|
2250
|
+
|
|
2251
|
+
This method launches an execution with a generated command_id and first attempts to
|
|
2252
|
+
return the result within the initial request's timeout. If the execution is not yet
|
|
2253
|
+
complete, it switches to using wait_for_command to minimize latency while waiting.
|
|
2254
|
+
"""
|
|
2255
|
+
|
|
2256
|
+
command_id = str(uuid7()) # type: ignore
|
|
2257
|
+
execution = await self.execute(
|
|
2258
|
+
devbox_id,
|
|
2259
|
+
command=command,
|
|
2260
|
+
command_id=command_id,
|
|
2261
|
+
shell_name=shell_name,
|
|
2262
|
+
extra_headers=extra_headers,
|
|
2263
|
+
extra_query=extra_query,
|
|
2264
|
+
extra_body=extra_body,
|
|
2265
|
+
timeout=timeout,
|
|
2266
|
+
idempotency_key=idempotency_key,
|
|
2267
|
+
)
|
|
2268
|
+
if execution.status == "completed":
|
|
2269
|
+
return execution
|
|
2270
|
+
|
|
2271
|
+
def handle_timeout_error(error: Exception) -> DevboxAsyncExecutionDetailView:
|
|
2272
|
+
if isinstance(error, APITimeoutError) or (
|
|
2273
|
+
isinstance(error, APIStatusError) and error.response.status_code == 408
|
|
2274
|
+
):
|
|
2275
|
+
return execution
|
|
2276
|
+
raise error
|
|
2277
|
+
|
|
2278
|
+
def is_done(result: DevboxAsyncExecutionDetailView) -> bool:
|
|
2279
|
+
return result.status == "completed"
|
|
2280
|
+
|
|
2281
|
+
return await async_poll_until(
|
|
2282
|
+
lambda: self.wait_for_command(execution.execution_id, devbox_id=devbox_id, statuses=["completed"]),
|
|
2283
|
+
is_done,
|
|
2284
|
+
polling_config,
|
|
2285
|
+
handle_timeout_error,
|
|
2286
|
+
)
|
|
2287
|
+
|
|
2178
2288
|
async def execute_async(
|
|
2179
2289
|
self,
|
|
2180
2290
|
id: str,
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
# Smoke tests
|
|
2
2
|
|
|
3
|
-
End-to-end smoke tests run against the real API to validate critical flows (devboxes, snapshots, blueprints, executions/log tailing, scenarios/benchmarks).
|
|
3
|
+
End-to-end smoke tests run against the real API to validate critical flows (devboxes, snapshots, blueprints, executions/log tailing, scenarios/benchmarks). Theses smoketests run both the
|
|
4
|
+
async and sync clients.
|
|
4
5
|
|
|
5
6
|
- Local run (requires `RUNLOOP_API_KEY`):
|
|
6
7
|
|
|
@@ -13,13 +14,13 @@ export RUNLOOP_API_KEY=... # required
|
|
|
13
14
|
uv pip install -r requirements-dev.lock
|
|
14
15
|
|
|
15
16
|
# Run all tests
|
|
16
|
-
RUN_SMOKETESTS=1 uv run pytest -q -vv tests/smoketests
|
|
17
|
+
RUN_SMOKETESTS=1 uv run pytest -q -vv -m smoketest tests/smoketests
|
|
17
18
|
|
|
18
19
|
# Run a single file
|
|
19
|
-
RUN_SMOKETESTS=1 uv run pytest -q -vv tests/smoketests/test_devboxes.py
|
|
20
|
+
RUN_SMOKETESTS=1 uv run pytest -q -vv -m smoketest tests/smoketests/test_devboxes.py
|
|
20
21
|
|
|
21
22
|
# Run a single test by name
|
|
22
|
-
RUN_SMOKETESTS=1 uv run pytest -q -k "test_create_and_await_running_timeout" tests/smoketests/test_devboxes.py
|
|
23
|
+
RUN_SMOKETESTS=1 uv run pytest -q -k -m smoketest "test_create_and_await_running_timeout" tests/smoketests/test_devboxes.py
|
|
23
24
|
```
|
|
24
25
|
|
|
25
26
|
- GitHub Actions: add repo secret `RUNLOOP_SMOKETEST_DEV_API_KEY` and `RUNLOOP_SMOKETEST_PROD_API_KEY`. The workflow `.github/workflows/smoketests.yml` supports an input `environment` (dev|prod) and runs these tests in CI.
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
from typing import Iterator
|
|
4
|
+
|
|
5
|
+
import pytest
|
|
6
|
+
from _pytest.fixtures import FixtureRequest # pyright: ignore[reportPrivateImportUsage]
|
|
7
|
+
|
|
8
|
+
from runloop_api_client import Runloop
|
|
9
|
+
|
|
10
|
+
from .utils import make_client, make_async_client_adapter
|
|
11
|
+
|
|
12
|
+
"""
|
|
13
|
+
This file is used to create a client fixture for the tests.
|
|
14
|
+
It makes it possible to run the tests with both sync and async clients.
|
|
15
|
+
"""
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
@pytest.fixture(scope="module", params=["sync", "async"], ids=["sync-client", "async-client"])
|
|
19
|
+
def client(request: FixtureRequest) -> Iterator[Runloop]:
|
|
20
|
+
if request.param == "sync":
|
|
21
|
+
c: Runloop = make_client()
|
|
22
|
+
try:
|
|
23
|
+
yield c
|
|
24
|
+
finally:
|
|
25
|
+
try:
|
|
26
|
+
# Runloop supports close()
|
|
27
|
+
c.close()
|
|
28
|
+
except Exception:
|
|
29
|
+
pass
|
|
30
|
+
else:
|
|
31
|
+
c: Runloop = make_async_client_adapter()
|
|
32
|
+
try:
|
|
33
|
+
yield c
|
|
34
|
+
finally:
|
|
35
|
+
try:
|
|
36
|
+
c.close()
|
|
37
|
+
except Exception:
|
|
38
|
+
pass
|
|
@@ -1,13 +1,26 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
from typing import Iterator
|
|
4
|
+
|
|
1
5
|
import pytest
|
|
2
6
|
|
|
7
|
+
from runloop_api_client import Runloop
|
|
3
8
|
from runloop_api_client.lib.polling import PollingConfig
|
|
4
9
|
|
|
5
|
-
from .utils import
|
|
10
|
+
from .utils import unique_name
|
|
6
11
|
|
|
7
12
|
pytestmark = [pytest.mark.smoketest]
|
|
8
13
|
|
|
9
14
|
|
|
10
|
-
|
|
15
|
+
@pytest.fixture(autouse=True, scope="module")
|
|
16
|
+
def _cleanup(client: Runloop) -> Iterator[None]: # pyright: ignore[reportUnusedFunction]
|
|
17
|
+
yield
|
|
18
|
+
global _blueprint_id
|
|
19
|
+
if _blueprint_id:
|
|
20
|
+
try:
|
|
21
|
+
client.blueprints.delete(_blueprint_id)
|
|
22
|
+
except Exception:
|
|
23
|
+
pass
|
|
11
24
|
|
|
12
25
|
|
|
13
26
|
"""
|
|
@@ -18,17 +31,8 @@ _blueprint_id = None
|
|
|
18
31
|
_blueprint_name = unique_name("bp")
|
|
19
32
|
|
|
20
33
|
|
|
21
|
-
def teardown_module() -> None:
|
|
22
|
-
global _blueprint_id
|
|
23
|
-
if _blueprint_id:
|
|
24
|
-
try:
|
|
25
|
-
client.blueprints.delete(_blueprint_id)
|
|
26
|
-
except Exception:
|
|
27
|
-
pass
|
|
28
|
-
|
|
29
|
-
|
|
30
34
|
@pytest.mark.timeout(30)
|
|
31
|
-
def test_create_blueprint_and_await_build() -> None:
|
|
35
|
+
def test_create_blueprint_and_await_build(client: Runloop) -> None:
|
|
32
36
|
global _blueprint_id
|
|
33
37
|
created = client.blueprints.create_and_await_build_complete(
|
|
34
38
|
name=_blueprint_name,
|
|
@@ -39,7 +43,7 @@ def test_create_blueprint_and_await_build() -> None:
|
|
|
39
43
|
|
|
40
44
|
|
|
41
45
|
@pytest.mark.timeout(30)
|
|
42
|
-
def test_start_devbox_from_base_blueprint_by_id() -> None:
|
|
46
|
+
def test_start_devbox_from_base_blueprint_by_id(client: Runloop) -> None:
|
|
43
47
|
assert _blueprint_id
|
|
44
48
|
devbox = client.devboxes.create_and_await_running(
|
|
45
49
|
blueprint_id=_blueprint_id,
|
|
@@ -51,7 +55,7 @@ def test_start_devbox_from_base_blueprint_by_id() -> None:
|
|
|
51
55
|
|
|
52
56
|
|
|
53
57
|
@pytest.mark.timeout(30)
|
|
54
|
-
def test_start_devbox_from_base_blueprint_by_name() -> None:
|
|
58
|
+
def test_start_devbox_from_base_blueprint_by_name(client: Runloop) -> None:
|
|
55
59
|
devbox = client.devboxes.create_and_await_running(
|
|
56
60
|
blueprint_name=_blueprint_name,
|
|
57
61
|
polling_config=PollingConfig(max_attempts=120, interval_seconds=5.0, timeout_seconds=20 * 60),
|
|
@@ -1,13 +1,27 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
from typing import Iterator
|
|
4
|
+
|
|
1
5
|
import pytest
|
|
2
6
|
|
|
7
|
+
from runloop_api_client import Runloop
|
|
3
8
|
from runloop_api_client.lib.polling import PollingConfig, PollingTimeout
|
|
4
9
|
|
|
5
|
-
from .utils import
|
|
10
|
+
from .utils import unique_name
|
|
6
11
|
|
|
7
12
|
pytestmark = [pytest.mark.smoketest]
|
|
8
13
|
|
|
9
14
|
|
|
10
|
-
|
|
15
|
+
@pytest.fixture(autouse=True, scope="module")
|
|
16
|
+
def _cleanup(client: Runloop) -> Iterator[None]: # pyright: ignore[reportUnusedFunction]
|
|
17
|
+
yield
|
|
18
|
+
global _devbox_id
|
|
19
|
+
if _devbox_id:
|
|
20
|
+
try:
|
|
21
|
+
client.devboxes.shutdown(_devbox_id)
|
|
22
|
+
except Exception:
|
|
23
|
+
pass
|
|
24
|
+
|
|
11
25
|
|
|
12
26
|
"""
|
|
13
27
|
Tests are run sequentially and can be dependent on each other.
|
|
@@ -17,14 +31,14 @@ _devbox_id = None
|
|
|
17
31
|
|
|
18
32
|
|
|
19
33
|
@pytest.mark.timeout(30)
|
|
20
|
-
def test_create_devbox() -> None:
|
|
34
|
+
def test_create_devbox(client: Runloop) -> None:
|
|
21
35
|
created = client.devboxes.create(name=unique_name("smoke-devbox"))
|
|
22
36
|
assert created.id
|
|
23
37
|
client.devboxes.shutdown(created.id)
|
|
24
38
|
|
|
25
39
|
|
|
26
40
|
@pytest.mark.timeout(30)
|
|
27
|
-
def test_await_running_create_and_await_running() -> None:
|
|
41
|
+
def test_await_running_create_and_await_running(client: Runloop) -> None:
|
|
28
42
|
global _devbox_id
|
|
29
43
|
created = client.devboxes.create_and_await_running(
|
|
30
44
|
name=unique_name("smoketest-devbox2"),
|
|
@@ -34,19 +48,19 @@ def test_await_running_create_and_await_running() -> None:
|
|
|
34
48
|
_devbox_id = created.id
|
|
35
49
|
|
|
36
50
|
|
|
37
|
-
def test_list_devboxes() -> None:
|
|
51
|
+
def test_list_devboxes(client: Runloop) -> None:
|
|
38
52
|
page = client.devboxes.list(limit=10)
|
|
39
53
|
assert isinstance(page.devboxes, list)
|
|
40
54
|
assert len(page.devboxes) > 0
|
|
41
55
|
|
|
42
56
|
|
|
43
|
-
def test_retrieve_devbox() -> None:
|
|
57
|
+
def test_retrieve_devbox(client: Runloop) -> None:
|
|
44
58
|
assert _devbox_id
|
|
45
59
|
view = client.devboxes.retrieve(_devbox_id)
|
|
46
60
|
assert view.id == _devbox_id
|
|
47
61
|
|
|
48
62
|
|
|
49
|
-
def test_shutdown_devbox() -> None:
|
|
63
|
+
def test_shutdown_devbox(client: Runloop) -> None:
|
|
50
64
|
assert _devbox_id
|
|
51
65
|
view = client.devboxes.shutdown(_devbox_id)
|
|
52
66
|
assert view.id == _devbox_id
|
|
@@ -54,7 +68,7 @@ def test_shutdown_devbox() -> None:
|
|
|
54
68
|
|
|
55
69
|
|
|
56
70
|
@pytest.mark.timeout(90)
|
|
57
|
-
def test_create_and_await_running_long_set_up() -> None:
|
|
71
|
+
def test_create_and_await_running_long_set_up(client: Runloop) -> None:
|
|
58
72
|
created = client.devboxes.create_and_await_running(
|
|
59
73
|
name=unique_name("smoketest-devbox-await-running-long-set-up"),
|
|
60
74
|
launch_parameters={"launch_commands": ["sleep 70"]},
|
|
@@ -65,7 +79,7 @@ def test_create_and_await_running_long_set_up() -> None:
|
|
|
65
79
|
|
|
66
80
|
|
|
67
81
|
@pytest.mark.timeout(30)
|
|
68
|
-
def test_create_and_await_running_timeout() -> None:
|
|
82
|
+
def test_create_and_await_running_timeout(client: Runloop) -> None:
|
|
69
83
|
with pytest.raises(PollingTimeout):
|
|
70
84
|
client.devboxes.create_and_await_running(
|
|
71
85
|
name=unique_name("smoketest-devbox-await-running-timeout"),
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
from typing import Iterator
|
|
4
|
+
|
|
5
|
+
import pytest
|
|
6
|
+
|
|
7
|
+
from runloop_api_client import Runloop
|
|
8
|
+
from runloop_api_client.lib.polling import PollingConfig
|
|
9
|
+
|
|
10
|
+
from .utils import unique_name
|
|
11
|
+
|
|
12
|
+
pytestmark = [pytest.mark.smoketest]
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
@pytest.fixture(autouse=True, scope="module")
|
|
16
|
+
def _cleanup(client: Runloop) -> Iterator[None]: # pyright: ignore[reportUnusedFunction]
|
|
17
|
+
yield
|
|
18
|
+
global _devbox_id
|
|
19
|
+
if _devbox_id:
|
|
20
|
+
try:
|
|
21
|
+
client.devboxes.shutdown(_devbox_id)
|
|
22
|
+
except Exception:
|
|
23
|
+
pass
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
"""
|
|
27
|
+
Tests are run sequentially and can be dependent on each other.
|
|
28
|
+
This is to avoid overloading resources and save efficiency.
|
|
29
|
+
"""
|
|
30
|
+
_devbox_id = None
|
|
31
|
+
_exec_id = None
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
@pytest.mark.timeout(30)
|
|
35
|
+
def test_launch_devbox(client: Runloop) -> None:
|
|
36
|
+
global _devbox_id
|
|
37
|
+
created = client.devboxes.create_and_await_running(
|
|
38
|
+
name=unique_name("exec-devbox"),
|
|
39
|
+
polling_config=PollingConfig(max_attempts=120, interval_seconds=5.0, timeout_seconds=20 * 60),
|
|
40
|
+
)
|
|
41
|
+
_devbox_id = created.id
|
|
42
|
+
|
|
43
|
+
|
|
44
|
+
@pytest.mark.timeout(30)
|
|
45
|
+
def test_execute_async_and_await_completion(client: Runloop) -> None:
|
|
46
|
+
assert _devbox_id
|
|
47
|
+
global _exec_id
|
|
48
|
+
started = client.devboxes.executions.execute_async(_devbox_id, command="echo hello && sleep 1")
|
|
49
|
+
_exec_id = started.execution_id
|
|
50
|
+
completed = client.devboxes.executions.await_completed(
|
|
51
|
+
_exec_id,
|
|
52
|
+
devbox_id=_devbox_id,
|
|
53
|
+
polling_config=PollingConfig(max_attempts=120, interval_seconds=2.0, timeout_seconds=10 * 60),
|
|
54
|
+
)
|
|
55
|
+
assert completed.status == "completed"
|
|
56
|
+
|
|
57
|
+
|
|
58
|
+
@pytest.mark.timeout(30)
|
|
59
|
+
def test_tail_stdout_logs(client: Runloop) -> None:
|
|
60
|
+
assert _devbox_id and _exec_id
|
|
61
|
+
stream = client.devboxes.executions.stream_stdout_updates(execution_id=_exec_id, devbox_id=_devbox_id)
|
|
62
|
+
received = ""
|
|
63
|
+
for chunk in stream:
|
|
64
|
+
received += getattr(chunk, "output", "") or ""
|
|
65
|
+
if received:
|
|
66
|
+
break
|
|
67
|
+
assert isinstance(received, str)
|
|
68
|
+
|
|
69
|
+
|
|
70
|
+
@pytest.mark.timeout(30)
|
|
71
|
+
def test_execute_and_await_completion(client: Runloop) -> None:
|
|
72
|
+
assert _devbox_id
|
|
73
|
+
completed = client.devboxes.execute_and_await_completion(
|
|
74
|
+
_devbox_id,
|
|
75
|
+
command="echo hello && sleep 1",
|
|
76
|
+
polling_config=PollingConfig(max_attempts=120, interval_seconds=2.0, timeout_seconds=10 * 60),
|
|
77
|
+
)
|
|
78
|
+
assert completed.status == "completed"
|
|
79
|
+
|
|
80
|
+
|
|
81
|
+
# @pytest.mark.timeout(90)
|
|
82
|
+
# def test_execute_and_await_completion_long_running(client: Runloop) -> None:
|
|
83
|
+
# assert _devbox_id
|
|
84
|
+
# completed = client.devboxes.execute_and_await_completion(
|
|
85
|
+
# _devbox_id,
|
|
86
|
+
# command="echo hello && sleep 70",
|
|
87
|
+
# polling_config=PollingConfig(max_attempts=120, interval_seconds=2.0),
|
|
88
|
+
# )
|
|
89
|
+
# assert completed.status == "completed"
|
|
90
|
+
|
|
91
|
+
|
|
92
|
+
# TODO: Uncomment this test when we fix timeouts for polling
|
|
93
|
+
# @pytest.mark.timeout(30)
|
|
94
|
+
# def test_execute_and_await_completion_timeout() -> None:
|
|
95
|
+
# assert _devbox_id
|
|
96
|
+
# with pytest.raises(PollingTimeout):
|
|
97
|
+
# client.devboxes.execute_and_await_completion(
|
|
98
|
+
# devbox_id=_devbox_id,
|
|
99
|
+
# command="echo hello && sleep 10",
|
|
100
|
+
# polling_config=PollingConfig(max_attempts=1, interval_seconds=2.0, timeout_seconds=3),
|
|
101
|
+
# )
|