Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 4 additions & 4 deletions seam/modules/action_attempts.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,8 @@ def validate_poll_options(timeout: float, polling_interval: float) -> None:


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

return action_attempt_from_dict(res["action_attempt"])
Expand Down Expand Up @@ -93,8 +93,8 @@ def resolve_action_attempt(
async def get_action_attempt_async(
client: AsyncSeamHttpClient, action_attempt_id: str
) -> ActionAttempt:
res = await client.post(
"/action_attempts/get", json={"action_attempt_id": action_attempt_id}
res = await client.get(
"/action_attempts/get", params={"action_attempt_id": action_attempt_id}
)

return action_attempt_from_dict(res["action_attempt"])
Expand Down
61 changes: 61 additions & 0 deletions test/wait_for_action_attempt_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -296,6 +296,67 @@ def test_wait_for_action_attempt_polls_at_least_once_before_timing_out(
assert time.monotonic() - start < 5


def test_wait_for_action_attempt_polls_with_the_generated_route_shape(
recording_server,
):
success_response = {
"action_attempt": {
**PENDING_ACTION_ATTEMPT_RESPONSE["action_attempt"],
"status": "success",
"result": {},
}
}

with recording_server(
[(200, PENDING_ACTION_ATTEMPT_RESPONSE), (200, success_response)]
) as (endpoint, requests):
seam = Seam.from_api_key("seam_apikey_token", endpoint=endpoint)

action_attempt = seam.action_attempts.get(
action_attempt_id=PENDING_ACTION_ATTEMPT_ID,
wait_for_action_attempt={"timeout": 5, "polling_interval": 0.05},
)

assert action_attempt.status == "success"

# The poll goes through the same wire shape as the generated route:
# a GET with the id and _strict in the query, and no request body.
poll_request = requests[1]
assert poll_request["method"] == "GET"
assert poll_request["path"] == "/action_attempts/get"
assert f"action_attempt_id={PENDING_ACTION_ATTEMPT_ID}" in poll_request["query"]
assert "_strict=true" in poll_request["query"]
assert poll_request["body"] is None


def test_wait_for_action_attempt_retries_a_failed_poll(recording_server):
success_response = {
"action_attempt": {
**PENDING_ACTION_ATTEMPT_RESPONSE["action_attempt"],
"status": "success",
"result": {},
}
}

with recording_server(
[
(200, PENDING_ACTION_ATTEMPT_RESPONSE),
(503, {"error": {"type": "service_unavailable", "message": "Down"}}),
(200, success_response),
]
) as (endpoint, requests):
seam = Seam.from_api_key("seam_apikey_token", endpoint=endpoint)

action_attempt = seam.action_attempts.get(
action_attempt_id=PENDING_ACTION_ATTEMPT_ID,
wait_for_action_attempt={"timeout": 5, "polling_interval": 0.05},
)

# A transient 503 mid-wait is retried instead of aborting the wait.
assert action_attempt.status == "success"
assert len(requests) == 3


async def test_wait_for_action_attempt_rejects_a_zero_polling_interval_async(
recording_server,
):
Expand Down
Loading