Skip to content

Commit c829062

Browse files
razor-xclaude
andauthored
fix: Send the action attempt poll id as a query (#636)
* fix: Stop polling an action attempt once the timeout passes Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Y1RzepycXEYA3LStfjt8cY * fix: Send the action attempt poll id as a query Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Y1RzepycXEYA3LStfjt8cY --------- Co-authored-by: Claude <noreply@anthropic.com>
1 parent 533cd1d commit c829062

2 files changed

Lines changed: 65 additions & 4 deletions

File tree

seam/modules/action_attempts.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -25,8 +25,8 @@ def validate_poll_options(timeout: float, polling_interval: float) -> None:
2525

2626

2727
def get_action_attempt(client: SeamHttpClient, action_attempt_id: str) -> ActionAttempt:
28-
res = client.post(
29-
"/action_attempts/get", json={"action_attempt_id": action_attempt_id}
28+
res = client.get(
29+
"/action_attempts/get", params={"action_attempt_id": action_attempt_id}
3030
)
3131

3232
return action_attempt_from_dict(res["action_attempt"])
@@ -93,8 +93,8 @@ def resolve_action_attempt(
9393
async def get_action_attempt_async(
9494
client: AsyncSeamHttpClient, action_attempt_id: str
9595
) -> ActionAttempt:
96-
res = await client.post(
97-
"/action_attempts/get", json={"action_attempt_id": action_attempt_id}
96+
res = await client.get(
97+
"/action_attempts/get", params={"action_attempt_id": action_attempt_id}
9898
)
9999

100100
return action_attempt_from_dict(res["action_attempt"])

test/wait_for_action_attempt_test.py

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -296,6 +296,67 @@ def test_wait_for_action_attempt_polls_at_least_once_before_timing_out(
296296
assert time.monotonic() - start < 5
297297

298298

299+
def test_wait_for_action_attempt_polls_with_the_generated_route_shape(
300+
recording_server,
301+
):
302+
success_response = {
303+
"action_attempt": {
304+
**PENDING_ACTION_ATTEMPT_RESPONSE["action_attempt"],
305+
"status": "success",
306+
"result": {},
307+
}
308+
}
309+
310+
with recording_server(
311+
[(200, PENDING_ACTION_ATTEMPT_RESPONSE), (200, success_response)]
312+
) as (endpoint, requests):
313+
seam = Seam.from_api_key("seam_apikey_token", endpoint=endpoint)
314+
315+
action_attempt = seam.action_attempts.get(
316+
action_attempt_id=PENDING_ACTION_ATTEMPT_ID,
317+
wait_for_action_attempt={"timeout": 5, "polling_interval": 0.05},
318+
)
319+
320+
assert action_attempt.status == "success"
321+
322+
# The poll goes through the same wire shape as the generated route:
323+
# a GET with the id and _strict in the query, and no request body.
324+
poll_request = requests[1]
325+
assert poll_request["method"] == "GET"
326+
assert poll_request["path"] == "/action_attempts/get"
327+
assert f"action_attempt_id={PENDING_ACTION_ATTEMPT_ID}" in poll_request["query"]
328+
assert "_strict=true" in poll_request["query"]
329+
assert poll_request["body"] is None
330+
331+
332+
def test_wait_for_action_attempt_retries_a_failed_poll(recording_server):
333+
success_response = {
334+
"action_attempt": {
335+
**PENDING_ACTION_ATTEMPT_RESPONSE["action_attempt"],
336+
"status": "success",
337+
"result": {},
338+
}
339+
}
340+
341+
with recording_server(
342+
[
343+
(200, PENDING_ACTION_ATTEMPT_RESPONSE),
344+
(503, {"error": {"type": "service_unavailable", "message": "Down"}}),
345+
(200, success_response),
346+
]
347+
) as (endpoint, requests):
348+
seam = Seam.from_api_key("seam_apikey_token", endpoint=endpoint)
349+
350+
action_attempt = seam.action_attempts.get(
351+
action_attempt_id=PENDING_ACTION_ATTEMPT_ID,
352+
wait_for_action_attempt={"timeout": 5, "polling_interval": 0.05},
353+
)
354+
355+
# A transient 503 mid-wait is retried instead of aborting the wait.
356+
assert action_attempt.status == "success"
357+
assert len(requests) == 3
358+
359+
299360
async def test_wait_for_action_attempt_rejects_a_zero_polling_interval_async(
300361
recording_server,
301362
):

0 commit comments

Comments
 (0)