Skip to content

Commit ebd75f4

Browse files
stainless-app[bot]stainless-bot
authored andcommitted
feat(api): OpenAPI spec update via Stainless API (#141)
1 parent f359981 commit ebd75f4

6 files changed

Lines changed: 198 additions & 1 deletion

File tree

.stats.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,2 @@
11
configured_endpoints: 26
2-
openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/runloop-ai%2Frunloop-e1f9515ca3a28d01bdf64ee9d93a785ba9bf4c603226f9bc3276e0b0f08d9acb.yml
2+
openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/runloop-ai%2Frunloop-f604aab9dce4ace8553e47c1fba2785330184e2b57ef594de0ac6e4027b9fd66.yml

api.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,7 @@ Methods:
6565
- <code title="get /v1/devboxes/{id}">client.devboxes.<a href="./src/runloop_api_client/resources/devboxes/devboxes.py">retrieve</a>(id) -> <a href="./src/runloop_api_client/types/devbox_view.py">DevboxView</a></code>
6666
- <code title="get /v1/devboxes">client.devboxes.<a href="./src/runloop_api_client/resources/devboxes/devboxes.py">list</a>(\*\*<a href="src/runloop_api_client/types/devbox_list_params.py">params</a>) -> <a href="./src/runloop_api_client/types/devbox_list_view.py">DevboxListView</a></code>
6767
- <code title="post /v1/devboxes/{id}/create_ssh_key">client.devboxes.<a href="./src/runloop_api_client/resources/devboxes/devboxes.py">create_ssh_key</a>(id) -> <a href="./src/runloop_api_client/types/devbox_create_ssh_key_response.py">DevboxCreateSSHKeyResponse</a></code>
68+
- <code title="post /v1/devboxes/{id}/execute_async">client.devboxes.<a href="./src/runloop_api_client/resources/devboxes/devboxes.py">execute_async</a>(id, \*\*<a href="src/runloop_api_client/types/devbox_execute_async_params.py">params</a>) -> <a href="./src/runloop_api_client/types/devbox_async_execution_detail_view.py">DevboxAsyncExecutionDetailView</a></code>
6869
- <code title="post /v1/devboxes/{id}/execute_sync">client.devboxes.<a href="./src/runloop_api_client/resources/devboxes/devboxes.py">execute_sync</a>(id, \*\*<a href="src/runloop_api_client/types/devbox_execute_sync_params.py">params</a>) -> <a href="./src/runloop_api_client/types/devbox_execution_detail_view.py">DevboxExecutionDetailView</a></code>
6970
- <code title="post /v1/devboxes/{id}/read_file_contents">client.devboxes.<a href="./src/runloop_api_client/resources/devboxes/devboxes.py">read_file_contents</a>(id, \*\*<a href="src/runloop_api_client/types/devbox_read_file_contents_params.py">params</a>) -> str</code>
7071
- <code title="post /v1/devboxes/{id}/shutdown">client.devboxes.<a href="./src/runloop_api_client/resources/devboxes/devboxes.py">shutdown</a>(id) -> <a href="./src/runloop_api_client/types/devbox_view.py">DevboxView</a></code>

src/runloop_api_client/resources/devboxes/devboxes.py

Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
devbox_write_file_params,
2121
devbox_upload_file_params,
2222
devbox_execute_sync_params,
23+
devbox_execute_async_params,
2324
devbox_read_file_contents_params,
2425
)
2526
from ..._types import NOT_GIVEN, Body, Query, Headers, NotGiven, FileTypes
@@ -50,6 +51,7 @@
5051
from ...types.devbox_list_view import DevboxListView
5152
from ...types.devbox_execution_detail_view import DevboxExecutionDetailView
5253
from ...types.devbox_create_ssh_key_response import DevboxCreateSSHKeyResponse
54+
from ...types.devbox_async_execution_detail_view import DevboxAsyncExecutionDetailView
5355

5456
__all__ = ["DevboxesResource", "AsyncDevboxesResource"]
5557

@@ -269,6 +271,43 @@ def create_ssh_key(
269271
cast_to=DevboxCreateSSHKeyResponse,
270272
)
271273

274+
def execute_async(
275+
self,
276+
id: str,
277+
*,
278+
command: str | NotGiven = NOT_GIVEN,
279+
# Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
280+
# The extra values given here take precedence over values defined on the client or passed to this method.
281+
extra_headers: Headers | None = None,
282+
extra_query: Query | None = None,
283+
extra_body: Body | None = None,
284+
timeout: float | httpx.Timeout | None | NotGiven = NOT_GIVEN,
285+
) -> DevboxAsyncExecutionDetailView:
286+
"""
287+
Asynchronously execute a command on a devbox
288+
289+
Args:
290+
command: The command to execute on the Devbox.
291+
292+
extra_headers: Send extra headers
293+
294+
extra_query: Add additional query parameters to the request
295+
296+
extra_body: Add additional JSON properties to the request
297+
298+
timeout: Override the client-level default timeout for this request, in seconds
299+
"""
300+
if not id:
301+
raise ValueError(f"Expected a non-empty value for `id` but received {id!r}")
302+
return self._post(
303+
f"/v1/devboxes/{id}/execute_async",
304+
body=maybe_transform({"command": command}, devbox_execute_async_params.DevboxExecuteAsyncParams),
305+
options=make_request_options(
306+
extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
307+
),
308+
cast_to=DevboxAsyncExecutionDetailView,
309+
)
310+
272311
def execute_sync(
273312
self,
274313
id: str,
@@ -690,6 +729,45 @@ async def create_ssh_key(
690729
cast_to=DevboxCreateSSHKeyResponse,
691730
)
692731

732+
async def execute_async(
733+
self,
734+
id: str,
735+
*,
736+
command: str | NotGiven = NOT_GIVEN,
737+
# Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
738+
# The extra values given here take precedence over values defined on the client or passed to this method.
739+
extra_headers: Headers | None = None,
740+
extra_query: Query | None = None,
741+
extra_body: Body | None = None,
742+
timeout: float | httpx.Timeout | None | NotGiven = NOT_GIVEN,
743+
) -> DevboxAsyncExecutionDetailView:
744+
"""
745+
Asynchronously execute a command on a devbox
746+
747+
Args:
748+
command: The command to execute on the Devbox.
749+
750+
extra_headers: Send extra headers
751+
752+
extra_query: Add additional query parameters to the request
753+
754+
extra_body: Add additional JSON properties to the request
755+
756+
timeout: Override the client-level default timeout for this request, in seconds
757+
"""
758+
if not id:
759+
raise ValueError(f"Expected a non-empty value for `id` but received {id!r}")
760+
return await self._post(
761+
f"/v1/devboxes/{id}/execute_async",
762+
body=await async_maybe_transform(
763+
{"command": command}, devbox_execute_async_params.DevboxExecuteAsyncParams
764+
),
765+
options=make_request_options(
766+
extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
767+
),
768+
cast_to=DevboxAsyncExecutionDetailView,
769+
)
770+
693771
async def execute_sync(
694772
self,
695773
id: str,
@@ -912,6 +990,9 @@ def __init__(self, devboxes: DevboxesResource) -> None:
912990
self.create_ssh_key = to_raw_response_wrapper(
913991
devboxes.create_ssh_key,
914992
)
993+
self.execute_async = to_raw_response_wrapper(
994+
devboxes.execute_async,
995+
)
915996
self.execute_sync = to_raw_response_wrapper(
916997
devboxes.execute_sync,
917998
)
@@ -953,6 +1034,9 @@ def __init__(self, devboxes: AsyncDevboxesResource) -> None:
9531034
self.create_ssh_key = async_to_raw_response_wrapper(
9541035
devboxes.create_ssh_key,
9551036
)
1037+
self.execute_async = async_to_raw_response_wrapper(
1038+
devboxes.execute_async,
1039+
)
9561040
self.execute_sync = async_to_raw_response_wrapper(
9571041
devboxes.execute_sync,
9581042
)
@@ -994,6 +1078,9 @@ def __init__(self, devboxes: DevboxesResource) -> None:
9941078
self.create_ssh_key = to_streamed_response_wrapper(
9951079
devboxes.create_ssh_key,
9961080
)
1081+
self.execute_async = to_streamed_response_wrapper(
1082+
devboxes.execute_async,
1083+
)
9971084
self.execute_sync = to_streamed_response_wrapper(
9981085
devboxes.execute_sync,
9991086
)
@@ -1035,6 +1122,9 @@ def __init__(self, devboxes: AsyncDevboxesResource) -> None:
10351122
self.create_ssh_key = async_to_streamed_response_wrapper(
10361123
devboxes.create_ssh_key,
10371124
)
1125+
self.execute_async = async_to_streamed_response_wrapper(
1126+
devboxes.execute_async,
1127+
)
10381128
self.execute_sync = async_to_streamed_response_wrapper(
10391129
devboxes.execute_sync,
10401130
)

src/runloop_api_client/types/__init__.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
from .blueprint_build_parameters import BlueprintBuildParameters as BlueprintBuildParameters
2727
from .devbox_execute_sync_params import DevboxExecuteSyncParams as DevboxExecuteSyncParams
2828
from .code_mount_parameters_param import CodeMountParametersParam as CodeMountParametersParam
29+
from .devbox_execute_async_params import DevboxExecuteAsyncParams as DevboxExecuteAsyncParams
2930
from .function_invoke_sync_params import FunctionInvokeSyncParams as FunctionInvokeSyncParams
3031
from .devbox_execution_detail_view import DevboxExecutionDetailView as DevboxExecutionDetailView
3132
from .function_invoke_async_params import FunctionInvokeAsyncParams as FunctionInvokeAsyncParams
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
2+
3+
from __future__ import annotations
4+
5+
from typing_extensions import TypedDict
6+
7+
__all__ = ["DevboxExecuteAsyncParams"]
8+
9+
10+
class DevboxExecuteAsyncParams(TypedDict, total=False):
11+
command: str
12+
"""The command to execute on the Devbox."""

tests/api_resources/test_devboxes.py

Lines changed: 93 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
DevboxListView,
1515
DevboxExecutionDetailView,
1616
DevboxCreateSSHKeyResponse,
17+
DevboxAsyncExecutionDetailView,
1718
)
1819

1920
base_url = os.environ.get("TEST_API_BASE_URL", "http://127.0.0.1:4010")
@@ -176,6 +177,52 @@ def test_path_params_create_ssh_key(self, client: Runloop) -> None:
176177
"",
177178
)
178179

180+
@parametrize
181+
def test_method_execute_async(self, client: Runloop) -> None:
182+
devbox = client.devboxes.execute_async(
183+
id="id",
184+
)
185+
assert_matches_type(DevboxAsyncExecutionDetailView, devbox, path=["response"])
186+
187+
@parametrize
188+
def test_method_execute_async_with_all_params(self, client: Runloop) -> None:
189+
devbox = client.devboxes.execute_async(
190+
id="id",
191+
command="command",
192+
)
193+
assert_matches_type(DevboxAsyncExecutionDetailView, devbox, path=["response"])
194+
195+
@parametrize
196+
def test_raw_response_execute_async(self, client: Runloop) -> None:
197+
response = client.devboxes.with_raw_response.execute_async(
198+
id="id",
199+
)
200+
201+
assert response.is_closed is True
202+
assert response.http_request.headers.get("X-Stainless-Lang") == "python"
203+
devbox = response.parse()
204+
assert_matches_type(DevboxAsyncExecutionDetailView, devbox, path=["response"])
205+
206+
@parametrize
207+
def test_streaming_response_execute_async(self, client: Runloop) -> None:
208+
with client.devboxes.with_streaming_response.execute_async(
209+
id="id",
210+
) as response:
211+
assert not response.is_closed
212+
assert response.http_request.headers.get("X-Stainless-Lang") == "python"
213+
214+
devbox = response.parse()
215+
assert_matches_type(DevboxAsyncExecutionDetailView, devbox, path=["response"])
216+
217+
assert cast(Any, response.is_closed) is True
218+
219+
@parametrize
220+
def test_path_params_execute_async(self, client: Runloop) -> None:
221+
with pytest.raises(ValueError, match=r"Expected a non-empty value for `id` but received ''"):
222+
client.devboxes.with_raw_response.execute_async(
223+
id="",
224+
)
225+
179226
@parametrize
180227
def test_method_execute_sync(self, client: Runloop) -> None:
181228
devbox = client.devboxes.execute_sync(
@@ -558,6 +605,52 @@ async def test_path_params_create_ssh_key(self, async_client: AsyncRunloop) -> N
558605
"",
559606
)
560607

608+
@parametrize
609+
async def test_method_execute_async(self, async_client: AsyncRunloop) -> None:
610+
devbox = await async_client.devboxes.execute_async(
611+
id="id",
612+
)
613+
assert_matches_type(DevboxAsyncExecutionDetailView, devbox, path=["response"])
614+
615+
@parametrize
616+
async def test_method_execute_async_with_all_params(self, async_client: AsyncRunloop) -> None:
617+
devbox = await async_client.devboxes.execute_async(
618+
id="id",
619+
command="command",
620+
)
621+
assert_matches_type(DevboxAsyncExecutionDetailView, devbox, path=["response"])
622+
623+
@parametrize
624+
async def test_raw_response_execute_async(self, async_client: AsyncRunloop) -> None:
625+
response = await async_client.devboxes.with_raw_response.execute_async(
626+
id="id",
627+
)
628+
629+
assert response.is_closed is True
630+
assert response.http_request.headers.get("X-Stainless-Lang") == "python"
631+
devbox = await response.parse()
632+
assert_matches_type(DevboxAsyncExecutionDetailView, devbox, path=["response"])
633+
634+
@parametrize
635+
async def test_streaming_response_execute_async(self, async_client: AsyncRunloop) -> None:
636+
async with async_client.devboxes.with_streaming_response.execute_async(
637+
id="id",
638+
) as response:
639+
assert not response.is_closed
640+
assert response.http_request.headers.get("X-Stainless-Lang") == "python"
641+
642+
devbox = await response.parse()
643+
assert_matches_type(DevboxAsyncExecutionDetailView, devbox, path=["response"])
644+
645+
assert cast(Any, response.is_closed) is True
646+
647+
@parametrize
648+
async def test_path_params_execute_async(self, async_client: AsyncRunloop) -> None:
649+
with pytest.raises(ValueError, match=r"Expected a non-empty value for `id` but received ''"):
650+
await async_client.devboxes.with_raw_response.execute_async(
651+
id="",
652+
)
653+
561654
@parametrize
562655
async def test_method_execute_sync(self, async_client: AsyncRunloop) -> None:
563656
devbox = await async_client.devboxes.execute_sync(

0 commit comments

Comments
 (0)