Skip to content

Commit 92c7db9

Browse files
authored
Merge pull request #630 from runloopai/tode/request_args-fix
Unpack args directly in python-sdk
2 parents 0148f1f + c2fe500 commit 92c7db9

8 files changed

Lines changed: 193 additions & 107 deletions

File tree

api.md

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -57,13 +57,13 @@ from runloop_api_client.types import (
5757
Methods:
5858

5959
- <code title="post /v1/blueprints">client.blueprints.<a href="./src/runloop_api_client/resources/blueprints.py">create</a>(\*\*<a href="src/runloop_api_client/types/blueprint_create_params.py">params</a>) -> <a href="./src/runloop_api_client/types/blueprint_view.py">BlueprintView</a></code>
60+
- <code title="create_and_await_build_complete">client.blueprints.<a href="./src/runloop_api_client/resources/blueprints.py">create_and_await_build_complete</a>(\*\*<a href="src/runloop_api_client/types/blueprint_create_params.py">params) -> <a href="./src/runloop_api_client/types/blueprint_view.py">BlueprintView</a></code>
6061
- <code title="get /v1/blueprints/{id}">client.blueprints.<a href="./src/runloop_api_client/resources/blueprints.py">retrieve</a>(id) -> <a href="./src/runloop_api_client/types/blueprint_view.py">BlueprintView</a></code>
6162
- <code title="get /v1/blueprints">client.blueprints.<a href="./src/runloop_api_client/resources/blueprints.py">list</a>(\*\*<a href="src/runloop_api_client/types/blueprint_list_params.py">params</a>) -> <a href="./src/runloop_api_client/types/blueprint_view.py">SyncBlueprintsCursorIDPage[BlueprintView]</a></code>
6263
- <code title="post /v1/blueprints/{id}/delete">client.blueprints.<a href="./src/runloop_api_client/resources/blueprints.py">delete</a>(id) -> object</code>
6364
- <code title="get /v1/blueprints/list_public">client.blueprints.<a href="./src/runloop_api_client/resources/blueprints.py">list_public</a>(\*\*<a href="src/runloop_api_client/types/blueprint_list_public_params.py">params</a>) -> <a href="./src/runloop_api_client/types/blueprint_view.py">SyncBlueprintsCursorIDPage[BlueprintView]</a></code>
6465
- <code title="get /v1/blueprints/{id}/logs">client.blueprints.<a href="./src/runloop_api_client/resources/blueprints.py">logs</a>(id) -> <a href="./src/runloop_api_client/types/blueprint_build_logs_list_view.py">BlueprintBuildLogsListView</a></code>
6566
- <code title="post /v1/blueprints/preview">client.blueprints.<a href="./src/runloop_api_client/resources/blueprints.py">preview</a>(\*\*<a href="src/runloop_api_client/types/blueprint_preview_params.py">params</a>) -> <a href="./src/runloop_api_client/types/blueprint_preview_view.py">BlueprintPreviewView</a></code>
66-
- <code title="create_and_await_build_complete">client.blueprints.<a href="./src/runloop_api_client/resources/blueprints.py">create_and_await_build_complete</a>(<a href="src/runloop_api_client/types/blueprint_create_params.py">create_args</a>, <a href="src/runloop_api_client/resources/blueprints.py">request_args</a>=None) -> <a href="./src/runloop_api_client/types/blueprint_view.py">BlueprintView</a></code>
6767

6868
# Devboxes
6969

@@ -86,6 +86,7 @@ from runloop_api_client.types import (
8686
Methods:
8787

8888
- <code title="post /v1/devboxes">client.devboxes.<a href="./src/runloop_api_client/resources/devboxes/devboxes.py">create</a>(\*\*<a href="src/runloop_api_client/types/devbox_create_params.py">params</a>) -> <a href="./src/runloop_api_client/types/devbox_view.py">DevboxView</a></code>
89+
- <code title="create_and_await_running">client.devboxes.<a href="./src/runloop_api_client/resources/devboxes/devboxes.py">create_and_await_running</a>(\*\*<a href="src/runloop_api_client/types/devbox_create_params.py">params</a>) -> <a href="./src/runloop_api_client/types/devbox_view.py">DevboxView</a></code>
8990
- <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>
9091
- <code title="post /v1/devboxes/{id}">client.devboxes.<a href="./src/runloop_api_client/resources/devboxes/devboxes.py">update</a>(id, \*\*<a href="src/runloop_api_client/types/devbox_update_params.py">params</a>) -> <a href="./src/runloop_api_client/types/devbox_view.py">DevboxView</a></code>
9192
- <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_view.py">SyncDevboxesCursorIDPage[DevboxView]</a></code>
@@ -106,7 +107,7 @@ Methods:
106107
- <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>
107108
- <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>
108109
- <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>
109-
- <code title="create_and_await_running">client.devboxes.<a href="./src/runloop_api_client/resources/devboxes/devboxes.py">create_and_await_running</a>(<a href="src/runloop_api_client/types/devbox_create_params.py">create_args</a>, <a href="src/runloop_api_client/resources/devboxes/devboxes.py">request_args</a>=None) -> <a href="./src/runloop_api_client/types/devbox_view.py">DevboxView</a></code>
110+
110111

111112
## DiskSnapshots
112113

src/runloop_api_client/lib/polling_async.py

Lines changed: 13 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,8 @@
44

55
from .polling import PollingConfig, PollingTimeout
66

7-
T = TypeVar('T')
7+
T = TypeVar("T")
8+
89

910
async def async_poll_until(
1011
retriever: Callable[[], Awaitable[T]],
@@ -14,27 +15,27 @@ async def async_poll_until(
1415
) -> T:
1516
"""
1617
Poll until a condition is met or timeout/max attempts are reached.
17-
18+
1819
Args:
1920
retriever: Async or sync callable that returns the object to check
2021
is_terminal: Callable that returns True when polling should stop
2122
config: Optional polling configuration
2223
on_error: Optional error handler that can return a value to continue polling
2324
or re-raise the exception to stop polling
24-
25+
2526
Returns:
2627
The final state of the polled object
27-
28+
2829
Raises:
2930
PollingTimeout: When max attempts or timeout is reached
3031
"""
3132
if config is None:
3233
config = PollingConfig()
33-
34+
3435
attempts = 0
3536
start_time = time.time()
3637
last_result: Union[T, None] = None
37-
38+
3839
while True:
3940
try:
4041
last_result = await retriever()
@@ -43,23 +44,17 @@ async def async_poll_until(
4344
last_result = on_error(e)
4445
else:
4546
raise
46-
47+
4748
if is_terminal(last_result):
4849
return last_result
49-
50+
5051
attempts += 1
5152
if attempts >= config.max_attempts:
52-
raise PollingTimeout(
53-
f"Exceeded maximum attempts ({config.max_attempts})",
54-
last_result
55-
)
56-
53+
raise PollingTimeout(f"Exceeded maximum attempts ({config.max_attempts})", last_result)
54+
5755
if config.timeout_seconds is not None:
5856
elapsed = time.time() - start_time
5957
if elapsed >= config.timeout_seconds:
60-
raise PollingTimeout(
61-
f"Exceeded timeout of {config.timeout_seconds} seconds",
62-
last_result
63-
)
64-
58+
raise PollingTimeout(f"Exceeded timeout of {config.timeout_seconds} seconds", last_result)
59+
6560
await asyncio.sleep(config.interval_seconds)

src/runloop_api_client/resources/blueprints.py

Lines changed: 76 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -230,16 +230,30 @@ def is_done_building(blueprint: BlueprintView) -> bool:
230230
def create_and_await_build_complete(
231231
self,
232232
*,
233-
create_args: blueprint_create_params.BlueprintCreateParams,
234-
request_args: BlueprintRequestArgs | None = None,
233+
name: str,
234+
base_blueprint_id: Optional[str] | NotGiven = NOT_GIVEN,
235+
code_mounts: Optional[Iterable[CodeMountParameters]] | NotGiven = NOT_GIVEN,
236+
dockerfile: Optional[str] | NotGiven = NOT_GIVEN,
237+
file_mounts: Optional[Dict[str, str]] | NotGiven = NOT_GIVEN,
238+
launch_parameters: Optional[LaunchParameters] | NotGiven = NOT_GIVEN,
239+
polling_config: PollingConfig | None = None,
240+
services: Optional[Iterable[blueprint_create_params.Service]] | NotGiven = NOT_GIVEN,
241+
system_setup_commands: Optional[List[str]] | NotGiven = NOT_GIVEN,
242+
# Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
243+
# The extra values given here take precedence over values defined on the client or passed to this method.
244+
extra_headers: Headers | None = None,
245+
extra_query: Query | None = None,
246+
extra_body: Body | None = None,
247+
timeout: float | httpx.Timeout | None | NotGiven = NOT_GIVEN,
248+
idempotency_key: str | None = None,
235249
) -> BlueprintView:
236250
"""Create a new Blueprint and wait for it to finish building.
237251
238252
This is a wrapper around the `create` method that waits for the blueprint to finish building.
239253
240254
Args:
241-
create_args: Arguments to pass to the `create` method. See the `create` method for detailed documentation.
242-
request_args: Optional request arguments including polling configuration and additional request options
255+
See the `create` method for detailed documentation.
256+
polling_config: Optional polling configuration
243257
244258
Returns:
245259
The built blueprint
@@ -249,18 +263,29 @@ def create_and_await_build_complete(
249263
RunloopError: If blueprint enters a non-built terminal state
250264
"""
251265
# Pass all create_args to the underlying create method
252-
blueprint = self.create(**create_args)
253-
254-
if request_args is None:
255-
request_args = {}
266+
blueprint = self.create(
267+
name=name,
268+
base_blueprint_id=base_blueprint_id,
269+
code_mounts=code_mounts,
270+
dockerfile=dockerfile,
271+
file_mounts=file_mounts,
272+
launch_parameters=launch_parameters,
273+
services=services,
274+
system_setup_commands=system_setup_commands,
275+
extra_headers=extra_headers,
276+
extra_query=extra_query,
277+
extra_body=extra_body,
278+
timeout=timeout,
279+
idempotency_key=idempotency_key,
280+
)
256281

257282
return self.await_build_complete(
258283
blueprint.id,
259-
polling_config=request_args.get("polling_config", None),
260-
extra_headers=request_args.get("extra_headers", None),
261-
extra_query=request_args.get("extra_query", None),
262-
extra_body=request_args.get("extra_body", None),
263-
timeout=request_args.get("timeout", None),
284+
polling_config=polling_config,
285+
extra_headers=extra_headers,
286+
extra_query=extra_query,
287+
extra_body=extra_body,
288+
timeout=timeout,
264289
)
265290

266291
def list(
@@ -700,16 +725,30 @@ def is_done_building(blueprint: BlueprintView) -> bool:
700725
async def create_and_await_build_complete(
701726
self,
702727
*,
703-
create_args: blueprint_create_params.BlueprintCreateParams,
704-
request_args: BlueprintRequestArgs | None = None,
728+
name: str,
729+
base_blueprint_id: Optional[str] | NotGiven = NOT_GIVEN,
730+
code_mounts: Optional[Iterable[CodeMountParameters]] | NotGiven = NOT_GIVEN,
731+
dockerfile: Optional[str] | NotGiven = NOT_GIVEN,
732+
file_mounts: Optional[Dict[str, str]] | NotGiven = NOT_GIVEN,
733+
launch_parameters: Optional[LaunchParameters] | NotGiven = NOT_GIVEN,
734+
polling_config: PollingConfig | None = None,
735+
services: Optional[Iterable[blueprint_create_params.Service]] | NotGiven = NOT_GIVEN,
736+
system_setup_commands: Optional[List[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+
idempotency_key: str | None = None,
705744
) -> BlueprintView:
706745
"""Create a new Blueprint and wait for it to finish building.
707746
708747
This is a wrapper around the `create` method that waits for the blueprint to finish building.
709748
710749
Args:
711-
create_args: Arguments to pass to the `create` method. See the `create` method for detailed documentation.
712-
request_args: Optional request arguments including polling configuration and additional request options
750+
See the `create` method for detailed documentation.
751+
polling_config: Optional polling configuration
713752
714753
Returns:
715754
The built blueprint
@@ -719,19 +758,29 @@ async def create_and_await_build_complete(
719758
RunloopError: If blueprint enters a non-built terminal state
720759
"""
721760
# Pass all create_args to the underlying create method
722-
blueprint = await self.create(**create_args)
723-
724-
# Extract polling config and other request args
725-
if request_args is None:
726-
request_args = {}
761+
blueprint = await self.create(
762+
name=name,
763+
base_blueprint_id=base_blueprint_id,
764+
code_mounts=code_mounts,
765+
dockerfile=dockerfile,
766+
file_mounts=file_mounts,
767+
launch_parameters=launch_parameters,
768+
services=services,
769+
system_setup_commands=system_setup_commands,
770+
extra_headers=extra_headers,
771+
extra_query=extra_query,
772+
extra_body=extra_body,
773+
timeout=timeout,
774+
idempotency_key=idempotency_key,
775+
)
727776

728777
return await self.await_build_complete(
729778
blueprint.id,
730-
polling_config=request_args.get("polling_config", None),
731-
extra_headers=request_args.get("extra_headers", None),
732-
extra_query=request_args.get("extra_query", None),
733-
extra_body=request_args.get("extra_body", None),
734-
timeout=request_args.get("timeout", None),
779+
polling_config=polling_config,
780+
extra_headers=extra_headers,
781+
extra_query=extra_query,
782+
extra_body=extra_body,
783+
timeout=timeout,
735784
)
736785

737786
def list(

0 commit comments

Comments
 (0)