Skip to content

Commit 0a4d740

Browse files
authored
Merge pull request #469 from ssl-hep/fix-ClientPayloadError
Add retries on the `get` request of `get_transform_status` function
2 parents 3874cda + 5bc0c40 commit 0a4d740

File tree

3 files changed

+39
-11
lines changed

3 files changed

+39
-11
lines changed

pyproject.toml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,8 @@ dependencies = [
5151
"make-it-sync", # compatible versions controlled through func_adl
5252
"ruamel.yaml>=0.18",
5353
"ccorp-yaml-include-relative-path>=0.0.4",
54-
"filelock>=3.12.0"
54+
"filelock>=3.12.0",
55+
"tenacity >= 9.0.0"
5556
]
5657

5758
[project.scripts]

servicex/servicex_adapter.py

Lines changed: 23 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@
3232
import httpx
3333
from aiohttp_retry import RetryClient, ExponentialRetry
3434
from google.auth import jwt
35+
from tenacity import AsyncRetrying, stop_after_attempt, wait_fixed, retry_if_not_exception_type
3536

3637
from servicex.models import TransformRequest, TransformStatus
3738

@@ -131,13 +132,26 @@ async def submit_transform(self, transform_request: TransformRequest):
131132

132133
async def get_transform_status(self, request_id: str) -> TransformStatus:
133134
headers = await self._get_authorization()
134-
retry_options = ExponentialRetry(attempts=5, start_timeout=10)
135+
retry_options = ExponentialRetry(attempts=5, start_timeout=3)
135136
async with RetryClient(retry_options=retry_options) as client:
136-
async with client.get(url=f"{self.url}/servicex/transformation/{request_id}",
137-
headers=headers) as r:
138-
if r.status == 401:
139-
raise AuthorizationError(f"Not authorized to access serviceX at {self.url}")
140-
if r.status == 404:
141-
raise ValueError(f"Transform ID {request_id} not found")
142-
o = await r.json()
143-
return TransformStatus(**o)
137+
try:
138+
async for attempt in AsyncRetrying(
139+
retry=(retry_if_not_exception_type(AuthorizationError)
140+
| retry_if_not_exception_type(ValueError)),
141+
stop=stop_after_attempt(3),
142+
wait=wait_fixed(3),
143+
reraise=True):
144+
with attempt:
145+
async with client.get(url=f"{self.url}/servicex/"
146+
f"transformation/{request_id}",
147+
headers=headers) as r:
148+
if r.status == 401:
149+
raise AuthorizationError("Not authorized to access serviceX"
150+
f"at {self.url}")
151+
if r.status == 404:
152+
raise ValueError(f"Transform ID {request_id} not found")
153+
o = await r.json()
154+
return TransformStatus(**o)
155+
except RuntimeError as e:
156+
raise RuntimeError("ServiceX WebAPI Error "
157+
f"while getting transform status: {e}")

tests/test_servicex_adapter.py

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,6 @@
3131
import httpx
3232
import pytest
3333
from pytest_asyncio import fixture
34-
3534
from servicex.models import TransformRequest, ResultDestination, ResultFormat
3635
from servicex.servicex_adapter import ServiceXAdapter, AuthorizationError
3736

@@ -199,6 +198,20 @@ async def test_get_transform_status_auth_error(get, servicex):
199198
assert "Transform ID b8c508d0-ccf2-4deb-a1f7-65c839eebabf not found" == str(err.value)
200199

201200

201+
@pytest.mark.asyncio
202+
@patch('servicex.servicex_adapter.TransformStatus', side_effect=RuntimeError)
203+
@patch('servicex.servicex_adapter.RetryClient.get')
204+
async def test_get_tranform_status_retry_error(get,
205+
mock_transform_status,
206+
servicex,
207+
transform_status_response):
208+
with pytest.raises(RuntimeError) as err:
209+
get.return_value.__aenter__.return_value.json.return_value = transform_status_response['requests'][0] # NOQA: E501
210+
get.return_value.__aenter__.return_value.status = 200
211+
await servicex.get_transform_status("b8c508d0-ccf2-4deb-a1f7-65c839eebabf")
212+
assert "ServiceX WebAPI Error while getting transform status:" in str(err.value)
213+
214+
202215
@pytest.mark.asyncio
203216
async def test_get_authorization(servicex):
204217
servicex.token = "token"

0 commit comments

Comments
 (0)