runloop_api_client 1.5.1__py3-none-any.whl

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.
Files changed (261) hide show
  1. runloop_api_client/__init__.py +95 -0
  2. runloop_api_client/_base_client.py +2127 -0
  3. runloop_api_client/_client.py +866 -0
  4. runloop_api_client/_compat.py +219 -0
  5. runloop_api_client/_constants.py +23 -0
  6. runloop_api_client/_exceptions.py +108 -0
  7. runloop_api_client/_files.py +123 -0
  8. runloop_api_client/_models.py +872 -0
  9. runloop_api_client/_qs.py +150 -0
  10. runloop_api_client/_resource.py +43 -0
  11. runloop_api_client/_response.py +832 -0
  12. runloop_api_client/_streaming.py +518 -0
  13. runloop_api_client/_types.py +270 -0
  14. runloop_api_client/_utils/__init__.py +65 -0
  15. runloop_api_client/_utils/_compat.py +45 -0
  16. runloop_api_client/_utils/_datetime_parse.py +136 -0
  17. runloop_api_client/_utils/_json.py +35 -0
  18. runloop_api_client/_utils/_logs.py +25 -0
  19. runloop_api_client/_utils/_proxy.py +65 -0
  20. runloop_api_client/_utils/_reflection.py +42 -0
  21. runloop_api_client/_utils/_resources_proxy.py +24 -0
  22. runloop_api_client/_utils/_streams.py +12 -0
  23. runloop_api_client/_utils/_sync.py +58 -0
  24. runloop_api_client/_utils/_transform.py +457 -0
  25. runloop_api_client/_utils/_typing.py +156 -0
  26. runloop_api_client/_utils/_utils.py +421 -0
  27. runloop_api_client/_utils/_validation.py +31 -0
  28. runloop_api_client/_version.py +4 -0
  29. runloop_api_client/lib/.keep +4 -0
  30. runloop_api_client/lib/__init__.py +3 -0
  31. runloop_api_client/lib/_ignore.py +496 -0
  32. runloop_api_client/lib/context_loader.py +78 -0
  33. runloop_api_client/lib/polling.py +75 -0
  34. runloop_api_client/lib/polling_async.py +60 -0
  35. runloop_api_client/pagination.py +986 -0
  36. runloop_api_client/py.typed +0 -0
  37. runloop_api_client/resources/__init__.py +173 -0
  38. runloop_api_client/resources/agents.py +431 -0
  39. runloop_api_client/resources/benchmark_jobs.py +394 -0
  40. runloop_api_client/resources/benchmark_runs.py +595 -0
  41. runloop_api_client/resources/benchmarks.py +1085 -0
  42. runloop_api_client/resources/blueprints.py +1563 -0
  43. runloop_api_client/resources/devboxes/__init__.py +89 -0
  44. runloop_api_client/resources/devboxes/browsers.py +267 -0
  45. runloop_api_client/resources/devboxes/computers.py +648 -0
  46. runloop_api_client/resources/devboxes/devboxes.py +3784 -0
  47. runloop_api_client/resources/devboxes/disk_snapshots.py +602 -0
  48. runloop_api_client/resources/devboxes/executions.py +1212 -0
  49. runloop_api_client/resources/devboxes/logs.py +197 -0
  50. runloop_api_client/resources/gateway_configs.py +658 -0
  51. runloop_api_client/resources/network_policies.py +680 -0
  52. runloop_api_client/resources/objects.py +870 -0
  53. runloop_api_client/resources/repositories.py +918 -0
  54. runloop_api_client/resources/scenarios/__init__.py +47 -0
  55. runloop_api_client/resources/scenarios/runs.py +973 -0
  56. runloop_api_client/resources/scenarios/scenarios.py +1101 -0
  57. runloop_api_client/resources/scenarios/scorers.py +629 -0
  58. runloop_api_client/resources/secrets.py +500 -0
  59. runloop_api_client/sdk/__init__.py +117 -0
  60. runloop_api_client/sdk/_helpers.py +49 -0
  61. runloop_api_client/sdk/_types.py +264 -0
  62. runloop_api_client/sdk/agent.py +70 -0
  63. runloop_api_client/sdk/async_.py +1036 -0
  64. runloop_api_client/sdk/async_agent.py +70 -0
  65. runloop_api_client/sdk/async_benchmark.py +169 -0
  66. runloop_api_client/sdk/async_benchmark_run.py +127 -0
  67. runloop_api_client/sdk/async_blueprint.py +104 -0
  68. runloop_api_client/sdk/async_devbox.py +797 -0
  69. runloop_api_client/sdk/async_execution.py +144 -0
  70. runloop_api_client/sdk/async_execution_result.py +175 -0
  71. runloop_api_client/sdk/async_network_policy.py +80 -0
  72. runloop_api_client/sdk/async_scenario.py +118 -0
  73. runloop_api_client/sdk/async_scenario_builder.py +480 -0
  74. runloop_api_client/sdk/async_scenario_run.py +242 -0
  75. runloop_api_client/sdk/async_scorer.py +77 -0
  76. runloop_api_client/sdk/async_snapshot.py +125 -0
  77. runloop_api_client/sdk/async_storage_object.py +188 -0
  78. runloop_api_client/sdk/benchmark.py +167 -0
  79. runloop_api_client/sdk/benchmark_run.py +127 -0
  80. runloop_api_client/sdk/blueprint.py +104 -0
  81. runloop_api_client/sdk/devbox.py +800 -0
  82. runloop_api_client/sdk/execution.py +132 -0
  83. runloop_api_client/sdk/execution_result.py +173 -0
  84. runloop_api_client/sdk/network_policy.py +80 -0
  85. runloop_api_client/sdk/scenario.py +118 -0
  86. runloop_api_client/sdk/scenario_builder.py +480 -0
  87. runloop_api_client/sdk/scenario_run.py +242 -0
  88. runloop_api_client/sdk/scorer.py +77 -0
  89. runloop_api_client/sdk/snapshot.py +125 -0
  90. runloop_api_client/sdk/storage_object.py +188 -0
  91. runloop_api_client/sdk/sync.py +1061 -0
  92. runloop_api_client/types/__init__.py +130 -0
  93. runloop_api_client/types/agent_create_params.py +21 -0
  94. runloop_api_client/types/agent_list_params.py +27 -0
  95. runloop_api_client/types/agent_list_view.py +24 -0
  96. runloop_api_client/types/agent_view.py +30 -0
  97. runloop_api_client/types/benchmark_create_params.py +40 -0
  98. runloop_api_client/types/benchmark_definitions_params.py +15 -0
  99. runloop_api_client/types/benchmark_job_create_params.py +220 -0
  100. runloop_api_client/types/benchmark_job_list_params.py +18 -0
  101. runloop_api_client/types/benchmark_job_list_view.py +19 -0
  102. runloop_api_client/types/benchmark_job_view.py +344 -0
  103. runloop_api_client/types/benchmark_list_params.py +18 -0
  104. runloop_api_client/types/benchmark_list_public_params.py +15 -0
  105. runloop_api_client/types/benchmark_run_list_params.py +21 -0
  106. runloop_api_client/types/benchmark_run_list_scenario_runs_params.py +18 -0
  107. runloop_api_client/types/benchmark_run_list_view.py +19 -0
  108. runloop_api_client/types/benchmark_run_view.py +58 -0
  109. runloop_api_client/types/benchmark_start_run_params.py +29 -0
  110. runloop_api_client/types/benchmark_update_params.py +42 -0
  111. runloop_api_client/types/benchmark_update_scenarios_params.py +18 -0
  112. runloop_api_client/types/benchmark_view.py +49 -0
  113. runloop_api_client/types/blueprint_build_log.py +16 -0
  114. runloop_api_client/types/blueprint_build_logs_list_view.py +16 -0
  115. runloop_api_client/types/blueprint_build_parameters.py +119 -0
  116. runloop_api_client/types/blueprint_create_from_inspection_params.py +49 -0
  117. runloop_api_client/types/blueprint_create_params.py +121 -0
  118. runloop_api_client/types/blueprint_list_params.py +21 -0
  119. runloop_api_client/types/blueprint_list_public_params.py +21 -0
  120. runloop_api_client/types/blueprint_list_view.py +19 -0
  121. runloop_api_client/types/blueprint_preview_params.py +121 -0
  122. runloop_api_client/types/blueprint_preview_view.py +10 -0
  123. runloop_api_client/types/blueprint_view.py +93 -0
  124. runloop_api_client/types/devbox_async_execution_detail_view.py +46 -0
  125. runloop_api_client/types/devbox_create_params.py +124 -0
  126. runloop_api_client/types/devbox_create_ssh_key_response.py +19 -0
  127. runloop_api_client/types/devbox_create_tunnel_params.py +12 -0
  128. runloop_api_client/types/devbox_download_file_params.py +15 -0
  129. runloop_api_client/types/devbox_enable_tunnel_params.py +13 -0
  130. runloop_api_client/types/devbox_execute_async_params.py +33 -0
  131. runloop_api_client/types/devbox_execute_params.py +37 -0
  132. runloop_api_client/types/devbox_execute_sync_params.py +31 -0
  133. runloop_api_client/types/devbox_execution_detail_view.py +24 -0
  134. runloop_api_client/types/devbox_list_disk_snapshots_params.py +32 -0
  135. runloop_api_client/types/devbox_list_params.py +20 -0
  136. runloop_api_client/types/devbox_list_view.py +19 -0
  137. runloop_api_client/types/devbox_read_file_contents_params.py +15 -0
  138. runloop_api_client/types/devbox_read_file_contents_response.py +7 -0
  139. runloop_api_client/types/devbox_remove_tunnel_params.py +12 -0
  140. runloop_api_client/types/devbox_send_std_in_result.py +16 -0
  141. runloop_api_client/types/devbox_snapshot_disk_async_params.py +19 -0
  142. runloop_api_client/types/devbox_snapshot_disk_params.py +19 -0
  143. runloop_api_client/types/devbox_snapshot_list_view.py +19 -0
  144. runloop_api_client/types/devbox_snapshot_view.py +30 -0
  145. runloop_api_client/types/devbox_tunnel_view.py +16 -0
  146. runloop_api_client/types/devbox_update_params.py +16 -0
  147. runloop_api_client/types/devbox_upload_file_params.py +19 -0
  148. runloop_api_client/types/devbox_view.py +121 -0
  149. runloop_api_client/types/devbox_wait_for_command_params.py +28 -0
  150. runloop_api_client/types/devbox_write_file_contents_params.py +18 -0
  151. runloop_api_client/types/devboxes/__init__.py +33 -0
  152. runloop_api_client/types/devboxes/browser_create_params.py +13 -0
  153. runloop_api_client/types/devboxes/browser_view.py +29 -0
  154. runloop_api_client/types/devboxes/computer_create_params.py +26 -0
  155. runloop_api_client/types/devboxes/computer_keyboard_interaction_params.py +16 -0
  156. runloop_api_client/types/devboxes/computer_keyboard_interaction_response.py +15 -0
  157. runloop_api_client/types/devboxes/computer_mouse_interaction_params.py +35 -0
  158. runloop_api_client/types/devboxes/computer_mouse_interaction_response.py +15 -0
  159. runloop_api_client/types/devboxes/computer_screen_interaction_params.py +12 -0
  160. runloop_api_client/types/devboxes/computer_screen_interaction_response.py +15 -0
  161. runloop_api_client/types/devboxes/computer_view.py +23 -0
  162. runloop_api_client/types/devboxes/devbox_logs_list_view.py +39 -0
  163. runloop_api_client/types/devboxes/devbox_snapshot_async_status_view.py +20 -0
  164. runloop_api_client/types/devboxes/disk_snapshot_list_params.py +32 -0
  165. runloop_api_client/types/devboxes/disk_snapshot_update_params.py +19 -0
  166. runloop_api_client/types/devboxes/execution_execute_async_params.py +31 -0
  167. runloop_api_client/types/devboxes/execution_execute_sync_params.py +31 -0
  168. runloop_api_client/types/devboxes/execution_kill_params.py +18 -0
  169. runloop_api_client/types/devboxes/execution_retrieve_params.py +14 -0
  170. runloop_api_client/types/devboxes/execution_send_std_in_params.py +18 -0
  171. runloop_api_client/types/devboxes/execution_stream_stderr_updates_params.py +17 -0
  172. runloop_api_client/types/devboxes/execution_stream_stdout_updates_params.py +17 -0
  173. runloop_api_client/types/devboxes/execution_update_chunk.py +15 -0
  174. runloop_api_client/types/devboxes/log_list_params.py +15 -0
  175. runloop_api_client/types/gateway_config_create_params.py +41 -0
  176. runloop_api_client/types/gateway_config_list_params.py +21 -0
  177. runloop_api_client/types/gateway_config_list_view.py +21 -0
  178. runloop_api_client/types/gateway_config_update_params.py +32 -0
  179. runloop_api_client/types/gateway_config_view.py +47 -0
  180. runloop_api_client/types/input_context.py +19 -0
  181. runloop_api_client/types/input_context_param.py +20 -0
  182. runloop_api_client/types/input_context_update_param.py +16 -0
  183. runloop_api_client/types/inspection_source_param.py +18 -0
  184. runloop_api_client/types/network_policy_create_params.py +40 -0
  185. runloop_api_client/types/network_policy_list_params.py +21 -0
  186. runloop_api_client/types/network_policy_list_view.py +21 -0
  187. runloop_api_client/types/network_policy_update_params.py +30 -0
  188. runloop_api_client/types/network_policy_view.py +52 -0
  189. runloop_api_client/types/object_create_params.py +30 -0
  190. runloop_api_client/types/object_download_params.py +12 -0
  191. runloop_api_client/types/object_download_url_view.py +12 -0
  192. runloop_api_client/types/object_list_params.py +27 -0
  193. runloop_api_client/types/object_list_public_params.py +27 -0
  194. runloop_api_client/types/object_list_view.py +24 -0
  195. runloop_api_client/types/object_view.py +36 -0
  196. runloop_api_client/types/repository_connection_list_view.py +19 -0
  197. runloop_api_client/types/repository_connection_view.py +18 -0
  198. runloop_api_client/types/repository_create_params.py +22 -0
  199. runloop_api_client/types/repository_inspect_params.py +13 -0
  200. runloop_api_client/types/repository_inspection_details.py +83 -0
  201. runloop_api_client/types/repository_inspection_list_view.py +13 -0
  202. runloop_api_client/types/repository_list_params.py +21 -0
  203. runloop_api_client/types/repository_manifest_view.py +174 -0
  204. runloop_api_client/types/repository_refresh_params.py +16 -0
  205. runloop_api_client/types/scenario_create_params.py +53 -0
  206. runloop_api_client/types/scenario_definition_list_view.py +19 -0
  207. runloop_api_client/types/scenario_environment.py +29 -0
  208. runloop_api_client/types/scenario_environment_param.py +31 -0
  209. runloop_api_client/types/scenario_list_params.py +24 -0
  210. runloop_api_client/types/scenario_list_public_params.py +18 -0
  211. runloop_api_client/types/scenario_run_list_view.py +19 -0
  212. runloop_api_client/types/scenario_run_view.py +55 -0
  213. runloop_api_client/types/scenario_start_run_params.py +30 -0
  214. runloop_api_client/types/scenario_update_params.py +49 -0
  215. runloop_api_client/types/scenario_view.py +61 -0
  216. runloop_api_client/types/scenarios/__init__.py +14 -0
  217. runloop_api_client/types/scenarios/run_list_params.py +27 -0
  218. runloop_api_client/types/scenarios/scorer_create_params.py +18 -0
  219. runloop_api_client/types/scenarios/scorer_create_response.py +18 -0
  220. runloop_api_client/types/scenarios/scorer_list_params.py +15 -0
  221. runloop_api_client/types/scenarios/scorer_list_response.py +18 -0
  222. runloop_api_client/types/scenarios/scorer_retrieve_response.py +18 -0
  223. runloop_api_client/types/scenarios/scorer_update_params.py +18 -0
  224. runloop_api_client/types/scenarios/scorer_update_response.py +18 -0
  225. runloop_api_client/types/scenarios/scorer_validate_params.py +17 -0
  226. runloop_api_client/types/scenarios/scorer_validate_response.py +23 -0
  227. runloop_api_client/types/scoring_contract.py +17 -0
  228. runloop_api_client/types/scoring_contract_param.py +19 -0
  229. runloop_api_client/types/scoring_contract_result_view.py +20 -0
  230. runloop_api_client/types/scoring_contract_update_param.py +15 -0
  231. runloop_api_client/types/scoring_function.py +157 -0
  232. runloop_api_client/types/scoring_function_param.py +153 -0
  233. runloop_api_client/types/scoring_function_result_view.py +25 -0
  234. runloop_api_client/types/secret_create_params.py +23 -0
  235. runloop_api_client/types/secret_list_params.py +12 -0
  236. runloop_api_client/types/secret_list_view.py +24 -0
  237. runloop_api_client/types/secret_update_params.py +16 -0
  238. runloop_api_client/types/secret_view.py +26 -0
  239. runloop_api_client/types/shared/__init__.py +10 -0
  240. runloop_api_client/types/shared/after_idle.py +15 -0
  241. runloop_api_client/types/shared/agent_mount.py +31 -0
  242. runloop_api_client/types/shared/agent_source.py +75 -0
  243. runloop_api_client/types/shared/code_mount_parameters.py +24 -0
  244. runloop_api_client/types/shared/launch_parameters.py +86 -0
  245. runloop_api_client/types/shared/mount.py +43 -0
  246. runloop_api_client/types/shared/object_mount.py +21 -0
  247. runloop_api_client/types/shared/run_profile.py +37 -0
  248. runloop_api_client/types/shared_params/__init__.py +10 -0
  249. runloop_api_client/types/shared_params/after_idle.py +15 -0
  250. runloop_api_client/types/shared_params/agent_mount.py +31 -0
  251. runloop_api_client/types/shared_params/agent_source.py +78 -0
  252. runloop_api_client/types/shared_params/code_mount_parameters.py +25 -0
  253. runloop_api_client/types/shared_params/launch_parameters.py +88 -0
  254. runloop_api_client/types/shared_params/mount.py +43 -0
  255. runloop_api_client/types/shared_params/object_mount.py +21 -0
  256. runloop_api_client/types/shared_params/run_profile.py +38 -0
  257. runloop_api_client/types/tunnel_view.py +34 -0
  258. runloop_api_client-1.5.1.dist-info/METADATA +522 -0
  259. runloop_api_client-1.5.1.dist-info/RECORD +261 -0
  260. runloop_api_client-1.5.1.dist-info/WHEEL +4 -0
  261. runloop_api_client-1.5.1.dist-info/licenses/LICENSE +7 -0
@@ -0,0 +1,3784 @@
1
+ # File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
2
+
3
+ from __future__ import annotations
4
+
5
+ import typing_extensions
6
+ from typing import Dict, List, Mapping, Iterable, Optional, TypedDict, cast
7
+ from typing_extensions import Literal
8
+
9
+ import httpx
10
+
11
+ # uuid_utils is not typed
12
+ from uuid_utils import uuid7 # type: ignore
13
+
14
+ from .logs import (
15
+ LogsResource,
16
+ AsyncLogsResource,
17
+ LogsResourceWithRawResponse,
18
+ AsyncLogsResourceWithRawResponse,
19
+ LogsResourceWithStreamingResponse,
20
+ AsyncLogsResourceWithStreamingResponse,
21
+ )
22
+ from ...types import (
23
+ devbox_list_params,
24
+ devbox_create_params,
25
+ devbox_update_params,
26
+ devbox_execute_params,
27
+ devbox_upload_file_params,
28
+ devbox_execute_sync_params,
29
+ devbox_create_tunnel_params,
30
+ devbox_download_file_params,
31
+ devbox_enable_tunnel_params,
32
+ devbox_execute_async_params,
33
+ devbox_remove_tunnel_params,
34
+ devbox_snapshot_disk_params,
35
+ devbox_wait_for_command_params,
36
+ devbox_read_file_contents_params,
37
+ devbox_list_disk_snapshots_params,
38
+ devbox_snapshot_disk_async_params,
39
+ devbox_write_file_contents_params,
40
+ )
41
+ from ..._types import Body, Omit, Query, Headers, NotGiven, FileTypes, omit, not_given
42
+ from ..._utils import is_given, extract_files, maybe_transform, deepcopy_minimal, async_maybe_transform
43
+ from .browsers import (
44
+ BrowsersResource,
45
+ AsyncBrowsersResource,
46
+ BrowsersResourceWithRawResponse,
47
+ AsyncBrowsersResourceWithRawResponse,
48
+ BrowsersResourceWithStreamingResponse,
49
+ AsyncBrowsersResourceWithStreamingResponse,
50
+ )
51
+ from ..._compat import cached_property
52
+ from .computers import (
53
+ ComputersResource,
54
+ AsyncComputersResource,
55
+ ComputersResourceWithRawResponse,
56
+ AsyncComputersResourceWithRawResponse,
57
+ ComputersResourceWithStreamingResponse,
58
+ AsyncComputersResourceWithStreamingResponse,
59
+ )
60
+ from .executions import (
61
+ ExecutionsResource,
62
+ AsyncExecutionsResource,
63
+ ExecutionsResourceWithRawResponse,
64
+ AsyncExecutionsResourceWithRawResponse,
65
+ ExecutionsResourceWithStreamingResponse,
66
+ AsyncExecutionsResourceWithStreamingResponse,
67
+ )
68
+ from ..._resource import SyncAPIResource, AsyncAPIResource
69
+ from ..._response import (
70
+ BinaryAPIResponse,
71
+ AsyncBinaryAPIResponse,
72
+ StreamedBinaryAPIResponse,
73
+ AsyncStreamedBinaryAPIResponse,
74
+ to_raw_response_wrapper,
75
+ to_streamed_response_wrapper,
76
+ async_to_raw_response_wrapper,
77
+ to_custom_raw_response_wrapper,
78
+ async_to_streamed_response_wrapper,
79
+ to_custom_streamed_response_wrapper,
80
+ async_to_custom_raw_response_wrapper,
81
+ async_to_custom_streamed_response_wrapper,
82
+ )
83
+ from ..._constants import DEFAULT_TIMEOUT
84
+ from ...pagination import (
85
+ SyncDevboxesCursorIDPage,
86
+ AsyncDevboxesCursorIDPage,
87
+ SyncDiskSnapshotsCursorIDPage,
88
+ AsyncDiskSnapshotsCursorIDPage,
89
+ )
90
+ from ..._exceptions import RunloopError, APIStatusError, APITimeoutError
91
+ from ...lib.polling import PollingConfig, poll_until
92
+ from ..._base_client import AsyncPaginator, make_request_options
93
+ from .disk_snapshots import (
94
+ DiskSnapshotsResource,
95
+ AsyncDiskSnapshotsResource,
96
+ DiskSnapshotsResourceWithRawResponse,
97
+ AsyncDiskSnapshotsResourceWithRawResponse,
98
+ DiskSnapshotsResourceWithStreamingResponse,
99
+ AsyncDiskSnapshotsResourceWithStreamingResponse,
100
+ )
101
+ from ...lib.polling_async import async_poll_until
102
+ from ...types.devbox_view import DevboxView
103
+ from ...types.tunnel_view import TunnelView
104
+ from ...types.devbox_tunnel_view import DevboxTunnelView
105
+ from ...types.shared_params.mount import Mount
106
+ from ...types.devbox_snapshot_view import DevboxSnapshotView
107
+ from ...types.shared.launch_parameters import LaunchParameters as SharedLaunchParameters
108
+ from ...types.devbox_execution_detail_view import DevboxExecutionDetailView
109
+ from ...types.devbox_create_ssh_key_response import DevboxCreateSSHKeyResponse
110
+ from ...types.shared_params.launch_parameters import LaunchParameters
111
+ from ...types.devbox_async_execution_detail_view import DevboxAsyncExecutionDetailView
112
+ from ...types.shared_params.code_mount_parameters import CodeMountParameters
113
+
114
+ __all__ = ["DevboxesResource", "AsyncDevboxesResource", "DevboxRequestArgs"]
115
+
116
+ DEVBOX_BOOTING_STATES = frozenset(("provisioning", "initializing"))
117
+ DEVBOX_TERMINAL_STATES = frozenset(("suspended", "failure", "shutdown"))
118
+
119
+
120
+ # Type for request arguments that combine polling config with additional request options
121
+ class DevboxRequestArgs(TypedDict, total=False):
122
+ polling_config: PollingConfig | None
123
+ extra_headers: Headers | None
124
+ extra_query: Query | None
125
+ extra_body: Body | None
126
+ timeout: float | httpx.Timeout | None | NotGiven
127
+
128
+
129
+ def placeholder_devbox_view(id: str) -> DevboxView:
130
+ return DevboxView(
131
+ id=id,
132
+ status="provisioning",
133
+ capabilities=[],
134
+ create_time_ms=0,
135
+ launch_parameters=SharedLaunchParameters(),
136
+ metadata={},
137
+ state_transitions=[],
138
+ )
139
+
140
+
141
+ class DevboxesResource(SyncAPIResource):
142
+ @cached_property
143
+ def disk_snapshots(self) -> DiskSnapshotsResource:
144
+ return DiskSnapshotsResource(self._client)
145
+
146
+ @cached_property
147
+ def browsers(self) -> BrowsersResource:
148
+ return BrowsersResource(self._client)
149
+
150
+ @cached_property
151
+ def computers(self) -> ComputersResource:
152
+ return ComputersResource(self._client)
153
+
154
+ @cached_property
155
+ def logs(self) -> LogsResource:
156
+ return LogsResource(self._client)
157
+
158
+ @cached_property
159
+ def executions(self) -> ExecutionsResource:
160
+ return ExecutionsResource(self._client)
161
+
162
+ @cached_property
163
+ def with_raw_response(self) -> DevboxesResourceWithRawResponse:
164
+ """
165
+ This property can be used as a prefix for any HTTP method call to return
166
+ the raw response object instead of the parsed content.
167
+
168
+ For more information, see https://www.github.com/runloopai/api-client-python#accessing-raw-response-data-eg-headers
169
+ """
170
+ return DevboxesResourceWithRawResponse(self)
171
+
172
+ @cached_property
173
+ def with_streaming_response(self) -> DevboxesResourceWithStreamingResponse:
174
+ """
175
+ An alternative to `.with_raw_response` that doesn't eagerly read the response body.
176
+
177
+ For more information, see https://www.github.com/runloopai/api-client-python#with_streaming_response
178
+ """
179
+ return DevboxesResourceWithStreamingResponse(self)
180
+
181
+ def create(
182
+ self,
183
+ *,
184
+ blueprint_id: Optional[str] | Omit = omit,
185
+ blueprint_name: Optional[str] | Omit = omit,
186
+ code_mounts: Optional[Iterable[CodeMountParameters]] | Omit = omit,
187
+ entrypoint: Optional[str] | Omit = omit,
188
+ environment_variables: Optional[Dict[str, str]] | Omit = omit,
189
+ file_mounts: Optional[Dict[str, str]] | Omit = omit,
190
+ gateways: Optional[Dict[str, devbox_create_params.Gateways]] | Omit = omit,
191
+ launch_parameters: Optional[LaunchParameters] | Omit = omit,
192
+ metadata: Optional[Dict[str, str]] | Omit = omit,
193
+ mounts: Optional[Iterable[Mount]] | Omit = omit,
194
+ name: Optional[str] | Omit = omit,
195
+ repo_connection_id: Optional[str] | Omit = omit,
196
+ secrets: Optional[Dict[str, str]] | Omit = omit,
197
+ snapshot_id: Optional[str] | Omit = omit,
198
+ tunnel: Optional[devbox_create_params.Tunnel] | Omit = omit,
199
+ # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
200
+ # The extra values given here take precedence over values defined on the client or passed to this method.
201
+ extra_headers: Headers | None = None,
202
+ extra_query: Query | None = None,
203
+ extra_body: Body | None = None,
204
+ timeout: float | httpx.Timeout | None | NotGiven = not_given,
205
+ idempotency_key: str | None = None,
206
+ ) -> DevboxView:
207
+ """Create a Devbox and begin the boot process.
208
+
209
+ The Devbox will initially launch in
210
+ the 'provisioning' state while Runloop allocates the necessary infrastructure.
211
+ It will transition to the 'initializing' state while the booted Devbox runs any
212
+ Runloop or user defined set up scripts. Finally, the Devbox will transition to
213
+ the 'running' state when it is ready for use.
214
+
215
+ Args:
216
+ blueprint_id: Blueprint ID to use for the Devbox. If none set, the Devbox will be created with
217
+ the default Runloop Devbox image. Only one of (Snapshot ID, Blueprint ID,
218
+ Blueprint name) should be specified.
219
+
220
+ blueprint_name: Name of Blueprint to use for the Devbox. When set, this will load the latest
221
+ successfully built Blueprint with the given name. Only one of (Snapshot ID,
222
+ Blueprint ID, Blueprint name) should be specified.
223
+
224
+ code_mounts: A list of code mounts to be included in the Devbox. Use mounts instead.
225
+
226
+ entrypoint: (Optional) When specified, the Devbox will run this script as its main
227
+ executable. The devbox lifecycle will be bound to entrypoint, shutting down when
228
+ the process is complete.
229
+
230
+ environment_variables: (Optional) Environment variables used to configure your Devbox.
231
+
232
+ file_mounts: Map of paths and file contents to write before setup. Use mounts instead.
233
+
234
+ gateways: [Beta] (Optional) Gateway specifications for credential proxying. Map key is the
235
+ environment variable prefix (e.g., 'GWS_ANTHROPIC'). The gateway will proxy
236
+ requests to external APIs using the specified credential without exposing the
237
+ real API key. Example: {'GWS_ANTHROPIC': {'gateway': 'anthropic', 'secret':
238
+ 'my_claude_key'}}
239
+
240
+ launch_parameters: Parameters to configure the resources and launch time behavior of the Devbox.
241
+
242
+ metadata: User defined metadata to attach to the devbox for organization.
243
+
244
+ mounts: A list of mounts to be included in the Devbox.
245
+
246
+ name: (Optional) A user specified name to give the Devbox.
247
+
248
+ repo_connection_id: Repository connection id the devbox should source its base image from.
249
+
250
+ secrets: (Optional) Map of environment variable names to secret names. The secret values
251
+ will be securely injected as environment variables in the Devbox. Example:
252
+ {"DB_PASS": "DATABASE_PASSWORD"} sets environment variable 'DB_PASS' to the
253
+ value of secret 'DATABASE_PASSWORD'.
254
+
255
+ snapshot_id: Snapshot ID to use for the Devbox. Only one of (Snapshot ID, Blueprint ID,
256
+ Blueprint name) should be specified.
257
+
258
+ tunnel: (Optional) Configuration for creating a V2 tunnel at Devbox launch time. When
259
+ specified, a tunnel will be automatically provisioned and the tunnel details
260
+ will be included in the Devbox response.
261
+
262
+ extra_headers: Send extra headers
263
+
264
+ extra_query: Add additional query parameters to the request
265
+
266
+ extra_body: Add additional JSON properties to the request
267
+
268
+ timeout: Override the client-level default timeout for this request, in seconds
269
+
270
+ idempotency_key: Specify a custom idempotency key for this request
271
+ """
272
+ return self._post(
273
+ "/v1/devboxes",
274
+ body=maybe_transform(
275
+ {
276
+ "blueprint_id": blueprint_id,
277
+ "blueprint_name": blueprint_name,
278
+ "code_mounts": code_mounts,
279
+ "entrypoint": entrypoint,
280
+ "environment_variables": environment_variables,
281
+ "file_mounts": file_mounts,
282
+ "gateways": gateways,
283
+ "launch_parameters": launch_parameters,
284
+ "metadata": metadata,
285
+ "mounts": mounts,
286
+ "name": name,
287
+ "repo_connection_id": repo_connection_id,
288
+ "secrets": secrets,
289
+ "snapshot_id": snapshot_id,
290
+ "tunnel": tunnel,
291
+ },
292
+ devbox_create_params.DevboxCreateParams,
293
+ ),
294
+ options=make_request_options(
295
+ extra_headers=extra_headers,
296
+ extra_query=extra_query,
297
+ extra_body=extra_body,
298
+ timeout=timeout,
299
+ idempotency_key=idempotency_key,
300
+ ),
301
+ cast_to=DevboxView,
302
+ )
303
+
304
+ def retrieve(
305
+ self,
306
+ id: str,
307
+ *,
308
+ # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
309
+ # The extra values given here take precedence over values defined on the client or passed to this method.
310
+ extra_headers: Headers | None = None,
311
+ extra_query: Query | None = None,
312
+ extra_body: Body | None = None,
313
+ timeout: float | httpx.Timeout | None | NotGiven = not_given,
314
+ ) -> DevboxView:
315
+ """
316
+ Get the latest details and status of a Devbox.
317
+
318
+ Args:
319
+ extra_headers: Send extra headers
320
+
321
+ extra_query: Add additional query parameters to the request
322
+
323
+ extra_body: Add additional JSON properties to the request
324
+
325
+ timeout: Override the client-level default timeout for this request, in seconds
326
+ """
327
+ if not id:
328
+ raise ValueError(f"Expected a non-empty value for `id` but received {id!r}")
329
+ return self._get(
330
+ f"/v1/devboxes/{id}",
331
+ options=make_request_options(
332
+ extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
333
+ ),
334
+ cast_to=DevboxView,
335
+ )
336
+
337
+ def update(
338
+ self,
339
+ id: str,
340
+ *,
341
+ metadata: Optional[Dict[str, str]] | Omit = omit,
342
+ name: Optional[str] | Omit = omit,
343
+ # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
344
+ # The extra values given here take precedence over values defined on the client or passed to this method.
345
+ extra_headers: Headers | None = None,
346
+ extra_query: Query | None = None,
347
+ extra_body: Body | None = None,
348
+ timeout: float | httpx.Timeout | None | NotGiven = not_given,
349
+ idempotency_key: str | None = None,
350
+ ) -> DevboxView:
351
+ """
352
+ Updates a devbox by doing a complete update the existing name,metadata fields.
353
+ It does not patch partial values.
354
+
355
+ Args:
356
+ metadata: User defined metadata to attach to the devbox for organization.
357
+
358
+ name: (Optional) A user specified name to give the Devbox.
359
+
360
+ extra_headers: Send extra headers
361
+
362
+ extra_query: Add additional query parameters to the request
363
+
364
+ extra_body: Add additional JSON properties to the request
365
+
366
+ timeout: Override the client-level default timeout for this request, in seconds
367
+
368
+ idempotency_key: Specify a custom idempotency key for this request
369
+ """
370
+ if not id:
371
+ raise ValueError(f"Expected a non-empty value for `id` but received {id!r}")
372
+ return self._post(
373
+ f"/v1/devboxes/{id}",
374
+ body=maybe_transform(
375
+ {
376
+ "metadata": metadata,
377
+ "name": name,
378
+ },
379
+ devbox_update_params.DevboxUpdateParams,
380
+ ),
381
+ options=make_request_options(
382
+ extra_headers=extra_headers,
383
+ extra_query=extra_query,
384
+ extra_body=extra_body,
385
+ timeout=timeout,
386
+ idempotency_key=idempotency_key,
387
+ ),
388
+ cast_to=DevboxView,
389
+ )
390
+
391
+ def await_running(
392
+ self,
393
+ id: str,
394
+ *,
395
+ # Use polling_config to configure the "long" polling behavior.
396
+ polling_config: PollingConfig | None = None,
397
+ ) -> DevboxView:
398
+ """Wait for a devbox to be in running state.
399
+
400
+ Args:
401
+ id: The ID of the devbox to wait for
402
+ config: Optional polling configuration
403
+ extra_headers: Send extra headers
404
+ extra_query: Add additional query parameters to the request
405
+ extra_body: Add additional JSON properties to the request
406
+ timeout: Override the client-level default timeout for this request, in seconds
407
+
408
+ Returns:
409
+ The devbox in running state
410
+
411
+ Raises:
412
+ PollingTimeout: If polling times out before devbox is running
413
+ RunloopError: If devbox enters a non-running terminal state
414
+ """
415
+
416
+ def wait_for_devbox_status() -> DevboxView:
417
+ # This wait_for_status endpoint polls the devbox status for 10 seconds until it reaches either running or failure.
418
+ # If it's neither, it will throw an error.
419
+ return self._post(
420
+ f"/v1/devboxes/{id}/wait_for_status",
421
+ body={"statuses": ["running", "failure", "shutdown"]},
422
+ cast_to=DevboxView,
423
+ )
424
+
425
+ def handle_timeout_error(error: Exception) -> DevboxView:
426
+ # Handle timeout errors by returning current devbox state to continue polling
427
+ if isinstance(error, APITimeoutError) or (
428
+ isinstance(error, APIStatusError) and error.response.status_code == 408
429
+ ):
430
+ # Return a placeholder result to continue polling
431
+ return placeholder_devbox_view(id)
432
+
433
+ # Re-raise other errors to stop polling
434
+ raise error
435
+
436
+ def is_done_booting(devbox: DevboxView) -> bool:
437
+ return devbox.status not in DEVBOX_BOOTING_STATES
438
+
439
+ devbox = poll_until(wait_for_devbox_status, is_done_booting, polling_config, handle_timeout_error)
440
+
441
+ if devbox.status != "running":
442
+ raise RunloopError(f"Devbox entered non-running terminal state: {devbox.status}")
443
+
444
+ return devbox
445
+
446
+ def await_suspended(
447
+ self,
448
+ id: str,
449
+ *,
450
+ polling_config: PollingConfig | None = None,
451
+ ) -> DevboxView:
452
+ """Wait for a devbox to reach the suspended state.
453
+
454
+ Args:
455
+ id: The ID of the devbox to wait for.
456
+ polling_config: Optional polling configuration.
457
+
458
+ Returns:
459
+ The devbox in the suspended state.
460
+
461
+ Raises:
462
+ PollingTimeout: If polling times out before the devbox is suspended.
463
+ RunloopError: If the devbox enters a non-suspended terminal state.
464
+ """
465
+
466
+ def wait_for_devbox_status() -> DevboxView:
467
+ return self._post(
468
+ f"/v1/devboxes/{id}/wait_for_status",
469
+ body={"statuses": list(DEVBOX_TERMINAL_STATES)},
470
+ cast_to=DevboxView,
471
+ )
472
+
473
+ def handle_timeout_error(error: Exception) -> DevboxView:
474
+ if isinstance(error, APITimeoutError) or (
475
+ isinstance(error, APIStatusError) and error.response.status_code == 408
476
+ ):
477
+ return placeholder_devbox_view(id)
478
+ raise error
479
+
480
+ def is_terminal_state(devbox: DevboxView) -> bool:
481
+ return devbox.status in DEVBOX_TERMINAL_STATES
482
+
483
+ devbox = poll_until(wait_for_devbox_status, is_terminal_state, polling_config, handle_timeout_error)
484
+
485
+ if devbox.status != "suspended":
486
+ raise RunloopError(f"Devbox entered non-suspended terminal state: {devbox.status}")
487
+
488
+ return devbox
489
+
490
+ def create_and_await_running(
491
+ self,
492
+ *,
493
+ blueprint_id: Optional[str] | Omit = omit,
494
+ blueprint_name: Optional[str] | Omit = omit,
495
+ code_mounts: Optional[Iterable[CodeMountParameters]] | Omit = omit,
496
+ entrypoint: Optional[str] | Omit = omit,
497
+ environment_variables: Optional[Dict[str, str]] | Omit = omit,
498
+ file_mounts: Optional[Dict[str, str]] | Omit = omit,
499
+ gateways: Optional[Dict[str, devbox_create_params.Gateways]] | Omit = omit,
500
+ launch_parameters: Optional[LaunchParameters] | Omit = omit,
501
+ metadata: Optional[Dict[str, str]] | Omit = omit,
502
+ mounts: Optional[Iterable[Mount]] | Omit = omit,
503
+ name: Optional[str] | Omit = omit,
504
+ polling_config: PollingConfig | None = None,
505
+ repo_connection_id: Optional[str] | Omit = omit,
506
+ secrets: Optional[Dict[str, str]] | Omit = omit,
507
+ snapshot_id: Optional[str] | Omit = omit,
508
+ tunnel: Optional[devbox_create_params.Tunnel] | Omit = omit,
509
+ # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
510
+ # The extra values given here take precedence over values defined on the client or passed to this method.
511
+ extra_headers: Headers | None = None,
512
+ extra_query: Query | None = None,
513
+ extra_body: Body | None = None,
514
+ timeout: float | httpx.Timeout | None | NotGiven = not_given,
515
+ idempotency_key: str | None = None,
516
+ ) -> DevboxView:
517
+ """Create a new devbox and wait for it to be in running state.
518
+
519
+ This is a wrapper around the `create` method that waits for the devbox to reach running state.
520
+
521
+ Args:
522
+ create_args: Arguments to pass to the `create` method. See the `create` method for detailed documentation.
523
+ request_args: Optional request arguments including polling configuration and additional request options
524
+
525
+ Returns:
526
+ The devbox in running state
527
+
528
+ Raises:
529
+ PollingTimeout: If polling times out before devbox is running
530
+ RunloopError: If devbox enters a non-running terminal state
531
+ """
532
+ # Pass all create_args to the underlying create method
533
+ devbox = self.create(
534
+ blueprint_id=blueprint_id,
535
+ blueprint_name=blueprint_name,
536
+ code_mounts=code_mounts,
537
+ entrypoint=entrypoint,
538
+ environment_variables=environment_variables,
539
+ file_mounts=file_mounts,
540
+ gateways=gateways,
541
+ launch_parameters=launch_parameters,
542
+ metadata=metadata,
543
+ mounts=mounts,
544
+ name=name,
545
+ repo_connection_id=repo_connection_id,
546
+ secrets=secrets,
547
+ snapshot_id=snapshot_id,
548
+ tunnel=tunnel,
549
+ extra_headers=extra_headers,
550
+ extra_query=extra_query,
551
+ extra_body=extra_body,
552
+ timeout=timeout,
553
+ idempotency_key=idempotency_key,
554
+ )
555
+
556
+ return self.await_running(
557
+ devbox.id,
558
+ polling_config=polling_config,
559
+ )
560
+
561
+ def list(
562
+ self,
563
+ *,
564
+ limit: int | Omit = omit,
565
+ starting_after: str | Omit = omit,
566
+ status: Literal[
567
+ "provisioning", "initializing", "running", "suspending", "suspended", "resuming", "failure", "shutdown"
568
+ ]
569
+ | Omit = omit,
570
+ # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
571
+ # The extra values given here take precedence over values defined on the client or passed to this method.
572
+ extra_headers: Headers | None = None,
573
+ extra_query: Query | None = None,
574
+ extra_body: Body | None = None,
575
+ timeout: float | httpx.Timeout | None | NotGiven = not_given,
576
+ ) -> SyncDevboxesCursorIDPage[DevboxView]:
577
+ """
578
+ List all Devboxes while optionally filtering by status.
579
+
580
+ Args:
581
+ limit: The limit of items to return. Default is 20. Max is 5000.
582
+
583
+ starting_after: Load the next page of data starting after the item with the given ID.
584
+
585
+ status: Filter by status
586
+
587
+ extra_headers: Send extra headers
588
+
589
+ extra_query: Add additional query parameters to the request
590
+
591
+ extra_body: Add additional JSON properties to the request
592
+
593
+ timeout: Override the client-level default timeout for this request, in seconds
594
+ """
595
+ return self._get_api_list(
596
+ "/v1/devboxes",
597
+ page=SyncDevboxesCursorIDPage[DevboxView],
598
+ options=make_request_options(
599
+ extra_headers=extra_headers,
600
+ extra_query=extra_query,
601
+ extra_body=extra_body,
602
+ timeout=timeout,
603
+ query=maybe_transform(
604
+ {
605
+ "limit": limit,
606
+ "starting_after": starting_after,
607
+ "status": status,
608
+ },
609
+ devbox_list_params.DevboxListParams,
610
+ ),
611
+ ),
612
+ model=DevboxView,
613
+ )
614
+
615
+ def create_ssh_key(
616
+ self,
617
+ id: str,
618
+ *,
619
+ # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
620
+ # The extra values given here take precedence over values defined on the client or passed to this method.
621
+ extra_headers: Headers | None = None,
622
+ extra_query: Query | None = None,
623
+ extra_body: Body | None = None,
624
+ timeout: float | httpx.Timeout | None | NotGiven = not_given,
625
+ idempotency_key: str | None = None,
626
+ ) -> DevboxCreateSSHKeyResponse:
627
+ """
628
+ Create an SSH key for a Devbox to enable remote access.
629
+
630
+ Args:
631
+ extra_headers: Send extra headers
632
+
633
+ extra_query: Add additional query parameters to the request
634
+
635
+ extra_body: Add additional JSON properties to the request
636
+
637
+ timeout: Override the client-level default timeout for this request, in seconds
638
+
639
+ idempotency_key: Specify a custom idempotency key for this request
640
+ """
641
+ if not id:
642
+ raise ValueError(f"Expected a non-empty value for `id` but received {id!r}")
643
+ return self._post(
644
+ f"/v1/devboxes/{id}/create_ssh_key",
645
+ options=make_request_options(
646
+ extra_headers=extra_headers,
647
+ extra_query=extra_query,
648
+ extra_body=extra_body,
649
+ timeout=timeout,
650
+ idempotency_key=idempotency_key,
651
+ ),
652
+ cast_to=DevboxCreateSSHKeyResponse,
653
+ )
654
+
655
+ @typing_extensions.deprecated("deprecated")
656
+ def create_tunnel(
657
+ self,
658
+ id: str,
659
+ *,
660
+ port: int,
661
+ # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
662
+ # The extra values given here take precedence over values defined on the client or passed to this method.
663
+ extra_headers: Headers | None = None,
664
+ extra_query: Query | None = None,
665
+ extra_body: Body | None = None,
666
+ timeout: float | httpx.Timeout | None | NotGiven = not_given,
667
+ idempotency_key: str | None = None,
668
+ ) -> DevboxTunnelView:
669
+ """[Deprecated] Use POST /v1/devboxes/{id}/enable_tunnel instead.
670
+
671
+ This endpoint
672
+ creates a legacy tunnel. The new enable_tunnel endpoint provides improved tunnel
673
+ functionality with authentication options.
674
+
675
+ Args:
676
+ port: Devbox port that tunnel will expose.
677
+
678
+ extra_headers: Send extra headers
679
+
680
+ extra_query: Add additional query parameters to the request
681
+
682
+ extra_body: Add additional JSON properties to the request
683
+
684
+ timeout: Override the client-level default timeout for this request, in seconds
685
+
686
+ idempotency_key: Specify a custom idempotency key for this request
687
+ """
688
+ if not id:
689
+ raise ValueError(f"Expected a non-empty value for `id` but received {id!r}")
690
+ return self._post(
691
+ f"/v1/devboxes/{id}/create_tunnel",
692
+ body=maybe_transform({"port": port}, devbox_create_tunnel_params.DevboxCreateTunnelParams),
693
+ options=make_request_options(
694
+ extra_headers=extra_headers,
695
+ extra_query=extra_query,
696
+ extra_body=extra_body,
697
+ timeout=timeout,
698
+ idempotency_key=idempotency_key,
699
+ ),
700
+ cast_to=DevboxTunnelView,
701
+ )
702
+
703
+ def delete_disk_snapshot(
704
+ self,
705
+ id: str,
706
+ *,
707
+ # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
708
+ # The extra values given here take precedence over values defined on the client or passed to this method.
709
+ extra_headers: Headers | None = None,
710
+ extra_query: Query | None = None,
711
+ extra_body: Body | None = None,
712
+ timeout: float | httpx.Timeout | None | NotGiven = not_given,
713
+ idempotency_key: str | None = None,
714
+ ) -> object:
715
+ """
716
+ Delete a previously taken disk snapshot of a Devbox.
717
+
718
+ Args:
719
+ extra_headers: Send extra headers
720
+
721
+ extra_query: Add additional query parameters to the request
722
+
723
+ extra_body: Add additional JSON properties to the request
724
+
725
+ timeout: Override the client-level default timeout for this request, in seconds
726
+
727
+ idempotency_key: Specify a custom idempotency key for this request
728
+ """
729
+ if not id:
730
+ raise ValueError(f"Expected a non-empty value for `id` but received {id!r}")
731
+ return self._post(
732
+ f"/v1/devboxes/disk_snapshots/{id}/delete",
733
+ options=make_request_options(
734
+ extra_headers=extra_headers,
735
+ extra_query=extra_query,
736
+ extra_body=extra_body,
737
+ timeout=timeout,
738
+ idempotency_key=idempotency_key,
739
+ ),
740
+ cast_to=object,
741
+ )
742
+
743
+ def download_file(
744
+ self,
745
+ id: str,
746
+ *,
747
+ path: str,
748
+ # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
749
+ # The extra values given here take precedence over values defined on the client or passed to this method.
750
+ extra_headers: Headers | None = None,
751
+ extra_query: Query | None = None,
752
+ extra_body: Body | None = None,
753
+ timeout: float | httpx.Timeout | None | NotGiven = not_given,
754
+ idempotency_key: str | None = None,
755
+ ) -> BinaryAPIResponse:
756
+ """
757
+ Download file contents of any type (binary, text, etc) from a specified path on
758
+ the Devbox.
759
+
760
+ Args:
761
+ path: The path on the Devbox filesystem to read the file from. Path is relative to
762
+ user home directory.
763
+
764
+ extra_headers: Send extra headers
765
+
766
+ extra_query: Add additional query parameters to the request
767
+
768
+ extra_body: Add additional JSON properties to the request
769
+
770
+ timeout: Override the client-level default timeout for this request, in seconds
771
+
772
+ idempotency_key: Specify a custom idempotency key for this request
773
+ """
774
+ if not id:
775
+ raise ValueError(f"Expected a non-empty value for `id` but received {id!r}")
776
+ if not is_given(timeout) and self._client.timeout == DEFAULT_TIMEOUT:
777
+ timeout = 600
778
+ extra_headers = {"Accept": "application/octet-stream", **(extra_headers or {})}
779
+ return self._post(
780
+ f"/v1/devboxes/{id}/download_file",
781
+ body=maybe_transform({"path": path}, devbox_download_file_params.DevboxDownloadFileParams),
782
+ options=make_request_options(
783
+ extra_headers=extra_headers,
784
+ extra_query=extra_query,
785
+ extra_body=extra_body,
786
+ timeout=timeout,
787
+ idempotency_key=idempotency_key,
788
+ ),
789
+ cast_to=BinaryAPIResponse,
790
+ )
791
+
792
+ def enable_tunnel(
793
+ self,
794
+ id: str,
795
+ *,
796
+ auth_mode: Optional[Literal["open", "authenticated"]] | Omit = omit,
797
+ # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
798
+ # The extra values given here take precedence over values defined on the client or passed to this method.
799
+ extra_headers: Headers | None = None,
800
+ extra_query: Query | None = None,
801
+ extra_body: Body | None = None,
802
+ timeout: float | httpx.Timeout | None | NotGiven = not_given,
803
+ idempotency_key: str | None = None,
804
+ ) -> TunnelView:
805
+ """Create a V2 tunnel for an existing running Devbox.
806
+
807
+ Tunnels provide encrypted
808
+ URL-based access to the Devbox without exposing internal IDs. The tunnel URL
809
+ format is: https://{port}-{tunnel_key}.tunnel.runloop.ai
810
+
811
+ Each Devbox can have one tunnel.
812
+
813
+ Args:
814
+ auth_mode: Authentication mode for the tunnel. Defaults to 'public' if not specified.
815
+
816
+ extra_headers: Send extra headers
817
+
818
+ extra_query: Add additional query parameters to the request
819
+
820
+ extra_body: Add additional JSON properties to the request
821
+
822
+ timeout: Override the client-level default timeout for this request, in seconds
823
+
824
+ idempotency_key: Specify a custom idempotency key for this request
825
+ """
826
+ if not id:
827
+ raise ValueError(f"Expected a non-empty value for `id` but received {id!r}")
828
+ return self._post(
829
+ f"/v1/devboxes/{id}/enable_tunnel",
830
+ body=maybe_transform({"auth_mode": auth_mode}, devbox_enable_tunnel_params.DevboxEnableTunnelParams),
831
+ options=make_request_options(
832
+ extra_headers=extra_headers,
833
+ extra_query=extra_query,
834
+ extra_body=extra_body,
835
+ timeout=timeout,
836
+ idempotency_key=idempotency_key,
837
+ ),
838
+ cast_to=TunnelView,
839
+ )
840
+
841
+ def execute(
842
+ self,
843
+ id: str,
844
+ *,
845
+ command: str,
846
+ command_id: str = str(uuid7()),
847
+ last_n: str | Omit = omit,
848
+ optimistic_timeout: Optional[int] | Omit = omit,
849
+ shell_name: Optional[str] | Omit = omit,
850
+ # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
851
+ # The extra values given here take precedence over values defined on the client or passed to this method.
852
+ extra_headers: Headers | None = None,
853
+ extra_query: Query | None = None,
854
+ extra_body: Body | None = None,
855
+ timeout: float | httpx.Timeout | None | NotGiven = not_given,
856
+ idempotency_key: str | None = None,
857
+ ) -> DevboxAsyncExecutionDetailView:
858
+ """
859
+ Execute a command with a known command ID on a devbox, optimistically waiting
860
+ for it to complete within the specified timeout. If it completes in time, return
861
+ the result. If not, return a status indicating the command is still running.
862
+ Note: attach_stdin parameter is not supported; use execute_async for stdin
863
+ support.
864
+
865
+ Args:
866
+ command: The command to execute via the Devbox shell. By default, commands are run from
867
+ the user home directory unless shell_name is specified. If shell_name is
868
+ specified the command is run from the directory based on the recent state of the
869
+ persistent shell.
870
+
871
+ command_id: The command ID in UUIDv7 string format for idempotency and tracking
872
+
873
+ last_n: Last n lines of standard error / standard out to return (default: 100)
874
+
875
+ optimistic_timeout: Timeout in seconds to wait for command completion, up to 25 seconds. Defaults to
876
+ 25 seconds. Operation is not killed.
877
+
878
+ shell_name: The name of the persistent shell to create or use if already created. When using
879
+ a persistent shell, the command will run from the directory at the end of the
880
+ previous command and environment variables will be preserved.
881
+
882
+ extra_headers: Send extra headers
883
+
884
+ extra_query: Add additional query parameters to the request
885
+
886
+ extra_body: Add additional JSON properties to the request
887
+
888
+ timeout: Override the client-level default timeout for this request, in seconds
889
+
890
+ idempotency_key: Specify a custom idempotency key for this request
891
+ """
892
+ if not id:
893
+ raise ValueError(f"Expected a non-empty value for `id` but received {id!r}")
894
+ if not is_given(timeout) and self._client.timeout == DEFAULT_TIMEOUT:
895
+ timeout = 600
896
+ return self._post(
897
+ f"/v1/devboxes/{id}/execute",
898
+ body=maybe_transform(
899
+ {
900
+ "command": command,
901
+ "command_id": command_id,
902
+ "optimistic_timeout": optimistic_timeout,
903
+ "shell_name": shell_name,
904
+ },
905
+ devbox_execute_params.DevboxExecuteParams,
906
+ ),
907
+ options=make_request_options(
908
+ extra_headers=extra_headers,
909
+ extra_query=extra_query,
910
+ extra_body=extra_body,
911
+ timeout=timeout,
912
+ idempotency_key=idempotency_key,
913
+ query=maybe_transform({"last_n": last_n}, devbox_execute_params.DevboxExecuteParams),
914
+ ),
915
+ cast_to=DevboxAsyncExecutionDetailView,
916
+ )
917
+
918
+ def execute_and_await_completion(
919
+ self,
920
+ devbox_id: str,
921
+ *,
922
+ command: str,
923
+ command_id: str = str(uuid7()),
924
+ last_n: str | Omit = omit,
925
+ optimistic_timeout: Optional[int] | Omit = omit,
926
+ shell_name: Optional[str] | Omit = omit,
927
+ polling_config: PollingConfig | None = None,
928
+ # The following are forwarded to the initial execute request
929
+ extra_headers: Headers | None = None,
930
+ extra_query: Query | None = None,
931
+ extra_body: Body | None = None,
932
+ timeout: float | httpx.Timeout | None | NotGiven = not_given,
933
+ idempotency_key: str | None = None,
934
+ ) -> DevboxAsyncExecutionDetailView:
935
+ """
936
+ Execute a command and wait for it to complete with optimal latency for long running commands.
937
+
938
+ This method launches an execution and first attempts to
939
+ return the result within the initial request's timeout. If the execution is not yet
940
+ complete, it switches to using wait_for_command to minimize latency while waiting.
941
+
942
+ A command_id (UUIDv7) is automatically generated for idempotency and tracking.
943
+ You can provide your own command_id to enable custom retry logic or external tracking.
944
+ """
945
+ execution = self.execute(
946
+ devbox_id,
947
+ command=command,
948
+ command_id=command_id,
949
+ last_n=last_n,
950
+ optimistic_timeout=optimistic_timeout,
951
+ shell_name=shell_name,
952
+ extra_headers=extra_headers,
953
+ extra_query=extra_query,
954
+ extra_body=extra_body,
955
+ timeout=timeout,
956
+ idempotency_key=idempotency_key,
957
+ )
958
+ if execution.status == "completed":
959
+ return execution
960
+
961
+ def handle_timeout_error(error: Exception) -> DevboxAsyncExecutionDetailView:
962
+ if isinstance(error, APITimeoutError) or (
963
+ isinstance(error, APIStatusError) and error.response.status_code == 408
964
+ ):
965
+ return execution
966
+ raise error
967
+
968
+ def is_done(result: DevboxAsyncExecutionDetailView) -> bool:
969
+ return result.status == "completed"
970
+
971
+ return poll_until(
972
+ lambda: self.wait_for_command(execution.execution_id, devbox_id=devbox_id, statuses=["completed"]),
973
+ is_done,
974
+ polling_config,
975
+ handle_timeout_error,
976
+ )
977
+
978
+ def execute_async(
979
+ self,
980
+ id: str,
981
+ *,
982
+ command: str,
983
+ attach_stdin: Optional[bool] | Omit = omit,
984
+ shell_name: Optional[str] | Omit = omit,
985
+ # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
986
+ # The extra values given here take precedence over values defined on the client or passed to this method.
987
+ extra_headers: Headers | None = None,
988
+ extra_query: Query | None = None,
989
+ extra_body: Body | None = None,
990
+ timeout: float | httpx.Timeout | None | NotGiven = not_given,
991
+ idempotency_key: str | None = None,
992
+ ) -> DevboxAsyncExecutionDetailView:
993
+ """
994
+ Execute the given command in the Devbox shell asynchronously and returns the
995
+ execution that can be used to track the command's progress.
996
+
997
+ Args:
998
+ command: The command to execute via the Devbox shell. By default, commands are run from
999
+ the user home directory unless shell_name is specified. If shell_name is
1000
+ specified the command is run from the directory based on the recent state of the
1001
+ persistent shell.
1002
+
1003
+ attach_stdin: Whether to attach stdin streaming for async commands. Not valid for execute_sync
1004
+ endpoint. Defaults to false if not specified.
1005
+
1006
+ shell_name: The name of the persistent shell to create or use if already created. When using
1007
+ a persistent shell, the command will run from the directory at the end of the
1008
+ previous command and environment variables will be preserved.
1009
+
1010
+ extra_headers: Send extra headers
1011
+
1012
+ extra_query: Add additional query parameters to the request
1013
+
1014
+ extra_body: Add additional JSON properties to the request
1015
+
1016
+ timeout: Override the client-level default timeout for this request, in seconds
1017
+
1018
+ idempotency_key: Specify a custom idempotency key for this request
1019
+ """
1020
+ if not id:
1021
+ raise ValueError(f"Expected a non-empty value for `id` but received {id!r}")
1022
+ return self._post(
1023
+ f"/v1/devboxes/{id}/execute_async",
1024
+ body=maybe_transform(
1025
+ {
1026
+ "command": command,
1027
+ "attach_stdin": attach_stdin,
1028
+ "shell_name": shell_name,
1029
+ },
1030
+ devbox_execute_async_params.DevboxExecuteAsyncParams,
1031
+ ),
1032
+ options=make_request_options(
1033
+ extra_headers=extra_headers,
1034
+ extra_query=extra_query,
1035
+ extra_body=extra_body,
1036
+ timeout=timeout,
1037
+ idempotency_key=idempotency_key,
1038
+ ),
1039
+ cast_to=DevboxAsyncExecutionDetailView,
1040
+ )
1041
+
1042
+ @typing_extensions.deprecated("deprecated")
1043
+ # Use execute, execute_async, or execute_and_await_completion instead
1044
+ def execute_sync(
1045
+ self,
1046
+ id: str,
1047
+ *,
1048
+ command: str,
1049
+ attach_stdin: Optional[bool] | Omit = omit,
1050
+ shell_name: Optional[str] | Omit = omit,
1051
+ # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
1052
+ # The extra values given here take precedence over values defined on the client or passed to this method.
1053
+ extra_headers: Headers | None = None,
1054
+ extra_query: Query | None = None,
1055
+ extra_body: Body | None = None,
1056
+ timeout: float | httpx.Timeout | None | NotGiven = not_given,
1057
+ idempotency_key: str | None = None,
1058
+ ) -> DevboxExecutionDetailView:
1059
+ """
1060
+ Execute a bash command in the Devbox shell, await the command completion and
1061
+ return the output. Note: attach_stdin parameter is not supported for synchronous
1062
+ execution.
1063
+
1064
+ .. deprecated::
1065
+ Use execute, execute_async, or execute_and_await_completion instead.
1066
+
1067
+ Args:
1068
+ command: The command to execute via the Devbox shell. By default, commands are run from
1069
+ the user home directory unless shell_name is specified. If shell_name is
1070
+ specified the command is run from the directory based on the recent state of the
1071
+ persistent shell.
1072
+
1073
+ attach_stdin: Whether to attach stdin streaming for async commands. Not valid for execute_sync
1074
+ endpoint. Defaults to false if not specified.
1075
+
1076
+ shell_name: The name of the persistent shell to create or use if already created. When using
1077
+ a persistent shell, the command will run from the directory at the end of the
1078
+ previous command and environment variables will be preserved.
1079
+
1080
+ extra_headers: Send extra headers
1081
+
1082
+ extra_query: Add additional query parameters to the request
1083
+
1084
+ extra_body: Add additional JSON properties to the request
1085
+
1086
+ timeout: Override the client-level default timeout for this request, in seconds
1087
+
1088
+ idempotency_key: Specify a custom idempotency key for this request
1089
+ """
1090
+ if not id:
1091
+ raise ValueError(f"Expected a non-empty value for `id` but received {id!r}")
1092
+ if not is_given(timeout) and self._client.timeout == DEFAULT_TIMEOUT:
1093
+ timeout = 600
1094
+ return self._post(
1095
+ f"/v1/devboxes/{id}/execute_sync",
1096
+ body=maybe_transform(
1097
+ {
1098
+ "command": command,
1099
+ "attach_stdin": attach_stdin,
1100
+ "shell_name": shell_name,
1101
+ },
1102
+ devbox_execute_sync_params.DevboxExecuteSyncParams,
1103
+ ),
1104
+ options=make_request_options(
1105
+ extra_headers=extra_headers,
1106
+ extra_query=extra_query,
1107
+ extra_body=extra_body,
1108
+ timeout=timeout,
1109
+ idempotency_key=idempotency_key,
1110
+ ),
1111
+ cast_to=DevboxExecutionDetailView,
1112
+ )
1113
+
1114
+ def keep_alive(
1115
+ self,
1116
+ id: str,
1117
+ *,
1118
+ # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
1119
+ # The extra values given here take precedence over values defined on the client or passed to this method.
1120
+ extra_headers: Headers | None = None,
1121
+ extra_query: Query | None = None,
1122
+ extra_body: Body | None = None,
1123
+ timeout: float | httpx.Timeout | None | NotGiven = not_given,
1124
+ idempotency_key: str | None = None,
1125
+ ) -> object:
1126
+ """
1127
+ Send a 'Keep Alive' signal to a running Devbox that is configured to shutdown on
1128
+ idle so the idle time resets.
1129
+
1130
+ Args:
1131
+ extra_headers: Send extra headers
1132
+
1133
+ extra_query: Add additional query parameters to the request
1134
+
1135
+ extra_body: Add additional JSON properties to the request
1136
+
1137
+ timeout: Override the client-level default timeout for this request, in seconds
1138
+
1139
+ idempotency_key: Specify a custom idempotency key for this request
1140
+ """
1141
+ if not id:
1142
+ raise ValueError(f"Expected a non-empty value for `id` but received {id!r}")
1143
+ return self._post(
1144
+ f"/v1/devboxes/{id}/keep_alive",
1145
+ options=make_request_options(
1146
+ extra_headers=extra_headers,
1147
+ extra_query=extra_query,
1148
+ extra_body=extra_body,
1149
+ timeout=timeout,
1150
+ idempotency_key=idempotency_key,
1151
+ ),
1152
+ cast_to=object,
1153
+ )
1154
+
1155
+ def list_disk_snapshots(
1156
+ self,
1157
+ *,
1158
+ devbox_id: str | Omit = omit,
1159
+ limit: int | Omit = omit,
1160
+ metadata_key: str | Omit = omit,
1161
+ metadata_key_in: str | Omit = omit,
1162
+ source_blueprint_id: str | Omit = omit,
1163
+ starting_after: str | Omit = omit,
1164
+ # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
1165
+ # The extra values given here take precedence over values defined on the client or passed to this method.
1166
+ extra_headers: Headers | None = None,
1167
+ extra_query: Query | None = None,
1168
+ extra_body: Body | None = None,
1169
+ timeout: float | httpx.Timeout | None | NotGiven = not_given,
1170
+ ) -> SyncDiskSnapshotsCursorIDPage[DevboxSnapshotView]:
1171
+ """
1172
+ List all snapshots of a Devbox while optionally filtering by Devbox ID, source
1173
+ Blueprint ID, and metadata.
1174
+
1175
+ Args:
1176
+ devbox_id: Devbox ID to filter by.
1177
+
1178
+ limit: The limit of items to return. Default is 20. Max is 5000.
1179
+
1180
+ metadata_key: Filter snapshots by metadata key-value pair. Can be used multiple times for
1181
+ different keys.
1182
+
1183
+ metadata_key_in: Filter snapshots by metadata key with multiple possible values (OR condition).
1184
+
1185
+ source_blueprint_id: Source Blueprint ID to filter snapshots by.
1186
+
1187
+ starting_after: Load the next page of data starting after the item with the given ID.
1188
+
1189
+ extra_headers: Send extra headers
1190
+
1191
+ extra_query: Add additional query parameters to the request
1192
+
1193
+ extra_body: Add additional JSON properties to the request
1194
+
1195
+ timeout: Override the client-level default timeout for this request, in seconds
1196
+ """
1197
+ return self._get_api_list(
1198
+ "/v1/devboxes/disk_snapshots",
1199
+ page=SyncDiskSnapshotsCursorIDPage[DevboxSnapshotView],
1200
+ options=make_request_options(
1201
+ extra_headers=extra_headers,
1202
+ extra_query=extra_query,
1203
+ extra_body=extra_body,
1204
+ timeout=timeout,
1205
+ query=maybe_transform(
1206
+ {
1207
+ "devbox_id": devbox_id,
1208
+ "limit": limit,
1209
+ "metadata_key": metadata_key,
1210
+ "metadata_key_in": metadata_key_in,
1211
+ "source_blueprint_id": source_blueprint_id,
1212
+ "starting_after": starting_after,
1213
+ },
1214
+ devbox_list_disk_snapshots_params.DevboxListDiskSnapshotsParams,
1215
+ ),
1216
+ ),
1217
+ model=DevboxSnapshotView,
1218
+ )
1219
+
1220
+ def read_file_contents(
1221
+ self,
1222
+ id: str,
1223
+ *,
1224
+ file_path: str,
1225
+ # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
1226
+ # The extra values given here take precedence over values defined on the client or passed to this method.
1227
+ extra_headers: Headers | None = None,
1228
+ extra_query: Query | None = None,
1229
+ extra_body: Body | None = None,
1230
+ timeout: float | httpx.Timeout | None | NotGiven = not_given,
1231
+ idempotency_key: str | None = None,
1232
+ ) -> str:
1233
+ """Read file contents from a file on a Devbox as a UTF-8.
1234
+
1235
+ Note 'downloadFile'
1236
+ should be used for large files (greater than 100MB). Returns the file contents
1237
+ as a UTF-8 string.
1238
+
1239
+ Args:
1240
+ file_path: The path on the Devbox filesystem to read the file from. Path is relative to
1241
+ user home directory.
1242
+
1243
+ extra_headers: Send extra headers
1244
+
1245
+ extra_query: Add additional query parameters to the request
1246
+
1247
+ extra_body: Add additional JSON properties to the request
1248
+
1249
+ timeout: Override the client-level default timeout for this request, in seconds
1250
+
1251
+ idempotency_key: Specify a custom idempotency key for this request
1252
+ """
1253
+ if not id:
1254
+ raise ValueError(f"Expected a non-empty value for `id` but received {id!r}")
1255
+ if not is_given(timeout) and self._client.timeout == DEFAULT_TIMEOUT:
1256
+ timeout = 600
1257
+ extra_headers = {"Accept": "text/plain", **(extra_headers or {})}
1258
+ return self._post(
1259
+ f"/v1/devboxes/{id}/read_file_contents",
1260
+ body=maybe_transform(
1261
+ {"file_path": file_path}, devbox_read_file_contents_params.DevboxReadFileContentsParams
1262
+ ),
1263
+ options=make_request_options(
1264
+ extra_headers=extra_headers,
1265
+ extra_query=extra_query,
1266
+ extra_body=extra_body,
1267
+ timeout=timeout,
1268
+ idempotency_key=idempotency_key,
1269
+ ),
1270
+ cast_to=str,
1271
+ )
1272
+
1273
+ @typing_extensions.deprecated("deprecated")
1274
+ def remove_tunnel(
1275
+ self,
1276
+ id: str,
1277
+ *,
1278
+ port: int,
1279
+ # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
1280
+ # The extra values given here take precedence over values defined on the client or passed to this method.
1281
+ extra_headers: Headers | None = None,
1282
+ extra_query: Query | None = None,
1283
+ extra_body: Body | None = None,
1284
+ timeout: float | httpx.Timeout | None | NotGiven = not_given,
1285
+ idempotency_key: str | None = None,
1286
+ ) -> object:
1287
+ """[Deprecated] Tunnels remain active until devbox is shutdown.
1288
+
1289
+ This endpoint
1290
+ removes a legacy tunnel.
1291
+
1292
+ Args:
1293
+ port: Devbox port that tunnel will expose.
1294
+
1295
+ extra_headers: Send extra headers
1296
+
1297
+ extra_query: Add additional query parameters to the request
1298
+
1299
+ extra_body: Add additional JSON properties to the request
1300
+
1301
+ timeout: Override the client-level default timeout for this request, in seconds
1302
+
1303
+ idempotency_key: Specify a custom idempotency key for this request
1304
+ """
1305
+ if not id:
1306
+ raise ValueError(f"Expected a non-empty value for `id` but received {id!r}")
1307
+ return self._post(
1308
+ f"/v1/devboxes/{id}/remove_tunnel",
1309
+ body=maybe_transform({"port": port}, devbox_remove_tunnel_params.DevboxRemoveTunnelParams),
1310
+ options=make_request_options(
1311
+ extra_headers=extra_headers,
1312
+ extra_query=extra_query,
1313
+ extra_body=extra_body,
1314
+ timeout=timeout,
1315
+ idempotency_key=idempotency_key,
1316
+ ),
1317
+ cast_to=object,
1318
+ )
1319
+
1320
+ def resume(
1321
+ self,
1322
+ id: str,
1323
+ *,
1324
+ # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
1325
+ # The extra values given here take precedence over values defined on the client or passed to this method.
1326
+ extra_headers: Headers | None = None,
1327
+ extra_query: Query | None = None,
1328
+ extra_body: Body | None = None,
1329
+ timeout: float | httpx.Timeout | None | NotGiven = not_given,
1330
+ idempotency_key: str | None = None,
1331
+ ) -> DevboxView:
1332
+ """Resume a suspended Devbox with the disk state captured as suspend time.
1333
+
1334
+ Note
1335
+ that any previously running processes or daemons will need to be restarted using
1336
+ the Devbox shell tools.
1337
+
1338
+ Args:
1339
+ extra_headers: Send extra headers
1340
+
1341
+ extra_query: Add additional query parameters to the request
1342
+
1343
+ extra_body: Add additional JSON properties to the request
1344
+
1345
+ timeout: Override the client-level default timeout for this request, in seconds
1346
+
1347
+ idempotency_key: Specify a custom idempotency key for this request
1348
+ """
1349
+ if not id:
1350
+ raise ValueError(f"Expected a non-empty value for `id` but received {id!r}")
1351
+ return self._post(
1352
+ f"/v1/devboxes/{id}/resume",
1353
+ options=make_request_options(
1354
+ extra_headers=extra_headers,
1355
+ extra_query=extra_query,
1356
+ extra_body=extra_body,
1357
+ timeout=timeout,
1358
+ idempotency_key=idempotency_key,
1359
+ ),
1360
+ cast_to=DevboxView,
1361
+ )
1362
+
1363
+ def shutdown(
1364
+ self,
1365
+ id: str,
1366
+ *,
1367
+ # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
1368
+ # The extra values given here take precedence over values defined on the client or passed to this method.
1369
+ extra_headers: Headers | None = None,
1370
+ extra_query: Query | None = None,
1371
+ extra_body: Body | None = None,
1372
+ timeout: float | httpx.Timeout | None | NotGiven = not_given,
1373
+ idempotency_key: str | None = None,
1374
+ ) -> DevboxView:
1375
+ """Shutdown a running Devbox.
1376
+
1377
+ This will permanently stop the Devbox. If you want to
1378
+ save the state of the Devbox, you should take a snapshot before shutting down or
1379
+ should suspend the Devbox instead of shutting down.
1380
+
1381
+ Args:
1382
+ extra_headers: Send extra headers
1383
+
1384
+ extra_query: Add additional query parameters to the request
1385
+
1386
+ extra_body: Add additional JSON properties to the request
1387
+
1388
+ timeout: Override the client-level default timeout for this request, in seconds
1389
+
1390
+ idempotency_key: Specify a custom idempotency key for this request
1391
+ """
1392
+ if not id:
1393
+ raise ValueError(f"Expected a non-empty value for `id` but received {id!r}")
1394
+ return self._post(
1395
+ f"/v1/devboxes/{id}/shutdown",
1396
+ options=make_request_options(
1397
+ extra_headers=extra_headers,
1398
+ extra_query=extra_query,
1399
+ extra_body=extra_body,
1400
+ timeout=timeout,
1401
+ idempotency_key=idempotency_key,
1402
+ ),
1403
+ cast_to=DevboxView,
1404
+ )
1405
+
1406
+ def snapshot_disk(
1407
+ self,
1408
+ id: str,
1409
+ *,
1410
+ commit_message: Optional[str] | Omit = omit,
1411
+ metadata: Optional[Dict[str, str]] | Omit = omit,
1412
+ name: Optional[str] | Omit = omit,
1413
+ # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
1414
+ # The extra values given here take precedence over values defined on the client or passed to this method.
1415
+ extra_headers: Headers | None = None,
1416
+ extra_query: Query | None = None,
1417
+ extra_body: Body | None = None,
1418
+ timeout: float | httpx.Timeout | None | NotGiven = not_given,
1419
+ idempotency_key: str | None = None,
1420
+ ) -> DevboxSnapshotView:
1421
+ """
1422
+ Create a disk snapshot of a devbox with the specified name and metadata to
1423
+ enable launching future Devboxes with the same disk state.
1424
+
1425
+ Args:
1426
+ commit_message: (Optional) Commit message associated with the snapshot (max 1000 characters)
1427
+
1428
+ metadata: (Optional) Metadata used to describe the snapshot
1429
+
1430
+ name: (Optional) A user specified name to give the snapshot
1431
+
1432
+ extra_headers: Send extra headers
1433
+
1434
+ extra_query: Add additional query parameters to the request
1435
+
1436
+ extra_body: Add additional JSON properties to the request
1437
+
1438
+ timeout: Override the client-level default timeout for this request, in seconds
1439
+
1440
+ idempotency_key: Specify a custom idempotency key for this request
1441
+ """
1442
+ if not id:
1443
+ raise ValueError(f"Expected a non-empty value for `id` but received {id!r}")
1444
+ if not is_given(timeout) and self._client.timeout == DEFAULT_TIMEOUT:
1445
+ timeout = 600
1446
+ return self._post(
1447
+ f"/v1/devboxes/{id}/snapshot_disk",
1448
+ body=maybe_transform(
1449
+ {
1450
+ "commit_message": commit_message,
1451
+ "metadata": metadata,
1452
+ "name": name,
1453
+ },
1454
+ devbox_snapshot_disk_params.DevboxSnapshotDiskParams,
1455
+ ),
1456
+ options=make_request_options(
1457
+ extra_headers=extra_headers,
1458
+ extra_query=extra_query,
1459
+ extra_body=extra_body,
1460
+ timeout=timeout,
1461
+ idempotency_key=idempotency_key,
1462
+ ),
1463
+ cast_to=DevboxSnapshotView,
1464
+ )
1465
+
1466
+ def snapshot_disk_async(
1467
+ self,
1468
+ id: str,
1469
+ *,
1470
+ commit_message: Optional[str] | Omit = omit,
1471
+ metadata: Optional[Dict[str, str]] | Omit = omit,
1472
+ name: Optional[str] | Omit = omit,
1473
+ # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
1474
+ # The extra values given here take precedence over values defined on the client or passed to this method.
1475
+ extra_headers: Headers | None = None,
1476
+ extra_query: Query | None = None,
1477
+ extra_body: Body | None = None,
1478
+ timeout: float | httpx.Timeout | None | NotGiven = not_given,
1479
+ idempotency_key: str | None = None,
1480
+ ) -> DevboxSnapshotView:
1481
+ """
1482
+ Start an asynchronous disk snapshot of a devbox with the specified name and
1483
+ metadata. The snapshot operation will continue in the background and can be
1484
+ monitored using the query endpoint.
1485
+
1486
+ Args:
1487
+ commit_message: (Optional) Commit message associated with the snapshot (max 1000 characters)
1488
+
1489
+ metadata: (Optional) Metadata used to describe the snapshot
1490
+
1491
+ name: (Optional) A user specified name to give the snapshot
1492
+
1493
+ extra_headers: Send extra headers
1494
+
1495
+ extra_query: Add additional query parameters to the request
1496
+
1497
+ extra_body: Add additional JSON properties to the request
1498
+
1499
+ timeout: Override the client-level default timeout for this request, in seconds
1500
+
1501
+ idempotency_key: Specify a custom idempotency key for this request
1502
+ """
1503
+ if not id:
1504
+ raise ValueError(f"Expected a non-empty value for `id` but received {id!r}")
1505
+ return self._post(
1506
+ f"/v1/devboxes/{id}/snapshot_disk_async",
1507
+ body=maybe_transform(
1508
+ {
1509
+ "commit_message": commit_message,
1510
+ "metadata": metadata,
1511
+ "name": name,
1512
+ },
1513
+ devbox_snapshot_disk_async_params.DevboxSnapshotDiskAsyncParams,
1514
+ ),
1515
+ options=make_request_options(
1516
+ extra_headers=extra_headers,
1517
+ extra_query=extra_query,
1518
+ extra_body=extra_body,
1519
+ timeout=timeout,
1520
+ idempotency_key=idempotency_key,
1521
+ ),
1522
+ cast_to=DevboxSnapshotView,
1523
+ )
1524
+
1525
+ def suspend(
1526
+ self,
1527
+ id: str,
1528
+ *,
1529
+ # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
1530
+ # The extra values given here take precedence over values defined on the client or passed to this method.
1531
+ extra_headers: Headers | None = None,
1532
+ extra_query: Query | None = None,
1533
+ extra_body: Body | None = None,
1534
+ timeout: float | httpx.Timeout | None | NotGiven = not_given,
1535
+ idempotency_key: str | None = None,
1536
+ ) -> DevboxView:
1537
+ """
1538
+ Suspend a running Devbox and create a disk snapshot to enable resuming the
1539
+ Devbox later with the same disk. Note this will not snapshot memory state such
1540
+ as running processes.
1541
+
1542
+ Args:
1543
+ extra_headers: Send extra headers
1544
+
1545
+ extra_query: Add additional query parameters to the request
1546
+
1547
+ extra_body: Add additional JSON properties to the request
1548
+
1549
+ timeout: Override the client-level default timeout for this request, in seconds
1550
+
1551
+ idempotency_key: Specify a custom idempotency key for this request
1552
+ """
1553
+ if not id:
1554
+ raise ValueError(f"Expected a non-empty value for `id` but received {id!r}")
1555
+ return self._post(
1556
+ f"/v1/devboxes/{id}/suspend",
1557
+ options=make_request_options(
1558
+ extra_headers=extra_headers,
1559
+ extra_query=extra_query,
1560
+ extra_body=extra_body,
1561
+ timeout=timeout,
1562
+ idempotency_key=idempotency_key,
1563
+ ),
1564
+ cast_to=DevboxView,
1565
+ )
1566
+
1567
+ def upload_file(
1568
+ self,
1569
+ id: str,
1570
+ *,
1571
+ path: str,
1572
+ file: FileTypes | Omit = omit,
1573
+ # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
1574
+ # The extra values given here take precedence over values defined on the client or passed to this method.
1575
+ extra_headers: Headers | None = None,
1576
+ extra_query: Query | None = None,
1577
+ extra_body: Body | None = None,
1578
+ timeout: float | httpx.Timeout | None | NotGiven = not_given,
1579
+ idempotency_key: str | None = None,
1580
+ ) -> object:
1581
+ """Upload file contents of any type (binary, text, etc) to a Devbox.
1582
+
1583
+ Note this API
1584
+ is suitable for large files (larger than 100MB) and efficiently uploads files
1585
+ via multipart form data.
1586
+
1587
+ Args:
1588
+ path: The path to write the file to on the Devbox. Path is relative to user home
1589
+ directory.
1590
+
1591
+ extra_headers: Send extra headers
1592
+
1593
+ extra_query: Add additional query parameters to the request
1594
+
1595
+ extra_body: Add additional JSON properties to the request
1596
+
1597
+ timeout: Override the client-level default timeout for this request, in seconds
1598
+
1599
+ idempotency_key: Specify a custom idempotency key for this request
1600
+ """
1601
+ if not id:
1602
+ raise ValueError(f"Expected a non-empty value for `id` but received {id!r}")
1603
+ if not is_given(timeout) and self._client.timeout == DEFAULT_TIMEOUT:
1604
+ timeout = 600
1605
+ body = deepcopy_minimal(
1606
+ {
1607
+ "path": path,
1608
+ "file": file,
1609
+ }
1610
+ )
1611
+ files = extract_files(cast(Mapping[str, object], body), paths=[["file"]])
1612
+ # It should be noted that the actual Content-Type header that will be
1613
+ # sent to the server will contain a `boundary` parameter, e.g.
1614
+ # multipart/form-data; boundary=---abc--
1615
+ extra_headers = {"Content-Type": "multipart/form-data", **(extra_headers or {})}
1616
+ return self._post(
1617
+ f"/v1/devboxes/{id}/upload_file",
1618
+ body=maybe_transform(body, devbox_upload_file_params.DevboxUploadFileParams),
1619
+ files=files,
1620
+ options=make_request_options(
1621
+ extra_headers=extra_headers,
1622
+ extra_query=extra_query,
1623
+ extra_body=extra_body,
1624
+ timeout=timeout,
1625
+ idempotency_key=idempotency_key,
1626
+ ),
1627
+ cast_to=object,
1628
+ )
1629
+
1630
+ def wait_for_command(
1631
+ self,
1632
+ execution_id: str,
1633
+ *,
1634
+ devbox_id: str,
1635
+ statuses: List[Literal["queued", "running", "completed"]],
1636
+ last_n: str | Omit = omit,
1637
+ timeout_seconds: Optional[int] | Omit = omit,
1638
+ # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
1639
+ # The extra values given here take precedence over values defined on the client or passed to this method.
1640
+ extra_headers: Headers | None = None,
1641
+ extra_query: Query | None = None,
1642
+ extra_body: Body | None = None,
1643
+ timeout: float | httpx.Timeout | None | NotGiven = not_given,
1644
+ idempotency_key: str | None = None,
1645
+ ) -> DevboxAsyncExecutionDetailView:
1646
+ """
1647
+ Polls the asynchronous execution's status until it reaches one of the desired
1648
+ statuses or times out. Max is 25 seconds.
1649
+
1650
+ Args:
1651
+ statuses: The command execution statuses to wait for. At least one status must be
1652
+ provided. The command will be returned as soon as it reaches any of the provided
1653
+ statuses.
1654
+
1655
+ last_n: Last n lines of standard error / standard out to return (default: 100)
1656
+
1657
+ timeout_seconds: (Optional) Timeout in seconds to wait for the status, up to 25 seconds. Defaults
1658
+ to 25 seconds.
1659
+
1660
+ extra_headers: Send extra headers
1661
+
1662
+ extra_query: Add additional query parameters to the request
1663
+
1664
+ extra_body: Add additional JSON properties to the request
1665
+
1666
+ timeout: Override the client-level default timeout for this request, in seconds
1667
+
1668
+ idempotency_key: Specify a custom idempotency key for this request
1669
+ """
1670
+ if not devbox_id:
1671
+ raise ValueError(f"Expected a non-empty value for `devbox_id` but received {devbox_id!r}")
1672
+ if not execution_id:
1673
+ raise ValueError(f"Expected a non-empty value for `execution_id` but received {execution_id!r}")
1674
+ return self._post(
1675
+ f"/v1/devboxes/{devbox_id}/executions/{execution_id}/wait_for_status",
1676
+ body=maybe_transform(
1677
+ {
1678
+ "statuses": statuses,
1679
+ "timeout_seconds": timeout_seconds,
1680
+ },
1681
+ devbox_wait_for_command_params.DevboxWaitForCommandParams,
1682
+ ),
1683
+ options=make_request_options(
1684
+ extra_headers=extra_headers,
1685
+ extra_query=extra_query,
1686
+ extra_body=extra_body,
1687
+ timeout=timeout,
1688
+ idempotency_key=idempotency_key,
1689
+ query=maybe_transform({"last_n": last_n}, devbox_wait_for_command_params.DevboxWaitForCommandParams),
1690
+ ),
1691
+ cast_to=DevboxAsyncExecutionDetailView,
1692
+ )
1693
+
1694
+ def write_file_contents(
1695
+ self,
1696
+ id: str,
1697
+ *,
1698
+ contents: str,
1699
+ file_path: str,
1700
+ # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
1701
+ # The extra values given here take precedence over values defined on the client or passed to this method.
1702
+ extra_headers: Headers | None = None,
1703
+ extra_query: Query | None = None,
1704
+ extra_body: Body | None = None,
1705
+ timeout: float | httpx.Timeout | None | NotGiven = not_given,
1706
+ idempotency_key: str | None = None,
1707
+ ) -> DevboxExecutionDetailView:
1708
+ """Write UTF-8 string contents to a file at path on the Devbox.
1709
+
1710
+ Note for large
1711
+ files (larger than 100MB), the upload_file endpoint must be used.
1712
+
1713
+ Args:
1714
+ contents: The UTF-8 string contents to write to the file.
1715
+
1716
+ file_path: The path to write the file to on the Devbox. Path is relative to user home
1717
+ directory.
1718
+
1719
+ extra_headers: Send extra headers
1720
+
1721
+ extra_query: Add additional query parameters to the request
1722
+
1723
+ extra_body: Add additional JSON properties to the request
1724
+
1725
+ timeout: Override the client-level default timeout for this request, in seconds
1726
+
1727
+ idempotency_key: Specify a custom idempotency key for this request
1728
+ """
1729
+ if not id:
1730
+ raise ValueError(f"Expected a non-empty value for `id` but received {id!r}")
1731
+ if not is_given(timeout) and self._client.timeout == DEFAULT_TIMEOUT:
1732
+ timeout = 600
1733
+ return self._post(
1734
+ f"/v1/devboxes/{id}/write_file_contents",
1735
+ body=maybe_transform(
1736
+ {
1737
+ "contents": contents,
1738
+ "file_path": file_path,
1739
+ },
1740
+ devbox_write_file_contents_params.DevboxWriteFileContentsParams,
1741
+ ),
1742
+ options=make_request_options(
1743
+ extra_headers=extra_headers,
1744
+ extra_query=extra_query,
1745
+ extra_body=extra_body,
1746
+ timeout=timeout,
1747
+ idempotency_key=idempotency_key,
1748
+ ),
1749
+ cast_to=DevboxExecutionDetailView,
1750
+ )
1751
+
1752
+
1753
+ class AsyncDevboxesResource(AsyncAPIResource):
1754
+ @cached_property
1755
+ def disk_snapshots(self) -> AsyncDiskSnapshotsResource:
1756
+ return AsyncDiskSnapshotsResource(self._client)
1757
+
1758
+ @cached_property
1759
+ def browsers(self) -> AsyncBrowsersResource:
1760
+ return AsyncBrowsersResource(self._client)
1761
+
1762
+ @cached_property
1763
+ def computers(self) -> AsyncComputersResource:
1764
+ return AsyncComputersResource(self._client)
1765
+
1766
+ @cached_property
1767
+ def logs(self) -> AsyncLogsResource:
1768
+ return AsyncLogsResource(self._client)
1769
+
1770
+ @cached_property
1771
+ def executions(self) -> AsyncExecutionsResource:
1772
+ return AsyncExecutionsResource(self._client)
1773
+
1774
+ @cached_property
1775
+ def with_raw_response(self) -> AsyncDevboxesResourceWithRawResponse:
1776
+ """
1777
+ This property can be used as a prefix for any HTTP method call to return
1778
+ the raw response object instead of the parsed content.
1779
+
1780
+ For more information, see https://www.github.com/runloopai/api-client-python#accessing-raw-response-data-eg-headers
1781
+ """
1782
+ return AsyncDevboxesResourceWithRawResponse(self)
1783
+
1784
+ @cached_property
1785
+ def with_streaming_response(self) -> AsyncDevboxesResourceWithStreamingResponse:
1786
+ """
1787
+ An alternative to `.with_raw_response` that doesn't eagerly read the response body.
1788
+
1789
+ For more information, see https://www.github.com/runloopai/api-client-python#with_streaming_response
1790
+ """
1791
+ return AsyncDevboxesResourceWithStreamingResponse(self)
1792
+
1793
+ async def create(
1794
+ self,
1795
+ *,
1796
+ blueprint_id: Optional[str] | Omit = omit,
1797
+ blueprint_name: Optional[str] | Omit = omit,
1798
+ code_mounts: Optional[Iterable[CodeMountParameters]] | Omit = omit,
1799
+ entrypoint: Optional[str] | Omit = omit,
1800
+ environment_variables: Optional[Dict[str, str]] | Omit = omit,
1801
+ file_mounts: Optional[Dict[str, str]] | Omit = omit,
1802
+ gateways: Optional[Dict[str, devbox_create_params.Gateways]] | Omit = omit,
1803
+ launch_parameters: Optional[LaunchParameters] | Omit = omit,
1804
+ metadata: Optional[Dict[str, str]] | Omit = omit,
1805
+ mounts: Optional[Iterable[Mount]] | Omit = omit,
1806
+ name: Optional[str] | Omit = omit,
1807
+ repo_connection_id: Optional[str] | Omit = omit,
1808
+ secrets: Optional[Dict[str, str]] | Omit = omit,
1809
+ snapshot_id: Optional[str] | Omit = omit,
1810
+ tunnel: Optional[devbox_create_params.Tunnel] | Omit = omit,
1811
+ # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
1812
+ # The extra values given here take precedence over values defined on the client or passed to this method.
1813
+ extra_headers: Headers | None = None,
1814
+ extra_query: Query | None = None,
1815
+ extra_body: Body | None = None,
1816
+ timeout: float | httpx.Timeout | None | NotGiven = not_given,
1817
+ idempotency_key: str | None = None,
1818
+ ) -> DevboxView:
1819
+ """Create a Devbox and begin the boot process.
1820
+
1821
+ The Devbox will initially launch in
1822
+ the 'provisioning' state while Runloop allocates the necessary infrastructure.
1823
+ It will transition to the 'initializing' state while the booted Devbox runs any
1824
+ Runloop or user defined set up scripts. Finally, the Devbox will transition to
1825
+ the 'running' state when it is ready for use.
1826
+
1827
+ Args:
1828
+ blueprint_id: Blueprint ID to use for the Devbox. If none set, the Devbox will be created with
1829
+ the default Runloop Devbox image. Only one of (Snapshot ID, Blueprint ID,
1830
+ Blueprint name) should be specified.
1831
+
1832
+ blueprint_name: Name of Blueprint to use for the Devbox. When set, this will load the latest
1833
+ successfully built Blueprint with the given name. Only one of (Snapshot ID,
1834
+ Blueprint ID, Blueprint name) should be specified.
1835
+
1836
+ code_mounts: A list of code mounts to be included in the Devbox. Use mounts instead.
1837
+
1838
+ entrypoint: (Optional) When specified, the Devbox will run this script as its main
1839
+ executable. The devbox lifecycle will be bound to entrypoint, shutting down when
1840
+ the process is complete.
1841
+
1842
+ environment_variables: (Optional) Environment variables used to configure your Devbox.
1843
+
1844
+ file_mounts: Map of paths and file contents to write before setup. Use mounts instead.
1845
+
1846
+ gateways: [Beta] (Optional) Gateway specifications for credential proxying. Map key is the
1847
+ environment variable prefix (e.g., 'GWS_ANTHROPIC'). The gateway will proxy
1848
+ requests to external APIs using the specified credential without exposing the
1849
+ real API key. Example: {'GWS_ANTHROPIC': {'gateway': 'anthropic', 'secret':
1850
+ 'my_claude_key'}}
1851
+
1852
+ launch_parameters: Parameters to configure the resources and launch time behavior of the Devbox.
1853
+
1854
+ metadata: User defined metadata to attach to the devbox for organization.
1855
+
1856
+ mounts: A list of mounts to be included in the Devbox.
1857
+
1858
+ name: (Optional) A user specified name to give the Devbox.
1859
+
1860
+ repo_connection_id: Repository connection id the devbox should source its base image from.
1861
+
1862
+ secrets: (Optional) Map of environment variable names to secret names. The secret values
1863
+ will be securely injected as environment variables in the Devbox. Example:
1864
+ {"DB_PASS": "DATABASE_PASSWORD"} sets environment variable 'DB_PASS' to the
1865
+ value of secret 'DATABASE_PASSWORD'.
1866
+
1867
+ snapshot_id: Snapshot ID to use for the Devbox. Only one of (Snapshot ID, Blueprint ID,
1868
+ Blueprint name) should be specified.
1869
+
1870
+ tunnel: (Optional) Configuration for creating a V2 tunnel at Devbox launch time. When
1871
+ specified, a tunnel will be automatically provisioned and the tunnel details
1872
+ will be included in the Devbox response.
1873
+
1874
+ extra_headers: Send extra headers
1875
+
1876
+ extra_query: Add additional query parameters to the request
1877
+
1878
+ extra_body: Add additional JSON properties to the request
1879
+
1880
+ timeout: Override the client-level default timeout for this request, in seconds
1881
+
1882
+ idempotency_key: Specify a custom idempotency key for this request
1883
+ """
1884
+ return await self._post(
1885
+ "/v1/devboxes",
1886
+ body=await async_maybe_transform(
1887
+ {
1888
+ "blueprint_id": blueprint_id,
1889
+ "blueprint_name": blueprint_name,
1890
+ "code_mounts": code_mounts,
1891
+ "entrypoint": entrypoint,
1892
+ "environment_variables": environment_variables,
1893
+ "file_mounts": file_mounts,
1894
+ "gateways": gateways,
1895
+ "launch_parameters": launch_parameters,
1896
+ "metadata": metadata,
1897
+ "mounts": mounts,
1898
+ "name": name,
1899
+ "repo_connection_id": repo_connection_id,
1900
+ "secrets": secrets,
1901
+ "snapshot_id": snapshot_id,
1902
+ "tunnel": tunnel,
1903
+ },
1904
+ devbox_create_params.DevboxCreateParams,
1905
+ ),
1906
+ options=make_request_options(
1907
+ extra_headers=extra_headers,
1908
+ extra_query=extra_query,
1909
+ extra_body=extra_body,
1910
+ timeout=timeout,
1911
+ idempotency_key=idempotency_key,
1912
+ ),
1913
+ cast_to=DevboxView,
1914
+ )
1915
+
1916
+ async def retrieve(
1917
+ self,
1918
+ id: str,
1919
+ *,
1920
+ # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
1921
+ # The extra values given here take precedence over values defined on the client or passed to this method.
1922
+ extra_headers: Headers | None = None,
1923
+ extra_query: Query | None = None,
1924
+ extra_body: Body | None = None,
1925
+ timeout: float | httpx.Timeout | None | NotGiven = not_given,
1926
+ ) -> DevboxView:
1927
+ """
1928
+ Get the latest details and status of a Devbox.
1929
+
1930
+ Args:
1931
+ extra_headers: Send extra headers
1932
+
1933
+ extra_query: Add additional query parameters to the request
1934
+
1935
+ extra_body: Add additional JSON properties to the request
1936
+
1937
+ timeout: Override the client-level default timeout for this request, in seconds
1938
+ """
1939
+ if not id:
1940
+ raise ValueError(f"Expected a non-empty value for `id` but received {id!r}")
1941
+ return await self._get(
1942
+ f"/v1/devboxes/{id}",
1943
+ options=make_request_options(
1944
+ extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
1945
+ ),
1946
+ cast_to=DevboxView,
1947
+ )
1948
+
1949
+ async def create_and_await_running(
1950
+ self,
1951
+ *,
1952
+ blueprint_id: Optional[str] | Omit = omit,
1953
+ blueprint_name: Optional[str] | Omit = omit,
1954
+ code_mounts: Optional[Iterable[CodeMountParameters]] | Omit = omit,
1955
+ entrypoint: Optional[str] | Omit = omit,
1956
+ environment_variables: Optional[Dict[str, str]] | Omit = omit,
1957
+ file_mounts: Optional[Dict[str, str]] | Omit = omit,
1958
+ gateways: Optional[Dict[str, devbox_create_params.Gateways]] | Omit = omit,
1959
+ launch_parameters: Optional[LaunchParameters] | Omit = omit,
1960
+ metadata: Optional[Dict[str, str]] | Omit = omit,
1961
+ mounts: Optional[Iterable[Mount]] | Omit = omit,
1962
+ name: Optional[str] | Omit = omit,
1963
+ polling_config: PollingConfig | None = None,
1964
+ repo_connection_id: Optional[str] | Omit = omit,
1965
+ secrets: Optional[Dict[str, str]] | Omit = omit,
1966
+ snapshot_id: Optional[str] | Omit = omit,
1967
+ tunnel: Optional[devbox_create_params.Tunnel] | Omit = omit,
1968
+ # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
1969
+ # The extra values given here take precedence over values defined on the client or passed to this method.
1970
+ extra_headers: Headers | None = None,
1971
+ extra_query: Query | None = None,
1972
+ extra_body: Body | None = None,
1973
+ timeout: float | httpx.Timeout | None | NotGiven = not_given,
1974
+ idempotency_key: str | None = None,
1975
+ ) -> DevboxView:
1976
+ """Create a devbox and wait for it to be in running state.
1977
+
1978
+ This is a wrapper around the `create` method that waits for the devbox to reach running state.
1979
+
1980
+ Args:
1981
+ See the `create` method for detailed documentation.
1982
+ polling_config: Optional polling configuration
1983
+
1984
+ Returns:
1985
+ The devbox in running state
1986
+
1987
+ Raises:
1988
+ PollingTimeout: If polling times out before devbox is running
1989
+ RunloopError: If devbox enters a non-running terminal state
1990
+ """
1991
+
1992
+ # Pass all create_args, relevant request args to the underlying create method
1993
+ devbox = await self.create(
1994
+ blueprint_id=blueprint_id,
1995
+ blueprint_name=blueprint_name,
1996
+ code_mounts=code_mounts,
1997
+ entrypoint=entrypoint,
1998
+ environment_variables=environment_variables,
1999
+ file_mounts=file_mounts,
2000
+ gateways=gateways,
2001
+ launch_parameters=launch_parameters,
2002
+ metadata=metadata,
2003
+ mounts=mounts,
2004
+ name=name,
2005
+ repo_connection_id=repo_connection_id,
2006
+ secrets=secrets,
2007
+ snapshot_id=snapshot_id,
2008
+ tunnel=tunnel,
2009
+ extra_headers=extra_headers,
2010
+ extra_query=extra_query,
2011
+ extra_body=extra_body,
2012
+ timeout=timeout,
2013
+ idempotency_key=idempotency_key,
2014
+ )
2015
+
2016
+ return await self.await_running(
2017
+ devbox.id,
2018
+ polling_config=polling_config,
2019
+ )
2020
+
2021
+ async def await_running(
2022
+ self,
2023
+ id: str,
2024
+ *,
2025
+ # Use polling_config to configure the "long" polling behavior.
2026
+ polling_config: PollingConfig | None = None,
2027
+ ) -> DevboxView:
2028
+ """Wait for a devbox to be in running state.
2029
+
2030
+ Args:
2031
+ id: The ID of the devbox to wait for
2032
+ config: Optional polling configuration
2033
+ extra_headers: Send extra headers
2034
+ extra_query: Add additional query parameters to the request
2035
+ extra_body: Add additional JSON properties to the request
2036
+ timeout: Override the client-level default timeout for this request, in seconds
2037
+
2038
+ Returns:
2039
+ The devbox in running state
2040
+
2041
+ Raises:
2042
+ PollingTimeout: If polling times out before devbox is running
2043
+ RunloopError: If devbox enters a non-running terminal state
2044
+ """
2045
+
2046
+ async def wait_for_devbox_status() -> DevboxView:
2047
+ # This wait_for_status endpoint polls the devbox status for 10 seconds until it reaches either running or failure.
2048
+ # If it's neither, it will throw an error.
2049
+ try:
2050
+ return await self._post(
2051
+ f"/v1/devboxes/{id}/wait_for_status",
2052
+ body={"statuses": ["running", "failure", "shutdown"]},
2053
+ cast_to=DevboxView,
2054
+ )
2055
+ except (APITimeoutError, APIStatusError) as error:
2056
+ # Handle timeout errors by returning current devbox state to continue polling
2057
+ if isinstance(error, APITimeoutError) or error.response.status_code == 408:
2058
+ # Return a placeholder result to continue polling
2059
+ return placeholder_devbox_view(id)
2060
+
2061
+ # Re-raise other errors to stop polling
2062
+ raise
2063
+
2064
+ def is_done_booting(devbox: DevboxView) -> bool:
2065
+ return devbox.status not in DEVBOX_BOOTING_STATES
2066
+
2067
+ devbox = await async_poll_until(wait_for_devbox_status, is_done_booting, polling_config)
2068
+
2069
+ if devbox.status != "running":
2070
+ raise RunloopError(f"Devbox entered non-running terminal state: {devbox.status}")
2071
+
2072
+ return devbox
2073
+
2074
+ async def await_suspended(
2075
+ self,
2076
+ id: str,
2077
+ *,
2078
+ polling_config: PollingConfig | None = None,
2079
+ ) -> DevboxView:
2080
+ """Wait for a devbox to reach the suspended state.
2081
+
2082
+ Args:
2083
+ id: The ID of the devbox to wait for.
2084
+ polling_config: Optional polling configuration.
2085
+
2086
+ Returns:
2087
+ The devbox in the suspended state.
2088
+
2089
+ Raises:
2090
+ PollingTimeout: If polling times out before the devbox is suspended.
2091
+ RunloopError: If the devbox enters a non-suspended terminal state.
2092
+ """
2093
+
2094
+ async def wait_for_devbox_status() -> DevboxView:
2095
+ try:
2096
+ return await self._post(
2097
+ f"/v1/devboxes/{id}/wait_for_status",
2098
+ body={"statuses": list(DEVBOX_TERMINAL_STATES)},
2099
+ cast_to=DevboxView,
2100
+ )
2101
+ except (APITimeoutError, APIStatusError) as error:
2102
+ if isinstance(error, APITimeoutError) or error.response.status_code == 408:
2103
+ return placeholder_devbox_view(id)
2104
+ raise
2105
+
2106
+ def is_terminal_state(devbox: DevboxView) -> bool:
2107
+ return devbox.status in DEVBOX_TERMINAL_STATES
2108
+
2109
+ devbox = await async_poll_until(wait_for_devbox_status, is_terminal_state, polling_config)
2110
+
2111
+ if devbox.status != "suspended":
2112
+ raise RunloopError(f"Devbox entered non-suspended terminal state: {devbox.status}")
2113
+
2114
+ return devbox
2115
+
2116
+ async def update(
2117
+ self,
2118
+ id: str,
2119
+ *,
2120
+ metadata: Optional[Dict[str, str]] | Omit = omit,
2121
+ name: Optional[str] | Omit = omit,
2122
+ # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
2123
+ # The extra values given here take precedence over values defined on the client or passed to this method.
2124
+ extra_headers: Headers | None = None,
2125
+ extra_query: Query | None = None,
2126
+ extra_body: Body | None = None,
2127
+ timeout: float | httpx.Timeout | None | NotGiven = not_given,
2128
+ idempotency_key: str | None = None,
2129
+ ) -> DevboxView:
2130
+ """
2131
+ Updates a devbox by doing a complete update the existing name,metadata fields.
2132
+ It does not patch partial values.
2133
+
2134
+ Args:
2135
+ metadata: User defined metadata to attach to the devbox for organization.
2136
+
2137
+ name: (Optional) A user specified name to give the Devbox.
2138
+
2139
+ extra_headers: Send extra headers
2140
+
2141
+ extra_query: Add additional query parameters to the request
2142
+
2143
+ extra_body: Add additional JSON properties to the request
2144
+
2145
+ timeout: Override the client-level default timeout for this request, in seconds
2146
+
2147
+ idempotency_key: Specify a custom idempotency key for this request
2148
+ """
2149
+ if not id:
2150
+ raise ValueError(f"Expected a non-empty value for `id` but received {id!r}")
2151
+ return await self._post(
2152
+ f"/v1/devboxes/{id}",
2153
+ body=await async_maybe_transform(
2154
+ {
2155
+ "metadata": metadata,
2156
+ "name": name,
2157
+ },
2158
+ devbox_update_params.DevboxUpdateParams,
2159
+ ),
2160
+ options=make_request_options(
2161
+ extra_headers=extra_headers,
2162
+ extra_query=extra_query,
2163
+ extra_body=extra_body,
2164
+ timeout=timeout,
2165
+ idempotency_key=idempotency_key,
2166
+ ),
2167
+ cast_to=DevboxView,
2168
+ )
2169
+
2170
+ def list(
2171
+ self,
2172
+ *,
2173
+ limit: int | Omit = omit,
2174
+ starting_after: str | Omit = omit,
2175
+ status: Literal[
2176
+ "provisioning", "initializing", "running", "suspending", "suspended", "resuming", "failure", "shutdown"
2177
+ ]
2178
+ | Omit = omit,
2179
+ # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
2180
+ # The extra values given here take precedence over values defined on the client or passed to this method.
2181
+ extra_headers: Headers | None = None,
2182
+ extra_query: Query | None = None,
2183
+ extra_body: Body | None = None,
2184
+ timeout: float | httpx.Timeout | None | NotGiven = not_given,
2185
+ ) -> AsyncPaginator[DevboxView, AsyncDevboxesCursorIDPage[DevboxView]]:
2186
+ """
2187
+ List all Devboxes while optionally filtering by status.
2188
+
2189
+ Args:
2190
+ limit: The limit of items to return. Default is 20. Max is 5000.
2191
+
2192
+ starting_after: Load the next page of data starting after the item with the given ID.
2193
+
2194
+ status: Filter by status
2195
+
2196
+ extra_headers: Send extra headers
2197
+
2198
+ extra_query: Add additional query parameters to the request
2199
+
2200
+ extra_body: Add additional JSON properties to the request
2201
+
2202
+ timeout: Override the client-level default timeout for this request, in seconds
2203
+ """
2204
+ return self._get_api_list(
2205
+ "/v1/devboxes",
2206
+ page=AsyncDevboxesCursorIDPage[DevboxView],
2207
+ options=make_request_options(
2208
+ extra_headers=extra_headers,
2209
+ extra_query=extra_query,
2210
+ extra_body=extra_body,
2211
+ timeout=timeout,
2212
+ query=maybe_transform(
2213
+ {
2214
+ "limit": limit,
2215
+ "starting_after": starting_after,
2216
+ "status": status,
2217
+ },
2218
+ devbox_list_params.DevboxListParams,
2219
+ ),
2220
+ ),
2221
+ model=DevboxView,
2222
+ )
2223
+
2224
+ async def create_ssh_key(
2225
+ self,
2226
+ id: str,
2227
+ *,
2228
+ # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
2229
+ # The extra values given here take precedence over values defined on the client or passed to this method.
2230
+ extra_headers: Headers | None = None,
2231
+ extra_query: Query | None = None,
2232
+ extra_body: Body | None = None,
2233
+ timeout: float | httpx.Timeout | None | NotGiven = not_given,
2234
+ idempotency_key: str | None = None,
2235
+ ) -> DevboxCreateSSHKeyResponse:
2236
+ """
2237
+ Create an SSH key for a Devbox to enable remote access.
2238
+
2239
+ Args:
2240
+ extra_headers: Send extra headers
2241
+
2242
+ extra_query: Add additional query parameters to the request
2243
+
2244
+ extra_body: Add additional JSON properties to the request
2245
+
2246
+ timeout: Override the client-level default timeout for this request, in seconds
2247
+
2248
+ idempotency_key: Specify a custom idempotency key for this request
2249
+ """
2250
+ if not id:
2251
+ raise ValueError(f"Expected a non-empty value for `id` but received {id!r}")
2252
+ return await self._post(
2253
+ f"/v1/devboxes/{id}/create_ssh_key",
2254
+ options=make_request_options(
2255
+ extra_headers=extra_headers,
2256
+ extra_query=extra_query,
2257
+ extra_body=extra_body,
2258
+ timeout=timeout,
2259
+ idempotency_key=idempotency_key,
2260
+ ),
2261
+ cast_to=DevboxCreateSSHKeyResponse,
2262
+ )
2263
+
2264
+ @typing_extensions.deprecated("deprecated")
2265
+ async def create_tunnel(
2266
+ self,
2267
+ id: str,
2268
+ *,
2269
+ port: int,
2270
+ # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
2271
+ # The extra values given here take precedence over values defined on the client or passed to this method.
2272
+ extra_headers: Headers | None = None,
2273
+ extra_query: Query | None = None,
2274
+ extra_body: Body | None = None,
2275
+ timeout: float | httpx.Timeout | None | NotGiven = not_given,
2276
+ idempotency_key: str | None = None,
2277
+ ) -> DevboxTunnelView:
2278
+ """[Deprecated] Use POST /v1/devboxes/{id}/enable_tunnel instead.
2279
+
2280
+ This endpoint
2281
+ creates a legacy tunnel. The new enable_tunnel endpoint provides improved tunnel
2282
+ functionality with authentication options.
2283
+
2284
+ Args:
2285
+ port: Devbox port that tunnel will expose.
2286
+
2287
+ extra_headers: Send extra headers
2288
+
2289
+ extra_query: Add additional query parameters to the request
2290
+
2291
+ extra_body: Add additional JSON properties to the request
2292
+
2293
+ timeout: Override the client-level default timeout for this request, in seconds
2294
+
2295
+ idempotency_key: Specify a custom idempotency key for this request
2296
+ """
2297
+ if not id:
2298
+ raise ValueError(f"Expected a non-empty value for `id` but received {id!r}")
2299
+ return await self._post(
2300
+ f"/v1/devboxes/{id}/create_tunnel",
2301
+ body=await async_maybe_transform({"port": port}, devbox_create_tunnel_params.DevboxCreateTunnelParams),
2302
+ options=make_request_options(
2303
+ extra_headers=extra_headers,
2304
+ extra_query=extra_query,
2305
+ extra_body=extra_body,
2306
+ timeout=timeout,
2307
+ idempotency_key=idempotency_key,
2308
+ ),
2309
+ cast_to=DevboxTunnelView,
2310
+ )
2311
+
2312
+ async def delete_disk_snapshot(
2313
+ self,
2314
+ id: str,
2315
+ *,
2316
+ # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
2317
+ # The extra values given here take precedence over values defined on the client or passed to this method.
2318
+ extra_headers: Headers | None = None,
2319
+ extra_query: Query | None = None,
2320
+ extra_body: Body | None = None,
2321
+ timeout: float | httpx.Timeout | None | NotGiven = not_given,
2322
+ idempotency_key: str | None = None,
2323
+ ) -> object:
2324
+ """
2325
+ Delete a previously taken disk snapshot of a Devbox.
2326
+
2327
+ Args:
2328
+ extra_headers: Send extra headers
2329
+
2330
+ extra_query: Add additional query parameters to the request
2331
+
2332
+ extra_body: Add additional JSON properties to the request
2333
+
2334
+ timeout: Override the client-level default timeout for this request, in seconds
2335
+
2336
+ idempotency_key: Specify a custom idempotency key for this request
2337
+ """
2338
+ if not id:
2339
+ raise ValueError(f"Expected a non-empty value for `id` but received {id!r}")
2340
+ return await self._post(
2341
+ f"/v1/devboxes/disk_snapshots/{id}/delete",
2342
+ options=make_request_options(
2343
+ extra_headers=extra_headers,
2344
+ extra_query=extra_query,
2345
+ extra_body=extra_body,
2346
+ timeout=timeout,
2347
+ idempotency_key=idempotency_key,
2348
+ ),
2349
+ cast_to=object,
2350
+ )
2351
+
2352
+ async def download_file(
2353
+ self,
2354
+ id: str,
2355
+ *,
2356
+ path: str,
2357
+ # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
2358
+ # The extra values given here take precedence over values defined on the client or passed to this method.
2359
+ extra_headers: Headers | None = None,
2360
+ extra_query: Query | None = None,
2361
+ extra_body: Body | None = None,
2362
+ timeout: float | httpx.Timeout | None | NotGiven = not_given,
2363
+ idempotency_key: str | None = None,
2364
+ ) -> AsyncBinaryAPIResponse:
2365
+ """
2366
+ Download file contents of any type (binary, text, etc) from a specified path on
2367
+ the Devbox.
2368
+
2369
+ Args:
2370
+ path: The path on the Devbox filesystem to read the file from. Path is relative to
2371
+ user home directory.
2372
+
2373
+ extra_headers: Send extra headers
2374
+
2375
+ extra_query: Add additional query parameters to the request
2376
+
2377
+ extra_body: Add additional JSON properties to the request
2378
+
2379
+ timeout: Override the client-level default timeout for this request, in seconds
2380
+
2381
+ idempotency_key: Specify a custom idempotency key for this request
2382
+ """
2383
+ if not id:
2384
+ raise ValueError(f"Expected a non-empty value for `id` but received {id!r}")
2385
+ if not is_given(timeout) and self._client.timeout == DEFAULT_TIMEOUT:
2386
+ timeout = 600
2387
+ extra_headers = {"Accept": "application/octet-stream", **(extra_headers or {})}
2388
+ return await self._post(
2389
+ f"/v1/devboxes/{id}/download_file",
2390
+ body=await async_maybe_transform({"path": path}, devbox_download_file_params.DevboxDownloadFileParams),
2391
+ options=make_request_options(
2392
+ extra_headers=extra_headers,
2393
+ extra_query=extra_query,
2394
+ extra_body=extra_body,
2395
+ timeout=timeout,
2396
+ idempotency_key=idempotency_key,
2397
+ ),
2398
+ cast_to=AsyncBinaryAPIResponse,
2399
+ )
2400
+
2401
+ async def enable_tunnel(
2402
+ self,
2403
+ id: str,
2404
+ *,
2405
+ auth_mode: Optional[Literal["open", "authenticated"]] | Omit = omit,
2406
+ # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
2407
+ # The extra values given here take precedence over values defined on the client or passed to this method.
2408
+ extra_headers: Headers | None = None,
2409
+ extra_query: Query | None = None,
2410
+ extra_body: Body | None = None,
2411
+ timeout: float | httpx.Timeout | None | NotGiven = not_given,
2412
+ idempotency_key: str | None = None,
2413
+ ) -> TunnelView:
2414
+ """Create a V2 tunnel for an existing running Devbox.
2415
+
2416
+ Tunnels provide encrypted
2417
+ URL-based access to the Devbox without exposing internal IDs. The tunnel URL
2418
+ format is: https://{port}-{tunnel_key}.tunnel.runloop.ai
2419
+
2420
+ Each Devbox can have one tunnel.
2421
+
2422
+ Args:
2423
+ auth_mode: Authentication mode for the tunnel. Defaults to 'public' if not specified.
2424
+
2425
+ extra_headers: Send extra headers
2426
+
2427
+ extra_query: Add additional query parameters to the request
2428
+
2429
+ extra_body: Add additional JSON properties to the request
2430
+
2431
+ timeout: Override the client-level default timeout for this request, in seconds
2432
+
2433
+ idempotency_key: Specify a custom idempotency key for this request
2434
+ """
2435
+ if not id:
2436
+ raise ValueError(f"Expected a non-empty value for `id` but received {id!r}")
2437
+ return await self._post(
2438
+ f"/v1/devboxes/{id}/enable_tunnel",
2439
+ body=await async_maybe_transform(
2440
+ {"auth_mode": auth_mode}, devbox_enable_tunnel_params.DevboxEnableTunnelParams
2441
+ ),
2442
+ options=make_request_options(
2443
+ extra_headers=extra_headers,
2444
+ extra_query=extra_query,
2445
+ extra_body=extra_body,
2446
+ timeout=timeout,
2447
+ idempotency_key=idempotency_key,
2448
+ ),
2449
+ cast_to=TunnelView,
2450
+ )
2451
+
2452
+ async def execute(
2453
+ self,
2454
+ id: str,
2455
+ *,
2456
+ command: str,
2457
+ command_id: str = str(uuid7()),
2458
+ last_n: str | Omit = omit,
2459
+ optimistic_timeout: Optional[int] | Omit = omit,
2460
+ shell_name: Optional[str] | Omit = omit,
2461
+ # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
2462
+ # The extra values given here take precedence over values defined on the client or passed to this method.
2463
+ extra_headers: Headers | None = None,
2464
+ extra_query: Query | None = None,
2465
+ extra_body: Body | None = None,
2466
+ timeout: float | httpx.Timeout | None | NotGiven = not_given,
2467
+ idempotency_key: str | None = None,
2468
+ ) -> DevboxAsyncExecutionDetailView:
2469
+ """
2470
+ Execute a command with a known command ID on a devbox, optimistically waiting
2471
+ for it to complete within the specified timeout. If it completes in time, return
2472
+ the result. If not, return a status indicating the command is still running.
2473
+ Note: attach_stdin parameter is not supported; use execute_async for stdin
2474
+ support.
2475
+
2476
+ Args:
2477
+ command: The command to execute via the Devbox shell. By default, commands are run from
2478
+ the user home directory unless shell_name is specified. If shell_name is
2479
+ specified the command is run from the directory based on the recent state of the
2480
+ persistent shell.
2481
+
2482
+ command_id: The command ID in UUIDv7 string format for idempotency and tracking
2483
+
2484
+ last_n: Last n lines of standard error / standard out to return (default: 100)
2485
+
2486
+ optimistic_timeout: Timeout in seconds to wait for command completion, up to 25 seconds. Defaults to
2487
+ 25 seconds. Operation is not killed.
2488
+
2489
+ shell_name: The name of the persistent shell to create or use if already created. When using
2490
+ a persistent shell, the command will run from the directory at the end of the
2491
+ previous command and environment variables will be preserved.
2492
+
2493
+ extra_headers: Send extra headers
2494
+
2495
+ extra_query: Add additional query parameters to the request
2496
+
2497
+ extra_body: Add additional JSON properties to the request
2498
+
2499
+ timeout: Override the client-level default timeout for this request, in seconds
2500
+
2501
+ idempotency_key: Specify a custom idempotency key for this request
2502
+ """
2503
+ if not id:
2504
+ raise ValueError(f"Expected a non-empty value for `id` but received {id!r}")
2505
+ if not is_given(timeout) and self._client.timeout == DEFAULT_TIMEOUT:
2506
+ timeout = 600
2507
+ return await self._post(
2508
+ f"/v1/devboxes/{id}/execute",
2509
+ body=await async_maybe_transform(
2510
+ {
2511
+ "command": command,
2512
+ "command_id": command_id,
2513
+ "optimistic_timeout": optimistic_timeout,
2514
+ "shell_name": shell_name,
2515
+ },
2516
+ devbox_execute_params.DevboxExecuteParams,
2517
+ ),
2518
+ options=make_request_options(
2519
+ extra_headers=extra_headers,
2520
+ extra_query=extra_query,
2521
+ extra_body=extra_body,
2522
+ timeout=timeout,
2523
+ idempotency_key=idempotency_key,
2524
+ query=await async_maybe_transform({"last_n": last_n}, devbox_execute_params.DevboxExecuteParams),
2525
+ ),
2526
+ cast_to=DevboxAsyncExecutionDetailView,
2527
+ )
2528
+
2529
+ async def execute_and_await_completion(
2530
+ self,
2531
+ devbox_id: str,
2532
+ *,
2533
+ command: str,
2534
+ command_id: str = str(uuid7()),
2535
+ last_n: str | Omit = omit,
2536
+ optimistic_timeout: Optional[int] | Omit = omit,
2537
+ shell_name: Optional[str] | Omit = omit,
2538
+ polling_config: PollingConfig | None = None,
2539
+ # The following are forwarded to the initial execute request
2540
+ extra_headers: Headers | None = None,
2541
+ extra_query: Query | None = None,
2542
+ extra_body: Body | None = None,
2543
+ timeout: float | httpx.Timeout | None | NotGiven = not_given,
2544
+ idempotency_key: str | None = None,
2545
+ ) -> DevboxAsyncExecutionDetailView:
2546
+ """
2547
+ Execute a command and wait for it to complete with optimal latency for long running commands.
2548
+
2549
+ This method launches an execution and first attempts to
2550
+ return the result within the initial request's timeout. If the execution is not yet
2551
+ complete, it switches to using wait_for_command to minimize latency while waiting.
2552
+
2553
+ A command_id (UUIDv7) is automatically generated for idempotency and tracking.
2554
+ You can provide your own command_id to enable custom retry logic or external tracking.
2555
+ """
2556
+
2557
+ execution = await self.execute(
2558
+ devbox_id,
2559
+ command=command,
2560
+ command_id=command_id,
2561
+ last_n=last_n,
2562
+ optimistic_timeout=optimistic_timeout,
2563
+ shell_name=shell_name,
2564
+ extra_headers=extra_headers,
2565
+ extra_query=extra_query,
2566
+ extra_body=extra_body,
2567
+ timeout=timeout,
2568
+ idempotency_key=idempotency_key,
2569
+ )
2570
+ if execution.status == "completed":
2571
+ return execution
2572
+
2573
+ def handle_timeout_error(error: Exception) -> DevboxAsyncExecutionDetailView:
2574
+ if isinstance(error, APITimeoutError) or (
2575
+ isinstance(error, APIStatusError) and error.response.status_code == 408
2576
+ ):
2577
+ return execution
2578
+ raise error
2579
+
2580
+ def is_done(result: DevboxAsyncExecutionDetailView) -> bool:
2581
+ return result.status == "completed"
2582
+
2583
+ return await async_poll_until(
2584
+ lambda: self.wait_for_command(execution.execution_id, devbox_id=devbox_id, statuses=["completed"]),
2585
+ is_done,
2586
+ polling_config,
2587
+ handle_timeout_error,
2588
+ )
2589
+
2590
+ async def execute_async(
2591
+ self,
2592
+ id: str,
2593
+ *,
2594
+ command: str,
2595
+ attach_stdin: Optional[bool] | Omit = omit,
2596
+ shell_name: Optional[str] | Omit = omit,
2597
+ # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
2598
+ # The extra values given here take precedence over values defined on the client or passed to this method.
2599
+ extra_headers: Headers | None = None,
2600
+ extra_query: Query | None = None,
2601
+ extra_body: Body | None = None,
2602
+ timeout: float | httpx.Timeout | None | NotGiven = not_given,
2603
+ idempotency_key: str | None = None,
2604
+ ) -> DevboxAsyncExecutionDetailView:
2605
+ """
2606
+ Execute the given command in the Devbox shell asynchronously and returns the
2607
+ execution that can be used to track the command's progress.
2608
+
2609
+ Args:
2610
+ command: The command to execute via the Devbox shell. By default, commands are run from
2611
+ the user home directory unless shell_name is specified. If shell_name is
2612
+ specified the command is run from the directory based on the recent state of the
2613
+ persistent shell.
2614
+
2615
+ attach_stdin: Whether to attach stdin streaming for async commands. Not valid for execute_sync
2616
+ endpoint. Defaults to false if not specified.
2617
+
2618
+ shell_name: The name of the persistent shell to create or use if already created. When using
2619
+ a persistent shell, the command will run from the directory at the end of the
2620
+ previous command and environment variables will be preserved.
2621
+
2622
+ extra_headers: Send extra headers
2623
+
2624
+ extra_query: Add additional query parameters to the request
2625
+
2626
+ extra_body: Add additional JSON properties to the request
2627
+
2628
+ timeout: Override the client-level default timeout for this request, in seconds
2629
+
2630
+ idempotency_key: Specify a custom idempotency key for this request
2631
+ """
2632
+ if not id:
2633
+ raise ValueError(f"Expected a non-empty value for `id` but received {id!r}")
2634
+ return await self._post(
2635
+ f"/v1/devboxes/{id}/execute_async",
2636
+ body=await async_maybe_transform(
2637
+ {
2638
+ "command": command,
2639
+ "attach_stdin": attach_stdin,
2640
+ "shell_name": shell_name,
2641
+ },
2642
+ devbox_execute_async_params.DevboxExecuteAsyncParams,
2643
+ ),
2644
+ options=make_request_options(
2645
+ extra_headers=extra_headers,
2646
+ extra_query=extra_query,
2647
+ extra_body=extra_body,
2648
+ timeout=timeout,
2649
+ idempotency_key=idempotency_key,
2650
+ ),
2651
+ cast_to=DevboxAsyncExecutionDetailView,
2652
+ )
2653
+
2654
+ @typing_extensions.deprecated("deprecated")
2655
+ # Use execute, execute_async, or execute_and_await_completion instead
2656
+ async def execute_sync(
2657
+ self,
2658
+ id: str,
2659
+ *,
2660
+ command: str,
2661
+ attach_stdin: Optional[bool] | Omit = omit,
2662
+ shell_name: Optional[str] | Omit = omit,
2663
+ # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
2664
+ # The extra values given here take precedence over values defined on the client or passed to this method.
2665
+ extra_headers: Headers | None = None,
2666
+ extra_query: Query | None = None,
2667
+ extra_body: Body | None = None,
2668
+ timeout: float | httpx.Timeout | None | NotGiven = not_given,
2669
+ idempotency_key: str | None = None,
2670
+ ) -> DevboxExecutionDetailView:
2671
+ """
2672
+ Execute a bash command in the Devbox shell, await the command completion and
2673
+ return the output. Note: attach_stdin parameter is not supported for synchronous
2674
+ execution.
2675
+
2676
+ .. deprecated::
2677
+ Use execute, execute_async, or execute_and_await_completion instead.
2678
+
2679
+ Args:
2680
+ command: The command to execute via the Devbox shell. By default, commands are run from
2681
+ the user home directory unless shell_name is specified. If shell_name is
2682
+ specified the command is run from the directory based on the recent state of the
2683
+ persistent shell.
2684
+
2685
+ attach_stdin: Whether to attach stdin streaming for async commands. Not valid for execute_sync
2686
+ endpoint. Defaults to false if not specified.
2687
+
2688
+ shell_name: The name of the persistent shell to create or use if already created. When using
2689
+ a persistent shell, the command will run from the directory at the end of the
2690
+ previous command and environment variables will be preserved.
2691
+
2692
+ extra_headers: Send extra headers
2693
+
2694
+ extra_query: Add additional query parameters to the request
2695
+
2696
+ extra_body: Add additional JSON properties to the request
2697
+
2698
+ timeout: Override the client-level default timeout for this request, in seconds
2699
+
2700
+ idempotency_key: Specify a custom idempotency key for this request
2701
+ """
2702
+ if not id:
2703
+ raise ValueError(f"Expected a non-empty value for `id` but received {id!r}")
2704
+ if not is_given(timeout) and self._client.timeout == DEFAULT_TIMEOUT:
2705
+ timeout = 600
2706
+ return await self._post(
2707
+ f"/v1/devboxes/{id}/execute_sync",
2708
+ body=await async_maybe_transform(
2709
+ {
2710
+ "command": command,
2711
+ "attach_stdin": attach_stdin,
2712
+ "shell_name": shell_name,
2713
+ },
2714
+ devbox_execute_sync_params.DevboxExecuteSyncParams,
2715
+ ),
2716
+ options=make_request_options(
2717
+ extra_headers=extra_headers,
2718
+ extra_query=extra_query,
2719
+ extra_body=extra_body,
2720
+ timeout=timeout,
2721
+ idempotency_key=idempotency_key,
2722
+ ),
2723
+ cast_to=DevboxExecutionDetailView,
2724
+ )
2725
+
2726
+ async def keep_alive(
2727
+ self,
2728
+ id: str,
2729
+ *,
2730
+ # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
2731
+ # The extra values given here take precedence over values defined on the client or passed to this method.
2732
+ extra_headers: Headers | None = None,
2733
+ extra_query: Query | None = None,
2734
+ extra_body: Body | None = None,
2735
+ timeout: float | httpx.Timeout | None | NotGiven = not_given,
2736
+ idempotency_key: str | None = None,
2737
+ ) -> object:
2738
+ """
2739
+ Send a 'Keep Alive' signal to a running Devbox that is configured to shutdown on
2740
+ idle so the idle time resets.
2741
+
2742
+ Args:
2743
+ extra_headers: Send extra headers
2744
+
2745
+ extra_query: Add additional query parameters to the request
2746
+
2747
+ extra_body: Add additional JSON properties to the request
2748
+
2749
+ timeout: Override the client-level default timeout for this request, in seconds
2750
+
2751
+ idempotency_key: Specify a custom idempotency key for this request
2752
+ """
2753
+ if not id:
2754
+ raise ValueError(f"Expected a non-empty value for `id` but received {id!r}")
2755
+ return await self._post(
2756
+ f"/v1/devboxes/{id}/keep_alive",
2757
+ options=make_request_options(
2758
+ extra_headers=extra_headers,
2759
+ extra_query=extra_query,
2760
+ extra_body=extra_body,
2761
+ timeout=timeout,
2762
+ idempotency_key=idempotency_key,
2763
+ ),
2764
+ cast_to=object,
2765
+ )
2766
+
2767
+ def list_disk_snapshots(
2768
+ self,
2769
+ *,
2770
+ devbox_id: str | Omit = omit,
2771
+ limit: int | Omit = omit,
2772
+ metadata_key: str | Omit = omit,
2773
+ metadata_key_in: str | Omit = omit,
2774
+ source_blueprint_id: str | Omit = omit,
2775
+ starting_after: str | Omit = omit,
2776
+ # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
2777
+ # The extra values given here take precedence over values defined on the client or passed to this method.
2778
+ extra_headers: Headers | None = None,
2779
+ extra_query: Query | None = None,
2780
+ extra_body: Body | None = None,
2781
+ timeout: float | httpx.Timeout | None | NotGiven = not_given,
2782
+ ) -> AsyncPaginator[DevboxSnapshotView, AsyncDiskSnapshotsCursorIDPage[DevboxSnapshotView]]:
2783
+ """
2784
+ List all snapshots of a Devbox while optionally filtering by Devbox ID, source
2785
+ Blueprint ID, and metadata.
2786
+
2787
+ Args:
2788
+ devbox_id: Devbox ID to filter by.
2789
+
2790
+ limit: The limit of items to return. Default is 20. Max is 5000.
2791
+
2792
+ metadata_key: Filter snapshots by metadata key-value pair. Can be used multiple times for
2793
+ different keys.
2794
+
2795
+ metadata_key_in: Filter snapshots by metadata key with multiple possible values (OR condition).
2796
+
2797
+ source_blueprint_id: Source Blueprint ID to filter snapshots by.
2798
+
2799
+ starting_after: Load the next page of data starting after the item with the given ID.
2800
+
2801
+ extra_headers: Send extra headers
2802
+
2803
+ extra_query: Add additional query parameters to the request
2804
+
2805
+ extra_body: Add additional JSON properties to the request
2806
+
2807
+ timeout: Override the client-level default timeout for this request, in seconds
2808
+ """
2809
+ return self._get_api_list(
2810
+ "/v1/devboxes/disk_snapshots",
2811
+ page=AsyncDiskSnapshotsCursorIDPage[DevboxSnapshotView],
2812
+ options=make_request_options(
2813
+ extra_headers=extra_headers,
2814
+ extra_query=extra_query,
2815
+ extra_body=extra_body,
2816
+ timeout=timeout,
2817
+ query=maybe_transform(
2818
+ {
2819
+ "devbox_id": devbox_id,
2820
+ "limit": limit,
2821
+ "metadata_key": metadata_key,
2822
+ "metadata_key_in": metadata_key_in,
2823
+ "source_blueprint_id": source_blueprint_id,
2824
+ "starting_after": starting_after,
2825
+ },
2826
+ devbox_list_disk_snapshots_params.DevboxListDiskSnapshotsParams,
2827
+ ),
2828
+ ),
2829
+ model=DevboxSnapshotView,
2830
+ )
2831
+
2832
+ async def read_file_contents(
2833
+ self,
2834
+ id: str,
2835
+ *,
2836
+ file_path: str,
2837
+ # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
2838
+ # The extra values given here take precedence over values defined on the client or passed to this method.
2839
+ extra_headers: Headers | None = None,
2840
+ extra_query: Query | None = None,
2841
+ extra_body: Body | None = None,
2842
+ timeout: float | httpx.Timeout | None | NotGiven = not_given,
2843
+ idempotency_key: str | None = None,
2844
+ ) -> str:
2845
+ """Read file contents from a file on a Devbox as a UTF-8.
2846
+
2847
+ Note 'downloadFile'
2848
+ should be used for large files (greater than 100MB). Returns the file contents
2849
+ as a UTF-8 string.
2850
+
2851
+ Args:
2852
+ file_path: The path on the Devbox filesystem to read the file from. Path is relative to
2853
+ user home directory.
2854
+
2855
+ extra_headers: Send extra headers
2856
+
2857
+ extra_query: Add additional query parameters to the request
2858
+
2859
+ extra_body: Add additional JSON properties to the request
2860
+
2861
+ timeout: Override the client-level default timeout for this request, in seconds
2862
+
2863
+ idempotency_key: Specify a custom idempotency key for this request
2864
+ """
2865
+ if not id:
2866
+ raise ValueError(f"Expected a non-empty value for `id` but received {id!r}")
2867
+ if not is_given(timeout) and self._client.timeout == DEFAULT_TIMEOUT:
2868
+ timeout = 600
2869
+ extra_headers = {"Accept": "text/plain", **(extra_headers or {})}
2870
+ return await self._post(
2871
+ f"/v1/devboxes/{id}/read_file_contents",
2872
+ body=await async_maybe_transform(
2873
+ {"file_path": file_path}, devbox_read_file_contents_params.DevboxReadFileContentsParams
2874
+ ),
2875
+ options=make_request_options(
2876
+ extra_headers=extra_headers,
2877
+ extra_query=extra_query,
2878
+ extra_body=extra_body,
2879
+ timeout=timeout,
2880
+ idempotency_key=idempotency_key,
2881
+ ),
2882
+ cast_to=str,
2883
+ )
2884
+
2885
+ @typing_extensions.deprecated("deprecated")
2886
+ async def remove_tunnel(
2887
+ self,
2888
+ id: str,
2889
+ *,
2890
+ port: int,
2891
+ # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
2892
+ # The extra values given here take precedence over values defined on the client or passed to this method.
2893
+ extra_headers: Headers | None = None,
2894
+ extra_query: Query | None = None,
2895
+ extra_body: Body | None = None,
2896
+ timeout: float | httpx.Timeout | None | NotGiven = not_given,
2897
+ idempotency_key: str | None = None,
2898
+ ) -> object:
2899
+ """[Deprecated] Tunnels remain active until devbox is shutdown.
2900
+
2901
+ This endpoint
2902
+ removes a legacy tunnel.
2903
+
2904
+ Args:
2905
+ port: Devbox port that tunnel will expose.
2906
+
2907
+ extra_headers: Send extra headers
2908
+
2909
+ extra_query: Add additional query parameters to the request
2910
+
2911
+ extra_body: Add additional JSON properties to the request
2912
+
2913
+ timeout: Override the client-level default timeout for this request, in seconds
2914
+
2915
+ idempotency_key: Specify a custom idempotency key for this request
2916
+ """
2917
+ if not id:
2918
+ raise ValueError(f"Expected a non-empty value for `id` but received {id!r}")
2919
+ return await self._post(
2920
+ f"/v1/devboxes/{id}/remove_tunnel",
2921
+ body=await async_maybe_transform({"port": port}, devbox_remove_tunnel_params.DevboxRemoveTunnelParams),
2922
+ options=make_request_options(
2923
+ extra_headers=extra_headers,
2924
+ extra_query=extra_query,
2925
+ extra_body=extra_body,
2926
+ timeout=timeout,
2927
+ idempotency_key=idempotency_key,
2928
+ ),
2929
+ cast_to=object,
2930
+ )
2931
+
2932
+ async def resume(
2933
+ self,
2934
+ id: str,
2935
+ *,
2936
+ # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
2937
+ # The extra values given here take precedence over values defined on the client or passed to this method.
2938
+ extra_headers: Headers | None = None,
2939
+ extra_query: Query | None = None,
2940
+ extra_body: Body | None = None,
2941
+ timeout: float | httpx.Timeout | None | NotGiven = not_given,
2942
+ idempotency_key: str | None = None,
2943
+ ) -> DevboxView:
2944
+ """Resume a suspended Devbox with the disk state captured as suspend time.
2945
+
2946
+ Note
2947
+ that any previously running processes or daemons will need to be restarted using
2948
+ the Devbox shell tools.
2949
+
2950
+ Args:
2951
+ extra_headers: Send extra headers
2952
+
2953
+ extra_query: Add additional query parameters to the request
2954
+
2955
+ extra_body: Add additional JSON properties to the request
2956
+
2957
+ timeout: Override the client-level default timeout for this request, in seconds
2958
+
2959
+ idempotency_key: Specify a custom idempotency key for this request
2960
+ """
2961
+ if not id:
2962
+ raise ValueError(f"Expected a non-empty value for `id` but received {id!r}")
2963
+ return await self._post(
2964
+ f"/v1/devboxes/{id}/resume",
2965
+ options=make_request_options(
2966
+ extra_headers=extra_headers,
2967
+ extra_query=extra_query,
2968
+ extra_body=extra_body,
2969
+ timeout=timeout,
2970
+ idempotency_key=idempotency_key,
2971
+ ),
2972
+ cast_to=DevboxView,
2973
+ )
2974
+
2975
+ async def shutdown(
2976
+ self,
2977
+ id: str,
2978
+ *,
2979
+ # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
2980
+ # The extra values given here take precedence over values defined on the client or passed to this method.
2981
+ extra_headers: Headers | None = None,
2982
+ extra_query: Query | None = None,
2983
+ extra_body: Body | None = None,
2984
+ timeout: float | httpx.Timeout | None | NotGiven = not_given,
2985
+ idempotency_key: str | None = None,
2986
+ ) -> DevboxView:
2987
+ """Shutdown a running Devbox.
2988
+
2989
+ This will permanently stop the Devbox. If you want to
2990
+ save the state of the Devbox, you should take a snapshot before shutting down or
2991
+ should suspend the Devbox instead of shutting down.
2992
+
2993
+ Args:
2994
+ extra_headers: Send extra headers
2995
+
2996
+ extra_query: Add additional query parameters to the request
2997
+
2998
+ extra_body: Add additional JSON properties to the request
2999
+
3000
+ timeout: Override the client-level default timeout for this request, in seconds
3001
+
3002
+ idempotency_key: Specify a custom idempotency key for this request
3003
+ """
3004
+ if not id:
3005
+ raise ValueError(f"Expected a non-empty value for `id` but received {id!r}")
3006
+ return await self._post(
3007
+ f"/v1/devboxes/{id}/shutdown",
3008
+ options=make_request_options(
3009
+ extra_headers=extra_headers,
3010
+ extra_query=extra_query,
3011
+ extra_body=extra_body,
3012
+ timeout=timeout,
3013
+ idempotency_key=idempotency_key,
3014
+ ),
3015
+ cast_to=DevboxView,
3016
+ )
3017
+
3018
+ async def snapshot_disk(
3019
+ self,
3020
+ id: str,
3021
+ *,
3022
+ commit_message: Optional[str] | Omit = omit,
3023
+ metadata: Optional[Dict[str, str]] | Omit = omit,
3024
+ name: Optional[str] | Omit = omit,
3025
+ # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
3026
+ # The extra values given here take precedence over values defined on the client or passed to this method.
3027
+ extra_headers: Headers | None = None,
3028
+ extra_query: Query | None = None,
3029
+ extra_body: Body | None = None,
3030
+ timeout: float | httpx.Timeout | None | NotGiven = not_given,
3031
+ idempotency_key: str | None = None,
3032
+ ) -> DevboxSnapshotView:
3033
+ """
3034
+ Create a disk snapshot of a devbox with the specified name and metadata to
3035
+ enable launching future Devboxes with the same disk state.
3036
+
3037
+ Args:
3038
+ commit_message: (Optional) Commit message associated with the snapshot (max 1000 characters)
3039
+
3040
+ metadata: (Optional) Metadata used to describe the snapshot
3041
+
3042
+ name: (Optional) A user specified name to give the snapshot
3043
+
3044
+ extra_headers: Send extra headers
3045
+
3046
+ extra_query: Add additional query parameters to the request
3047
+
3048
+ extra_body: Add additional JSON properties to the request
3049
+
3050
+ timeout: Override the client-level default timeout for this request, in seconds
3051
+
3052
+ idempotency_key: Specify a custom idempotency key for this request
3053
+ """
3054
+ if not id:
3055
+ raise ValueError(f"Expected a non-empty value for `id` but received {id!r}")
3056
+ if not is_given(timeout) and self._client.timeout == DEFAULT_TIMEOUT:
3057
+ timeout = 600
3058
+ return await self._post(
3059
+ f"/v1/devboxes/{id}/snapshot_disk",
3060
+ body=await async_maybe_transform(
3061
+ {
3062
+ "commit_message": commit_message,
3063
+ "metadata": metadata,
3064
+ "name": name,
3065
+ },
3066
+ devbox_snapshot_disk_params.DevboxSnapshotDiskParams,
3067
+ ),
3068
+ options=make_request_options(
3069
+ extra_headers=extra_headers,
3070
+ extra_query=extra_query,
3071
+ extra_body=extra_body,
3072
+ timeout=timeout,
3073
+ idempotency_key=idempotency_key,
3074
+ ),
3075
+ cast_to=DevboxSnapshotView,
3076
+ )
3077
+
3078
+ async def snapshot_disk_async(
3079
+ self,
3080
+ id: str,
3081
+ *,
3082
+ commit_message: Optional[str] | Omit = omit,
3083
+ metadata: Optional[Dict[str, str]] | Omit = omit,
3084
+ name: Optional[str] | Omit = omit,
3085
+ # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
3086
+ # The extra values given here take precedence over values defined on the client or passed to this method.
3087
+ extra_headers: Headers | None = None,
3088
+ extra_query: Query | None = None,
3089
+ extra_body: Body | None = None,
3090
+ timeout: float | httpx.Timeout | None | NotGiven = not_given,
3091
+ idempotency_key: str | None = None,
3092
+ ) -> DevboxSnapshotView:
3093
+ """
3094
+ Start an asynchronous disk snapshot of a devbox with the specified name and
3095
+ metadata. The snapshot operation will continue in the background and can be
3096
+ monitored using the query endpoint.
3097
+
3098
+ Args:
3099
+ commit_message: (Optional) Commit message associated with the snapshot (max 1000 characters)
3100
+
3101
+ metadata: (Optional) Metadata used to describe the snapshot
3102
+
3103
+ name: (Optional) A user specified name to give the snapshot
3104
+
3105
+ extra_headers: Send extra headers
3106
+
3107
+ extra_query: Add additional query parameters to the request
3108
+
3109
+ extra_body: Add additional JSON properties to the request
3110
+
3111
+ timeout: Override the client-level default timeout for this request, in seconds
3112
+
3113
+ idempotency_key: Specify a custom idempotency key for this request
3114
+ """
3115
+ if not id:
3116
+ raise ValueError(f"Expected a non-empty value for `id` but received {id!r}")
3117
+ return await self._post(
3118
+ f"/v1/devboxes/{id}/snapshot_disk_async",
3119
+ body=await async_maybe_transform(
3120
+ {
3121
+ "commit_message": commit_message,
3122
+ "metadata": metadata,
3123
+ "name": name,
3124
+ },
3125
+ devbox_snapshot_disk_async_params.DevboxSnapshotDiskAsyncParams,
3126
+ ),
3127
+ options=make_request_options(
3128
+ extra_headers=extra_headers,
3129
+ extra_query=extra_query,
3130
+ extra_body=extra_body,
3131
+ timeout=timeout,
3132
+ idempotency_key=idempotency_key,
3133
+ ),
3134
+ cast_to=DevboxSnapshotView,
3135
+ )
3136
+
3137
+ async def suspend(
3138
+ self,
3139
+ id: str,
3140
+ *,
3141
+ # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
3142
+ # The extra values given here take precedence over values defined on the client or passed to this method.
3143
+ extra_headers: Headers | None = None,
3144
+ extra_query: Query | None = None,
3145
+ extra_body: Body | None = None,
3146
+ timeout: float | httpx.Timeout | None | NotGiven = not_given,
3147
+ idempotency_key: str | None = None,
3148
+ ) -> DevboxView:
3149
+ """
3150
+ Suspend a running Devbox and create a disk snapshot to enable resuming the
3151
+ Devbox later with the same disk. Note this will not snapshot memory state such
3152
+ as running processes.
3153
+
3154
+ Args:
3155
+ extra_headers: Send extra headers
3156
+
3157
+ extra_query: Add additional query parameters to the request
3158
+
3159
+ extra_body: Add additional JSON properties to the request
3160
+
3161
+ timeout: Override the client-level default timeout for this request, in seconds
3162
+
3163
+ idempotency_key: Specify a custom idempotency key for this request
3164
+ """
3165
+ if not id:
3166
+ raise ValueError(f"Expected a non-empty value for `id` but received {id!r}")
3167
+ return await self._post(
3168
+ f"/v1/devboxes/{id}/suspend",
3169
+ options=make_request_options(
3170
+ extra_headers=extra_headers,
3171
+ extra_query=extra_query,
3172
+ extra_body=extra_body,
3173
+ timeout=timeout,
3174
+ idempotency_key=idempotency_key,
3175
+ ),
3176
+ cast_to=DevboxView,
3177
+ )
3178
+
3179
+ async def upload_file(
3180
+ self,
3181
+ id: str,
3182
+ *,
3183
+ path: str,
3184
+ file: FileTypes | Omit = omit,
3185
+ # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
3186
+ # The extra values given here take precedence over values defined on the client or passed to this method.
3187
+ extra_headers: Headers | None = None,
3188
+ extra_query: Query | None = None,
3189
+ extra_body: Body | None = None,
3190
+ timeout: float | httpx.Timeout | None | NotGiven = not_given,
3191
+ idempotency_key: str | None = None,
3192
+ ) -> object:
3193
+ """Upload file contents of any type (binary, text, etc) to a Devbox.
3194
+
3195
+ Note this API
3196
+ is suitable for large files (larger than 100MB) and efficiently uploads files
3197
+ via multipart form data.
3198
+
3199
+ Args:
3200
+ path: The path to write the file to on the Devbox. Path is relative to user home
3201
+ directory.
3202
+
3203
+ extra_headers: Send extra headers
3204
+
3205
+ extra_query: Add additional query parameters to the request
3206
+
3207
+ extra_body: Add additional JSON properties to the request
3208
+
3209
+ timeout: Override the client-level default timeout for this request, in seconds
3210
+
3211
+ idempotency_key: Specify a custom idempotency key for this request
3212
+ """
3213
+ if not id:
3214
+ raise ValueError(f"Expected a non-empty value for `id` but received {id!r}")
3215
+ if not is_given(timeout) and self._client.timeout == DEFAULT_TIMEOUT:
3216
+ timeout = 600
3217
+ body = deepcopy_minimal(
3218
+ {
3219
+ "path": path,
3220
+ "file": file,
3221
+ }
3222
+ )
3223
+ files = extract_files(cast(Mapping[str, object], body), paths=[["file"]])
3224
+ # It should be noted that the actual Content-Type header that will be
3225
+ # sent to the server will contain a `boundary` parameter, e.g.
3226
+ # multipart/form-data; boundary=---abc--
3227
+ extra_headers = {"Content-Type": "multipart/form-data", **(extra_headers or {})}
3228
+ return await self._post(
3229
+ f"/v1/devboxes/{id}/upload_file",
3230
+ body=await async_maybe_transform(body, devbox_upload_file_params.DevboxUploadFileParams),
3231
+ files=files,
3232
+ options=make_request_options(
3233
+ extra_headers=extra_headers,
3234
+ extra_query=extra_query,
3235
+ extra_body=extra_body,
3236
+ timeout=timeout,
3237
+ idempotency_key=idempotency_key,
3238
+ ),
3239
+ cast_to=object,
3240
+ )
3241
+
3242
+ async def wait_for_command(
3243
+ self,
3244
+ execution_id: str,
3245
+ *,
3246
+ devbox_id: str,
3247
+ statuses: List[Literal["queued", "running", "completed"]],
3248
+ last_n: str | Omit = omit,
3249
+ timeout_seconds: Optional[int] | Omit = omit,
3250
+ # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
3251
+ # The extra values given here take precedence over values defined on the client or passed to this method.
3252
+ extra_headers: Headers | None = None,
3253
+ extra_query: Query | None = None,
3254
+ extra_body: Body | None = None,
3255
+ timeout: float | httpx.Timeout | None | NotGiven = not_given,
3256
+ idempotency_key: str | None = None,
3257
+ ) -> DevboxAsyncExecutionDetailView:
3258
+ """
3259
+ Polls the asynchronous execution's status until it reaches one of the desired
3260
+ statuses or times out. Max is 25 seconds.
3261
+
3262
+ Args:
3263
+ statuses: The command execution statuses to wait for. At least one status must be
3264
+ provided. The command will be returned as soon as it reaches any of the provided
3265
+ statuses.
3266
+
3267
+ last_n: Last n lines of standard error / standard out to return (default: 100)
3268
+
3269
+ timeout_seconds: (Optional) Timeout in seconds to wait for the status, up to 25 seconds. Defaults
3270
+ to 25 seconds.
3271
+
3272
+ extra_headers: Send extra headers
3273
+
3274
+ extra_query: Add additional query parameters to the request
3275
+
3276
+ extra_body: Add additional JSON properties to the request
3277
+
3278
+ timeout: Override the client-level default timeout for this request, in seconds
3279
+
3280
+ idempotency_key: Specify a custom idempotency key for this request
3281
+ """
3282
+ if not devbox_id:
3283
+ raise ValueError(f"Expected a non-empty value for `devbox_id` but received {devbox_id!r}")
3284
+ if not execution_id:
3285
+ raise ValueError(f"Expected a non-empty value for `execution_id` but received {execution_id!r}")
3286
+ return await self._post(
3287
+ f"/v1/devboxes/{devbox_id}/executions/{execution_id}/wait_for_status",
3288
+ body=await async_maybe_transform(
3289
+ {
3290
+ "statuses": statuses,
3291
+ "timeout_seconds": timeout_seconds,
3292
+ },
3293
+ devbox_wait_for_command_params.DevboxWaitForCommandParams,
3294
+ ),
3295
+ options=make_request_options(
3296
+ extra_headers=extra_headers,
3297
+ extra_query=extra_query,
3298
+ extra_body=extra_body,
3299
+ timeout=timeout,
3300
+ idempotency_key=idempotency_key,
3301
+ query=await async_maybe_transform(
3302
+ {"last_n": last_n}, devbox_wait_for_command_params.DevboxWaitForCommandParams
3303
+ ),
3304
+ ),
3305
+ cast_to=DevboxAsyncExecutionDetailView,
3306
+ )
3307
+
3308
+ async def write_file_contents(
3309
+ self,
3310
+ id: str,
3311
+ *,
3312
+ contents: str,
3313
+ file_path: str,
3314
+ # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
3315
+ # The extra values given here take precedence over values defined on the client or passed to this method.
3316
+ extra_headers: Headers | None = None,
3317
+ extra_query: Query | None = None,
3318
+ extra_body: Body | None = None,
3319
+ timeout: float | httpx.Timeout | None | NotGiven = not_given,
3320
+ idempotency_key: str | None = None,
3321
+ ) -> DevboxExecutionDetailView:
3322
+ """Write UTF-8 string contents to a file at path on the Devbox.
3323
+
3324
+ Note for large
3325
+ files (larger than 100MB), the upload_file endpoint must be used.
3326
+
3327
+ Args:
3328
+ contents: The UTF-8 string contents to write to the file.
3329
+
3330
+ file_path: The path to write the file to on the Devbox. Path is relative to user home
3331
+ directory.
3332
+
3333
+ extra_headers: Send extra headers
3334
+
3335
+ extra_query: Add additional query parameters to the request
3336
+
3337
+ extra_body: Add additional JSON properties to the request
3338
+
3339
+ timeout: Override the client-level default timeout for this request, in seconds
3340
+
3341
+ idempotency_key: Specify a custom idempotency key for this request
3342
+ """
3343
+ if not id:
3344
+ raise ValueError(f"Expected a non-empty value for `id` but received {id!r}")
3345
+ if not is_given(timeout) and self._client.timeout == DEFAULT_TIMEOUT:
3346
+ timeout = 600
3347
+ return await self._post(
3348
+ f"/v1/devboxes/{id}/write_file_contents",
3349
+ body=await async_maybe_transform(
3350
+ {
3351
+ "contents": contents,
3352
+ "file_path": file_path,
3353
+ },
3354
+ devbox_write_file_contents_params.DevboxWriteFileContentsParams,
3355
+ ),
3356
+ options=make_request_options(
3357
+ extra_headers=extra_headers,
3358
+ extra_query=extra_query,
3359
+ extra_body=extra_body,
3360
+ timeout=timeout,
3361
+ idempotency_key=idempotency_key,
3362
+ ),
3363
+ cast_to=DevboxExecutionDetailView,
3364
+ )
3365
+
3366
+
3367
+ class DevboxesResourceWithRawResponse:
3368
+ def __init__(self, devboxes: DevboxesResource) -> None:
3369
+ self._devboxes = devboxes
3370
+
3371
+ self.create = to_raw_response_wrapper(
3372
+ devboxes.create,
3373
+ )
3374
+ self.retrieve = to_raw_response_wrapper(
3375
+ devboxes.retrieve,
3376
+ )
3377
+ self.update = to_raw_response_wrapper(
3378
+ devboxes.update,
3379
+ )
3380
+ self.list = to_raw_response_wrapper(
3381
+ devboxes.list,
3382
+ )
3383
+ self.create_ssh_key = to_raw_response_wrapper(
3384
+ devboxes.create_ssh_key,
3385
+ )
3386
+ self.create_tunnel = ( # pyright: ignore[reportDeprecated]
3387
+ to_raw_response_wrapper(
3388
+ devboxes.create_tunnel, # pyright: ignore[reportDeprecated],
3389
+ )
3390
+ )
3391
+ self.delete_disk_snapshot = to_raw_response_wrapper(
3392
+ devboxes.delete_disk_snapshot,
3393
+ )
3394
+ self.download_file = to_custom_raw_response_wrapper(
3395
+ devboxes.download_file,
3396
+ BinaryAPIResponse,
3397
+ )
3398
+ self.enable_tunnel = to_raw_response_wrapper(
3399
+ devboxes.enable_tunnel,
3400
+ )
3401
+ self.execute = to_raw_response_wrapper(
3402
+ devboxes.execute,
3403
+ )
3404
+ self.execute_async = to_raw_response_wrapper(
3405
+ devboxes.execute_async,
3406
+ )
3407
+ self.execute_sync = ( # pyright: ignore[reportDeprecated]
3408
+ to_raw_response_wrapper(
3409
+ devboxes.execute_sync, # pyright: ignore[reportDeprecated],
3410
+ )
3411
+ )
3412
+ self.keep_alive = to_raw_response_wrapper(
3413
+ devboxes.keep_alive,
3414
+ )
3415
+ self.list_disk_snapshots = to_raw_response_wrapper(
3416
+ devboxes.list_disk_snapshots,
3417
+ )
3418
+ self.read_file_contents = to_raw_response_wrapper(
3419
+ devboxes.read_file_contents,
3420
+ )
3421
+ self.remove_tunnel = ( # pyright: ignore[reportDeprecated]
3422
+ to_raw_response_wrapper(
3423
+ devboxes.remove_tunnel, # pyright: ignore[reportDeprecated],
3424
+ )
3425
+ )
3426
+ self.resume = to_raw_response_wrapper(
3427
+ devboxes.resume,
3428
+ )
3429
+ self.shutdown = to_raw_response_wrapper(
3430
+ devboxes.shutdown,
3431
+ )
3432
+ self.snapshot_disk = to_raw_response_wrapper(
3433
+ devboxes.snapshot_disk,
3434
+ )
3435
+ self.snapshot_disk_async = to_raw_response_wrapper(
3436
+ devboxes.snapshot_disk_async,
3437
+ )
3438
+ self.suspend = to_raw_response_wrapper(
3439
+ devboxes.suspend,
3440
+ )
3441
+ self.upload_file = to_raw_response_wrapper(
3442
+ devboxes.upload_file,
3443
+ )
3444
+ self.wait_for_command = to_raw_response_wrapper(
3445
+ devboxes.wait_for_command,
3446
+ )
3447
+ self.write_file_contents = to_raw_response_wrapper(
3448
+ devboxes.write_file_contents,
3449
+ )
3450
+
3451
+ @cached_property
3452
+ def disk_snapshots(self) -> DiskSnapshotsResourceWithRawResponse:
3453
+ return DiskSnapshotsResourceWithRawResponse(self._devboxes.disk_snapshots)
3454
+
3455
+ @cached_property
3456
+ def browsers(self) -> BrowsersResourceWithRawResponse:
3457
+ return BrowsersResourceWithRawResponse(self._devboxes.browsers)
3458
+
3459
+ @cached_property
3460
+ def computers(self) -> ComputersResourceWithRawResponse:
3461
+ return ComputersResourceWithRawResponse(self._devboxes.computers)
3462
+
3463
+ @cached_property
3464
+ def logs(self) -> LogsResourceWithRawResponse:
3465
+ return LogsResourceWithRawResponse(self._devboxes.logs)
3466
+
3467
+ @cached_property
3468
+ def executions(self) -> ExecutionsResourceWithRawResponse:
3469
+ return ExecutionsResourceWithRawResponse(self._devboxes.executions)
3470
+
3471
+
3472
+ class AsyncDevboxesResourceWithRawResponse:
3473
+ def __init__(self, devboxes: AsyncDevboxesResource) -> None:
3474
+ self._devboxes = devboxes
3475
+
3476
+ self.create = async_to_raw_response_wrapper(
3477
+ devboxes.create,
3478
+ )
3479
+ self.retrieve = async_to_raw_response_wrapper(
3480
+ devboxes.retrieve,
3481
+ )
3482
+ self.update = async_to_raw_response_wrapper(
3483
+ devboxes.update,
3484
+ )
3485
+ self.list = async_to_raw_response_wrapper(
3486
+ devboxes.list,
3487
+ )
3488
+ self.create_ssh_key = async_to_raw_response_wrapper(
3489
+ devboxes.create_ssh_key,
3490
+ )
3491
+ self.create_tunnel = ( # pyright: ignore[reportDeprecated]
3492
+ async_to_raw_response_wrapper(
3493
+ devboxes.create_tunnel, # pyright: ignore[reportDeprecated],
3494
+ )
3495
+ )
3496
+ self.delete_disk_snapshot = async_to_raw_response_wrapper(
3497
+ devboxes.delete_disk_snapshot,
3498
+ )
3499
+ self.download_file = async_to_custom_raw_response_wrapper(
3500
+ devboxes.download_file,
3501
+ AsyncBinaryAPIResponse,
3502
+ )
3503
+ self.enable_tunnel = async_to_raw_response_wrapper(
3504
+ devboxes.enable_tunnel,
3505
+ )
3506
+ self.execute = async_to_raw_response_wrapper(
3507
+ devboxes.execute,
3508
+ )
3509
+ self.execute_async = async_to_raw_response_wrapper(
3510
+ devboxes.execute_async,
3511
+ )
3512
+ self.execute_sync = ( # pyright: ignore[reportDeprecated]
3513
+ async_to_raw_response_wrapper(
3514
+ devboxes.execute_sync, # pyright: ignore[reportDeprecated],
3515
+ )
3516
+ )
3517
+ self.keep_alive = async_to_raw_response_wrapper(
3518
+ devboxes.keep_alive,
3519
+ )
3520
+ self.list_disk_snapshots = async_to_raw_response_wrapper(
3521
+ devboxes.list_disk_snapshots,
3522
+ )
3523
+ self.read_file_contents = async_to_raw_response_wrapper(
3524
+ devboxes.read_file_contents,
3525
+ )
3526
+ self.remove_tunnel = ( # pyright: ignore[reportDeprecated]
3527
+ async_to_raw_response_wrapper(
3528
+ devboxes.remove_tunnel, # pyright: ignore[reportDeprecated],
3529
+ )
3530
+ )
3531
+ self.resume = async_to_raw_response_wrapper(
3532
+ devboxes.resume,
3533
+ )
3534
+ self.shutdown = async_to_raw_response_wrapper(
3535
+ devboxes.shutdown,
3536
+ )
3537
+ self.snapshot_disk = async_to_raw_response_wrapper(
3538
+ devboxes.snapshot_disk,
3539
+ )
3540
+ self.snapshot_disk_async = async_to_raw_response_wrapper(
3541
+ devboxes.snapshot_disk_async,
3542
+ )
3543
+ self.suspend = async_to_raw_response_wrapper(
3544
+ devboxes.suspend,
3545
+ )
3546
+ self.upload_file = async_to_raw_response_wrapper(
3547
+ devboxes.upload_file,
3548
+ )
3549
+ self.wait_for_command = async_to_raw_response_wrapper(
3550
+ devboxes.wait_for_command,
3551
+ )
3552
+ self.write_file_contents = async_to_raw_response_wrapper(
3553
+ devboxes.write_file_contents,
3554
+ )
3555
+
3556
+ @cached_property
3557
+ def disk_snapshots(self) -> AsyncDiskSnapshotsResourceWithRawResponse:
3558
+ return AsyncDiskSnapshotsResourceWithRawResponse(self._devboxes.disk_snapshots)
3559
+
3560
+ @cached_property
3561
+ def browsers(self) -> AsyncBrowsersResourceWithRawResponse:
3562
+ return AsyncBrowsersResourceWithRawResponse(self._devboxes.browsers)
3563
+
3564
+ @cached_property
3565
+ def computers(self) -> AsyncComputersResourceWithRawResponse:
3566
+ return AsyncComputersResourceWithRawResponse(self._devboxes.computers)
3567
+
3568
+ @cached_property
3569
+ def logs(self) -> AsyncLogsResourceWithRawResponse:
3570
+ return AsyncLogsResourceWithRawResponse(self._devboxes.logs)
3571
+
3572
+ @cached_property
3573
+ def executions(self) -> AsyncExecutionsResourceWithRawResponse:
3574
+ return AsyncExecutionsResourceWithRawResponse(self._devboxes.executions)
3575
+
3576
+
3577
+ class DevboxesResourceWithStreamingResponse:
3578
+ def __init__(self, devboxes: DevboxesResource) -> None:
3579
+ self._devboxes = devboxes
3580
+
3581
+ self.create = to_streamed_response_wrapper(
3582
+ devboxes.create,
3583
+ )
3584
+ self.retrieve = to_streamed_response_wrapper(
3585
+ devboxes.retrieve,
3586
+ )
3587
+ self.update = to_streamed_response_wrapper(
3588
+ devboxes.update,
3589
+ )
3590
+ self.list = to_streamed_response_wrapper(
3591
+ devboxes.list,
3592
+ )
3593
+ self.create_ssh_key = to_streamed_response_wrapper(
3594
+ devboxes.create_ssh_key,
3595
+ )
3596
+ self.create_tunnel = ( # pyright: ignore[reportDeprecated]
3597
+ to_streamed_response_wrapper(
3598
+ devboxes.create_tunnel, # pyright: ignore[reportDeprecated],
3599
+ )
3600
+ )
3601
+ self.delete_disk_snapshot = to_streamed_response_wrapper(
3602
+ devboxes.delete_disk_snapshot,
3603
+ )
3604
+ self.download_file = to_custom_streamed_response_wrapper(
3605
+ devboxes.download_file,
3606
+ StreamedBinaryAPIResponse,
3607
+ )
3608
+ self.enable_tunnel = to_streamed_response_wrapper(
3609
+ devboxes.enable_tunnel,
3610
+ )
3611
+ self.execute = to_streamed_response_wrapper(
3612
+ devboxes.execute,
3613
+ )
3614
+ self.execute_async = to_streamed_response_wrapper(
3615
+ devboxes.execute_async,
3616
+ )
3617
+ self.execute_sync = ( # pyright: ignore[reportDeprecated]
3618
+ to_streamed_response_wrapper(
3619
+ devboxes.execute_sync, # pyright: ignore[reportDeprecated],
3620
+ )
3621
+ )
3622
+ self.keep_alive = to_streamed_response_wrapper(
3623
+ devboxes.keep_alive,
3624
+ )
3625
+ self.list_disk_snapshots = to_streamed_response_wrapper(
3626
+ devboxes.list_disk_snapshots,
3627
+ )
3628
+ self.read_file_contents = to_streamed_response_wrapper(
3629
+ devboxes.read_file_contents,
3630
+ )
3631
+ self.remove_tunnel = ( # pyright: ignore[reportDeprecated]
3632
+ to_streamed_response_wrapper(
3633
+ devboxes.remove_tunnel, # pyright: ignore[reportDeprecated],
3634
+ )
3635
+ )
3636
+ self.resume = to_streamed_response_wrapper(
3637
+ devboxes.resume,
3638
+ )
3639
+ self.shutdown = to_streamed_response_wrapper(
3640
+ devboxes.shutdown,
3641
+ )
3642
+ self.snapshot_disk = to_streamed_response_wrapper(
3643
+ devboxes.snapshot_disk,
3644
+ )
3645
+ self.snapshot_disk_async = to_streamed_response_wrapper(
3646
+ devboxes.snapshot_disk_async,
3647
+ )
3648
+ self.suspend = to_streamed_response_wrapper(
3649
+ devboxes.suspend,
3650
+ )
3651
+ self.upload_file = to_streamed_response_wrapper(
3652
+ devboxes.upload_file,
3653
+ )
3654
+ self.wait_for_command = to_streamed_response_wrapper(
3655
+ devboxes.wait_for_command,
3656
+ )
3657
+ self.write_file_contents = to_streamed_response_wrapper(
3658
+ devboxes.write_file_contents,
3659
+ )
3660
+
3661
+ @cached_property
3662
+ def disk_snapshots(self) -> DiskSnapshotsResourceWithStreamingResponse:
3663
+ return DiskSnapshotsResourceWithStreamingResponse(self._devboxes.disk_snapshots)
3664
+
3665
+ @cached_property
3666
+ def browsers(self) -> BrowsersResourceWithStreamingResponse:
3667
+ return BrowsersResourceWithStreamingResponse(self._devboxes.browsers)
3668
+
3669
+ @cached_property
3670
+ def computers(self) -> ComputersResourceWithStreamingResponse:
3671
+ return ComputersResourceWithStreamingResponse(self._devboxes.computers)
3672
+
3673
+ @cached_property
3674
+ def logs(self) -> LogsResourceWithStreamingResponse:
3675
+ return LogsResourceWithStreamingResponse(self._devboxes.logs)
3676
+
3677
+ @cached_property
3678
+ def executions(self) -> ExecutionsResourceWithStreamingResponse:
3679
+ return ExecutionsResourceWithStreamingResponse(self._devboxes.executions)
3680
+
3681
+
3682
+ class AsyncDevboxesResourceWithStreamingResponse:
3683
+ def __init__(self, devboxes: AsyncDevboxesResource) -> None:
3684
+ self._devboxes = devboxes
3685
+
3686
+ self.create = async_to_streamed_response_wrapper(
3687
+ devboxes.create,
3688
+ )
3689
+ self.retrieve = async_to_streamed_response_wrapper(
3690
+ devboxes.retrieve,
3691
+ )
3692
+ self.update = async_to_streamed_response_wrapper(
3693
+ devboxes.update,
3694
+ )
3695
+ self.list = async_to_streamed_response_wrapper(
3696
+ devboxes.list,
3697
+ )
3698
+ self.create_ssh_key = async_to_streamed_response_wrapper(
3699
+ devboxes.create_ssh_key,
3700
+ )
3701
+ self.create_tunnel = ( # pyright: ignore[reportDeprecated]
3702
+ async_to_streamed_response_wrapper(
3703
+ devboxes.create_tunnel, # pyright: ignore[reportDeprecated],
3704
+ )
3705
+ )
3706
+ self.delete_disk_snapshot = async_to_streamed_response_wrapper(
3707
+ devboxes.delete_disk_snapshot,
3708
+ )
3709
+ self.download_file = async_to_custom_streamed_response_wrapper(
3710
+ devboxes.download_file,
3711
+ AsyncStreamedBinaryAPIResponse,
3712
+ )
3713
+ self.enable_tunnel = async_to_streamed_response_wrapper(
3714
+ devboxes.enable_tunnel,
3715
+ )
3716
+ self.execute = async_to_streamed_response_wrapper(
3717
+ devboxes.execute,
3718
+ )
3719
+ self.execute_async = async_to_streamed_response_wrapper(
3720
+ devboxes.execute_async,
3721
+ )
3722
+ self.execute_sync = ( # pyright: ignore[reportDeprecated]
3723
+ async_to_streamed_response_wrapper(
3724
+ devboxes.execute_sync, # pyright: ignore[reportDeprecated],
3725
+ )
3726
+ )
3727
+ self.keep_alive = async_to_streamed_response_wrapper(
3728
+ devboxes.keep_alive,
3729
+ )
3730
+ self.list_disk_snapshots = async_to_streamed_response_wrapper(
3731
+ devboxes.list_disk_snapshots,
3732
+ )
3733
+ self.read_file_contents = async_to_streamed_response_wrapper(
3734
+ devboxes.read_file_contents,
3735
+ )
3736
+ self.remove_tunnel = ( # pyright: ignore[reportDeprecated]
3737
+ async_to_streamed_response_wrapper(
3738
+ devboxes.remove_tunnel, # pyright: ignore[reportDeprecated],
3739
+ )
3740
+ )
3741
+ self.resume = async_to_streamed_response_wrapper(
3742
+ devboxes.resume,
3743
+ )
3744
+ self.shutdown = async_to_streamed_response_wrapper(
3745
+ devboxes.shutdown,
3746
+ )
3747
+ self.snapshot_disk = async_to_streamed_response_wrapper(
3748
+ devboxes.snapshot_disk,
3749
+ )
3750
+ self.snapshot_disk_async = async_to_streamed_response_wrapper(
3751
+ devboxes.snapshot_disk_async,
3752
+ )
3753
+ self.suspend = async_to_streamed_response_wrapper(
3754
+ devboxes.suspend,
3755
+ )
3756
+ self.upload_file = async_to_streamed_response_wrapper(
3757
+ devboxes.upload_file,
3758
+ )
3759
+ self.wait_for_command = async_to_streamed_response_wrapper(
3760
+ devboxes.wait_for_command,
3761
+ )
3762
+ self.write_file_contents = async_to_streamed_response_wrapper(
3763
+ devboxes.write_file_contents,
3764
+ )
3765
+
3766
+ @cached_property
3767
+ def disk_snapshots(self) -> AsyncDiskSnapshotsResourceWithStreamingResponse:
3768
+ return AsyncDiskSnapshotsResourceWithStreamingResponse(self._devboxes.disk_snapshots)
3769
+
3770
+ @cached_property
3771
+ def browsers(self) -> AsyncBrowsersResourceWithStreamingResponse:
3772
+ return AsyncBrowsersResourceWithStreamingResponse(self._devboxes.browsers)
3773
+
3774
+ @cached_property
3775
+ def computers(self) -> AsyncComputersResourceWithStreamingResponse:
3776
+ return AsyncComputersResourceWithStreamingResponse(self._devboxes.computers)
3777
+
3778
+ @cached_property
3779
+ def logs(self) -> AsyncLogsResourceWithStreamingResponse:
3780
+ return AsyncLogsResourceWithStreamingResponse(self._devboxes.logs)
3781
+
3782
+ @cached_property
3783
+ def executions(self) -> AsyncExecutionsResourceWithStreamingResponse:
3784
+ return AsyncExecutionsResourceWithStreamingResponse(self._devboxes.executions)