1717 async_to_streamed_response_wrapper ,
1818)
1919from ..._constants import DEFAULT_TIMEOUT
20- from ..._exceptions import APIStatusError
20+ from ..._exceptions import APIStatusError , APITimeoutError
2121from ...lib .polling import PollingConfig , poll_until
2222from ..._base_client import make_request_options
2323from ...types .devboxes import execution_retrieve_params , execution_execute_sync_params , execution_execute_async_params
2828__all__ = ["ExecutionsResource" , "AsyncExecutionsResource" ]
2929
3030
31+ def placeholder_execution_detail_view (devbox_id : str , execution_id : str ) -> DevboxAsyncExecutionDetailView :
32+ return DevboxAsyncExecutionDetailView (
33+ devbox_id = devbox_id ,
34+ execution_id = execution_id ,
35+ status = "queued" ,
36+ stdout = "" ,
37+ stderr = "" ,
38+ )
39+
40+
3141class ExecutionsResource (SyncAPIResource ):
3242 @cached_property
3343 def with_raw_response (self ) -> ExecutionsResourceWithRawResponse :
@@ -97,13 +107,8 @@ def await_completed(
97107 execution_id : str ,
98108 devbox_id : str ,
99109 * ,
100- config : PollingConfig | None = None ,
101- # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
102- # The extra values given here take precedence over values defined on the client or passed to this method.
103- extra_headers : Headers | None = None ,
104- extra_query : Query | None = None ,
105- extra_body : Body | None = None ,
106- timeout : float | httpx .Timeout | None | NotGiven = NOT_GIVEN ,
110+ # Use polling_config to configure the "long" polling behavior.
111+ polling_config : PollingConfig | None = None ,
107112 ) -> DevboxAsyncExecutionDetailView :
108113 """Wait for an execution to complete.
109114
@@ -128,31 +133,24 @@ def wait_for_execution_status() -> DevboxAsyncExecutionDetailView:
128133 return self ._post (
129134 f"/v1/devboxes/{ devbox_id } /executions/{ execution_id } /wait_for_status" ,
130135 body = {"statuses" : ["completed" ]},
131- options = make_request_options (
132- extra_headers = extra_headers , extra_query = extra_query , extra_body = extra_body , timeout = timeout
133- ),
134136 cast_to = DevboxAsyncExecutionDetailView ,
135137 )
136138
137139 def handle_timeout_error (error : Exception ) -> DevboxAsyncExecutionDetailView :
138- # Handle 408 timeout errors by returning current execution state to continue polling
139- if isinstance (error , APIStatusError ) and error .response .status_code == 408 :
140+ # Handle timeout errors by returning current execution state to continue polling
141+ if isinstance (error , APITimeoutError ) or (
142+ isinstance (error , APIStatusError ) and error .response .status_code == 408
143+ ):
140144 # Return a placeholder result to continue polling
141- return DevboxAsyncExecutionDetailView (
142- devbox_id = devbox_id ,
143- execution_id = execution_id ,
144- status = "queued" ,
145- stdout = "" ,
146- stderr = "" ,
147- )
145+ return placeholder_execution_detail_view (devbox_id , execution_id )
148146 else :
149147 # Re-raise other errors to stop polling
150148 raise error
151149
152150 def is_done (execution : DevboxAsyncExecutionDetailView ) -> bool :
153151 return execution .status == "completed"
154152
155- return poll_until (wait_for_execution_status , is_done , config , handle_timeout_error )
153+ return poll_until (wait_for_execution_status , is_done , polling_config , handle_timeout_error )
156154
157155 def execute_async (
158156 self ,
@@ -390,13 +388,8 @@ async def await_completed(
390388 execution_id : str ,
391389 * ,
392390 devbox_id : str ,
391+ # Use polling_config to configure the "long" polling behavior.
393392 polling_config : PollingConfig | None = None ,
394- # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
395- # The extra values given here take precedence over values defined on the client or passed to this method.
396- extra_headers : Headers | None = None ,
397- extra_query : Query | None = None ,
398- extra_body : Body | None = None ,
399- timeout : float | httpx .Timeout | None | NotGiven = NOT_GIVEN ,
400393 ) -> DevboxAsyncExecutionDetailView :
401394 """Wait for an execution to complete.
402395
@@ -421,24 +414,15 @@ async def wait_for_execution_status() -> DevboxAsyncExecutionDetailView:
421414 return await self ._post (
422415 f"/v1/devboxes/{ devbox_id } /executions/{ execution_id } /wait_for_status" ,
423416 body = {"statuses" : ["completed" ]},
424- options = make_request_options (
425- extra_headers = extra_headers , extra_query = extra_query , extra_body = extra_body , timeout = timeout
426- ),
427417 cast_to = DevboxAsyncExecutionDetailView ,
428418 )
429- except APIStatusError as error :
430- if error .response .status_code == 408 :
431- # Handle 408 timeout errors by returning current execution state to continue polling
432- return DevboxAsyncExecutionDetailView (
433- devbox_id = devbox_id ,
434- execution_id = execution_id ,
435- status = "queued" ,
436- stdout = "" ,
437- stderr = "" ,
438- )
439- else :
440- # Re-raise other errors to stop polling
441- raise
419+ except (APITimeoutError , APIStatusError ) as error :
420+ # Handle timeout errors by returning placeholder to continue polling
421+ if isinstance (error , APITimeoutError ) or error .response .status_code == 408 :
422+ return placeholder_execution_detail_view (devbox_id , execution_id )
423+
424+ # Re-raise other errors to stop polling
425+ raise
442426
443427 def is_done (execution : DevboxAsyncExecutionDetailView ) -> bool :
444428 return execution .status == "completed"
0 commit comments