Skip to content

Commit 35c4784

Browse files
feat(api): api update
1 parent c3c5658 commit 35c4784

6 files changed

Lines changed: 269 additions & 3 deletions

File tree

.stats.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
configured_endpoints: 103
1+
configured_endpoints: 104
22
openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/runloop-ai%2Frunloop-a8e2289b32b616e0bd7e15995a6553d0335bd21e30617a013d07450f8f5a7a20.yml
33
openapi_spec_hash: cd13a7af1ffe64c7ce8753f87786e01f
4-
config_hash: b9de5d96e095a7e749a8c1fc3536c308
4+
config_hash: 98a0f112ecc9445456962dab3136d7b6

api.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -108,6 +108,7 @@ Methods:
108108
- <code title="post /v1/devboxes/{id}/snapshot_disk_async">client.devboxes.<a href="./src/runloop_api_client/resources/devboxes/devboxes.py">snapshot_disk_async</a>(id, \*\*<a href="src/runloop_api_client/types/devbox_snapshot_disk_async_params.py">params</a>) -> <a href="./src/runloop_api_client/types/devbox_snapshot_view.py">DevboxSnapshotView</a></code>
109109
- <code title="post /v1/devboxes/{id}/suspend">client.devboxes.<a href="./src/runloop_api_client/resources/devboxes/devboxes.py">suspend</a>(id) -> <a href="./src/runloop_api_client/types/devbox_view.py">DevboxView</a></code>
110110
- <code title="post /v1/devboxes/{id}/upload_file">client.devboxes.<a href="./src/runloop_api_client/resources/devboxes/devboxes.py">upload_file</a>(id, \*\*<a href="src/runloop_api_client/types/devbox_upload_file_params.py">params</a>) -> object</code>
111+
- <code title="post /v1/devboxes/{id}/wait_for_status">client.devboxes.<a href="./src/runloop_api_client/resources/devboxes/devboxes.py">wait_for_command</a>(id, \*\*<a href="src/runloop_api_client/types/devbox_wait_for_command_params.py">params</a>) -> <a href="./src/runloop_api_client/types/devbox_view.py">DevboxView</a></code>
111112
- <code title="post /v1/devboxes/{id}/write_file_contents">client.devboxes.<a href="./src/runloop_api_client/resources/devboxes/devboxes.py">write_file_contents</a>(id, \*\*<a href="src/runloop_api_client/types/devbox_write_file_contents_params.py">params</a>) -> <a href="./src/runloop_api_client/types/devbox_execution_detail_view.py">DevboxExecutionDetailView</a></code>
112113

113114

src/runloop_api_client/resources/devboxes/devboxes.py

Lines changed: 134 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
from __future__ import annotations
44

5-
from typing import Dict, Mapping, Iterable, Optional, TypedDict, cast
5+
from typing import Dict, List, Mapping, Iterable, Optional, TypedDict, cast
66
from typing_extensions import Literal
77

88
import httpx
@@ -35,6 +35,7 @@
3535
devbox_execute_async_params,
3636
devbox_remove_tunnel_params,
3737
devbox_snapshot_disk_params,
38+
devbox_wait_for_command_params,
3839
devbox_read_file_contents_params,
3940
devbox_list_disk_snapshots_params,
4041
devbox_snapshot_disk_async_params,
@@ -1407,6 +1408,66 @@ def upload_file(
14071408
cast_to=object,
14081409
)
14091410

1411+
def wait_for_command(
1412+
self,
1413+
id: str,
1414+
*,
1415+
statuses: List[
1416+
Literal[
1417+
"provisioning", "initializing", "running", "suspending", "suspended", "resuming", "failure", "shutdown"
1418+
]
1419+
],
1420+
timeout_seconds: Optional[int] | NotGiven = NOT_GIVEN,
1421+
# Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
1422+
# The extra values given here take precedence over values defined on the client or passed to this method.
1423+
extra_headers: Headers | None = None,
1424+
extra_query: Query | None = None,
1425+
extra_body: Body | None = None,
1426+
timeout: float | httpx.Timeout | None | NotGiven = NOT_GIVEN,
1427+
idempotency_key: str | None = None,
1428+
) -> DevboxView:
1429+
"""
1430+
Polls the Devbox's status until it reaches one of the desired statuses or times
1431+
out.
1432+
1433+
Args:
1434+
statuses: The Devbox statuses to wait for. At least one status must be provided. The
1435+
devbox will be returned as soon as it reaches any of the provided statuses.
1436+
1437+
timeout_seconds: (Optional) Timeout in seconds to wait for the status, up to 30 seconds. Defaults
1438+
to 10 seconds.
1439+
1440+
extra_headers: Send extra headers
1441+
1442+
extra_query: Add additional query parameters to the request
1443+
1444+
extra_body: Add additional JSON properties to the request
1445+
1446+
timeout: Override the client-level default timeout for this request, in seconds
1447+
1448+
idempotency_key: Specify a custom idempotency key for this request
1449+
"""
1450+
if not id:
1451+
raise ValueError(f"Expected a non-empty value for `id` but received {id!r}")
1452+
return self._post(
1453+
f"/v1/devboxes/{id}/wait_for_status",
1454+
body=maybe_transform(
1455+
{
1456+
"statuses": statuses,
1457+
"timeout_seconds": timeout_seconds,
1458+
},
1459+
devbox_wait_for_command_params.DevboxWaitForCommandParams,
1460+
),
1461+
options=make_request_options(
1462+
extra_headers=extra_headers,
1463+
extra_query=extra_query,
1464+
extra_body=extra_body,
1465+
timeout=timeout,
1466+
idempotency_key=idempotency_key,
1467+
),
1468+
cast_to=DevboxView,
1469+
)
1470+
14101471
def write_file_contents(
14111472
self,
14121473
id: str,
@@ -2735,6 +2796,66 @@ async def upload_file(
27352796
cast_to=object,
27362797
)
27372798

2799+
async def wait_for_command(
2800+
self,
2801+
id: str,
2802+
*,
2803+
statuses: List[
2804+
Literal[
2805+
"provisioning", "initializing", "running", "suspending", "suspended", "resuming", "failure", "shutdown"
2806+
]
2807+
],
2808+
timeout_seconds: Optional[int] | NotGiven = NOT_GIVEN,
2809+
# Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
2810+
# The extra values given here take precedence over values defined on the client or passed to this method.
2811+
extra_headers: Headers | None = None,
2812+
extra_query: Query | None = None,
2813+
extra_body: Body | None = None,
2814+
timeout: float | httpx.Timeout | None | NotGiven = NOT_GIVEN,
2815+
idempotency_key: str | None = None,
2816+
) -> DevboxView:
2817+
"""
2818+
Polls the Devbox's status until it reaches one of the desired statuses or times
2819+
out.
2820+
2821+
Args:
2822+
statuses: The Devbox statuses to wait for. At least one status must be provided. The
2823+
devbox will be returned as soon as it reaches any of the provided statuses.
2824+
2825+
timeout_seconds: (Optional) Timeout in seconds to wait for the status, up to 30 seconds. Defaults
2826+
to 10 seconds.
2827+
2828+
extra_headers: Send extra headers
2829+
2830+
extra_query: Add additional query parameters to the request
2831+
2832+
extra_body: Add additional JSON properties to the request
2833+
2834+
timeout: Override the client-level default timeout for this request, in seconds
2835+
2836+
idempotency_key: Specify a custom idempotency key for this request
2837+
"""
2838+
if not id:
2839+
raise ValueError(f"Expected a non-empty value for `id` but received {id!r}")
2840+
return await self._post(
2841+
f"/v1/devboxes/{id}/wait_for_status",
2842+
body=await async_maybe_transform(
2843+
{
2844+
"statuses": statuses,
2845+
"timeout_seconds": timeout_seconds,
2846+
},
2847+
devbox_wait_for_command_params.DevboxWaitForCommandParams,
2848+
),
2849+
options=make_request_options(
2850+
extra_headers=extra_headers,
2851+
extra_query=extra_query,
2852+
extra_body=extra_body,
2853+
timeout=timeout,
2854+
idempotency_key=idempotency_key,
2855+
),
2856+
cast_to=DevboxView,
2857+
)
2858+
27382859
async def write_file_contents(
27392860
self,
27402861
id: str,
@@ -2862,6 +2983,9 @@ def __init__(self, devboxes: DevboxesResource) -> None:
28622983
self.upload_file = to_raw_response_wrapper(
28632984
devboxes.upload_file,
28642985
)
2986+
self.wait_for_command = to_raw_response_wrapper(
2987+
devboxes.wait_for_command,
2988+
)
28652989
self.write_file_contents = to_raw_response_wrapper(
28662990
devboxes.write_file_contents,
28672991
)
@@ -2959,6 +3083,9 @@ def __init__(self, devboxes: AsyncDevboxesResource) -> None:
29593083
self.upload_file = async_to_raw_response_wrapper(
29603084
devboxes.upload_file,
29613085
)
3086+
self.wait_for_command = async_to_raw_response_wrapper(
3087+
devboxes.wait_for_command,
3088+
)
29623089
self.write_file_contents = async_to_raw_response_wrapper(
29633090
devboxes.write_file_contents,
29643091
)
@@ -3056,6 +3183,9 @@ def __init__(self, devboxes: DevboxesResource) -> None:
30563183
self.upload_file = to_streamed_response_wrapper(
30573184
devboxes.upload_file,
30583185
)
3186+
self.wait_for_command = to_streamed_response_wrapper(
3187+
devboxes.wait_for_command,
3188+
)
30593189
self.write_file_contents = to_streamed_response_wrapper(
30603190
devboxes.write_file_contents,
30613191
)
@@ -3153,6 +3283,9 @@ def __init__(self, devboxes: AsyncDevboxesResource) -> None:
31533283
self.upload_file = async_to_streamed_response_wrapper(
31543284
devboxes.upload_file,
31553285
)
3286+
self.wait_for_command = async_to_streamed_response_wrapper(
3287+
devboxes.wait_for_command,
3288+
)
31563289
self.write_file_contents = async_to_streamed_response_wrapper(
31573290
devboxes.write_file_contents,
31583291
)

src/runloop_api_client/types/__init__.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,7 @@
8686
from .scoring_contract_update_param import ScoringContractUpdateParam as ScoringContractUpdateParam
8787
from .blueprint_build_logs_list_view import BlueprintBuildLogsListView as BlueprintBuildLogsListView
8888
from .devbox_create_ssh_key_response import DevboxCreateSSHKeyResponse as DevboxCreateSSHKeyResponse
89+
from .devbox_wait_for_command_params import DevboxWaitForCommandParams as DevboxWaitForCommandParams
8990
from .repository_connection_list_view import RepositoryConnectionListView as RepositoryConnectionListView
9091
from .repository_inspection_list_view import RepositoryInspectionListView as RepositoryInspectionListView
9192
from .devbox_read_file_contents_params import DevboxReadFileContentsParams as DevboxReadFileContentsParams
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
2+
3+
from __future__ import annotations
4+
5+
from typing import List, Optional
6+
from typing_extensions import Literal, Required, TypedDict
7+
8+
__all__ = ["DevboxWaitForCommandParams"]
9+
10+
11+
class DevboxWaitForCommandParams(TypedDict, total=False):
12+
statuses: Required[
13+
List[
14+
Literal[
15+
"provisioning", "initializing", "running", "suspending", "suspended", "resuming", "failure", "shutdown"
16+
]
17+
]
18+
]
19+
"""The Devbox statuses to wait for.
20+
21+
At least one status must be provided. The devbox will be returned as soon as it
22+
reaches any of the provided statuses.
23+
"""
24+
25+
timeout_seconds: Optional[int]
26+
"""(Optional) Timeout in seconds to wait for the status, up to 30 seconds.
27+
28+
Defaults to 10 seconds.
29+
"""

tests/api_resources/test_devboxes.py

Lines changed: 102 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -980,6 +980,57 @@ def test_path_params_upload_file(self, client: Runloop) -> None:
980980
path="path",
981981
)
982982

983+
@parametrize
984+
def test_method_wait_for_command(self, client: Runloop) -> None:
985+
devbox = client.devboxes.wait_for_command(
986+
id="id",
987+
statuses=["provisioning"],
988+
)
989+
assert_matches_type(DevboxView, devbox, path=["response"])
990+
991+
@parametrize
992+
def test_method_wait_for_command_with_all_params(self, client: Runloop) -> None:
993+
devbox = client.devboxes.wait_for_command(
994+
id="id",
995+
statuses=["provisioning"],
996+
timeout_seconds=0,
997+
)
998+
assert_matches_type(DevboxView, devbox, path=["response"])
999+
1000+
@parametrize
1001+
def test_raw_response_wait_for_command(self, client: Runloop) -> None:
1002+
response = client.devboxes.with_raw_response.wait_for_command(
1003+
id="id",
1004+
statuses=["provisioning"],
1005+
)
1006+
1007+
assert response.is_closed is True
1008+
assert response.http_request.headers.get("X-Stainless-Lang") == "python"
1009+
devbox = response.parse()
1010+
assert_matches_type(DevboxView, devbox, path=["response"])
1011+
1012+
@parametrize
1013+
def test_streaming_response_wait_for_command(self, client: Runloop) -> None:
1014+
with client.devboxes.with_streaming_response.wait_for_command(
1015+
id="id",
1016+
statuses=["provisioning"],
1017+
) as response:
1018+
assert not response.is_closed
1019+
assert response.http_request.headers.get("X-Stainless-Lang") == "python"
1020+
1021+
devbox = response.parse()
1022+
assert_matches_type(DevboxView, devbox, path=["response"])
1023+
1024+
assert cast(Any, response.is_closed) is True
1025+
1026+
@parametrize
1027+
def test_path_params_wait_for_command(self, client: Runloop) -> None:
1028+
with pytest.raises(ValueError, match=r"Expected a non-empty value for `id` but received ''"):
1029+
client.devboxes.with_raw_response.wait_for_command(
1030+
id="",
1031+
statuses=["provisioning"],
1032+
)
1033+
9831034
@parametrize
9841035
def test_method_write_file_contents(self, client: Runloop) -> None:
9851036
devbox = client.devboxes.write_file_contents(
@@ -2256,6 +2307,57 @@ async def test_path_params_upload_file(self, async_client: AsyncRunloop) -> None
22562307
path="path",
22572308
)
22582309

2310+
@parametrize
2311+
async def test_method_wait_for_command(self, async_client: AsyncRunloop) -> None:
2312+
devbox = await async_client.devboxes.wait_for_command(
2313+
id="id",
2314+
statuses=["provisioning"],
2315+
)
2316+
assert_matches_type(DevboxView, devbox, path=["response"])
2317+
2318+
@parametrize
2319+
async def test_method_wait_for_command_with_all_params(self, async_client: AsyncRunloop) -> None:
2320+
devbox = await async_client.devboxes.wait_for_command(
2321+
id="id",
2322+
statuses=["provisioning"],
2323+
timeout_seconds=0,
2324+
)
2325+
assert_matches_type(DevboxView, devbox, path=["response"])
2326+
2327+
@parametrize
2328+
async def test_raw_response_wait_for_command(self, async_client: AsyncRunloop) -> None:
2329+
response = await async_client.devboxes.with_raw_response.wait_for_command(
2330+
id="id",
2331+
statuses=["provisioning"],
2332+
)
2333+
2334+
assert response.is_closed is True
2335+
assert response.http_request.headers.get("X-Stainless-Lang") == "python"
2336+
devbox = await response.parse()
2337+
assert_matches_type(DevboxView, devbox, path=["response"])
2338+
2339+
@parametrize
2340+
async def test_streaming_response_wait_for_command(self, async_client: AsyncRunloop) -> None:
2341+
async with async_client.devboxes.with_streaming_response.wait_for_command(
2342+
id="id",
2343+
statuses=["provisioning"],
2344+
) as response:
2345+
assert not response.is_closed
2346+
assert response.http_request.headers.get("X-Stainless-Lang") == "python"
2347+
2348+
devbox = await response.parse()
2349+
assert_matches_type(DevboxView, devbox, path=["response"])
2350+
2351+
assert cast(Any, response.is_closed) is True
2352+
2353+
@parametrize
2354+
async def test_path_params_wait_for_command(self, async_client: AsyncRunloop) -> None:
2355+
with pytest.raises(ValueError, match=r"Expected a non-empty value for `id` but received ''"):
2356+
await async_client.devboxes.with_raw_response.wait_for_command(
2357+
id="",
2358+
statuses=["provisioning"],
2359+
)
2360+
22592361
@parametrize
22602362
async def test_method_write_file_contents(self, async_client: AsyncRunloop) -> None:
22612363
devbox = await async_client.devboxes.write_file_contents(

0 commit comments

Comments
 (0)