Skip to content

Commit

Permalink
only retry for certain status codes
Browse files Browse the repository at this point in the history
  • Loading branch information
oliver.gordon committed Apr 12, 2024
1 parent 5301c5c commit 0798242
Show file tree
Hide file tree
Showing 7 changed files with 75 additions and 32 deletions.
3 changes: 2 additions & 1 deletion pasqal_cloud/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -137,7 +137,8 @@ def create_batch(
stored in the serialized sequence
configuration: A dictionary with extra configuration for the emulators
that accept it.
wait: Whether to block on this statement until all the submitted jobs are terminated
wait: Whether to block on this statement until all the submitted jobs are
terminated
fetch_results (deprecated): Whether to wait for the batch to
be done and fetch results
Expand Down
4 changes: 2 additions & 2 deletions pasqal_cloud/batch.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@
BatchSetCompleteError,
BatchCancellingError,
JobCreationError,
JobFetchingError,
JobRetryError,
)
from pasqal_cloud.job import CreateJob, Job
Expand Down Expand Up @@ -170,7 +169,8 @@ def retry(self, job: Job, wait: bool = False) -> None:
raise JobRetryError from e

def declare_complete(self, wait: bool = False, fetch_results: bool = False) -> None:
"""Declare to PCS that the batch is complete and returns an updated batch instance.
"""Declare to PCS that the batch is complete and returns an updated
batch instance.
Args:
wait: Whether to wait for the batch to be done and fetch results.
Expand Down
32 changes: 17 additions & 15 deletions pasqal_cloud/client.py
Original file line number Diff line number Diff line change
Expand Up @@ -114,25 +114,27 @@ def _request(
while not successful_request and iteration <= HTTP_RETRIES:
# time = (interval seconds * exponent rule) ^ retries
delay = (1 * 2) ** iteration
rsp = requests.request(
method,
url,
json=payload,
timeout=TIMEOUT,
headers={"content-type": "application/json"},
auth=self.authenticator,
params=params,
)
try:
rsp = requests.request(
method,
url,
json=payload,
timeout=TIMEOUT,
headers={"content-type": "application/json"},
auth=self.authenticator,
params=params,
)
data: JSendPayload = rsp.json()
successful_request = True
rsp.raise_for_status()
except Exception as e:
if iteration == HTTP_RETRIES:
if (
rsp.status_code not in {408, 425, 429, 500, 502, 503, 504}
or iteration == HTTP_RETRIES
):
raise e
time.sleep(delay)
iteration += 1

return data
time.sleep(delay)
iteration += 1
return rsp.json()

def _send_batch(self, batch_data: Dict[str, Any]) -> Dict[str, Any]:
batch_data.update({"project_id": self.project_id})
Expand Down
8 changes: 4 additions & 4 deletions tests/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
from pasqal_cloud.endpoints import Endpoints
from tests.test_doubles.authentication import FakeAuth0AuthenticationSuccess
from requests import HTTPError
from typing import Generator, Any
from typing import Generator, Any, Optional

TEST_API_FIXTURES_PATH = "tests/fixtures/api"
RESULT_LINK_ENDPOINT = "http://result-link/"
Expand Down Expand Up @@ -61,7 +61,7 @@ def mock_response(request, context) -> Dict[str, Any]:

@pytest.fixture(scope="session")
@requests_mock.Mocker(kw="mock")
def request_mock(mock=None):
def request_mock(mock=None) -> Optional[Any]:
# Configure requests to use the local JSON files a response
mock.register_uri(
requests_mock.ANY,
Expand All @@ -73,7 +73,7 @@ def request_mock(mock=None):

@pytest.fixture(scope="session")
@requests_mock.Mocker(kw="mock")
def request_mock_exception(mock=None):
def request_mock_exception(mock=None) -> Optional[Any]:
mock.register_uri(
requests_mock.ANY,
requests_mock.ANY,
Expand Down Expand Up @@ -106,7 +106,7 @@ def batch_creation_error_data() -> Dict[str, Any]:
def request_mock_exception_batch_creation(
batch_creation_error_data,
mock=None,
):
) -> Optional[Any]:
# Configure requests to use the local JSON files a response
mock.register_uri(
requests_mock.ANY,
Expand Down
42 changes: 42 additions & 0 deletions tests/fixtures/test_payloads.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
from typing import Any, Dict


def successful_batch_payload_response() -> Dict[str, Any]:
return {
"code": 200,
"data": {
"complete": True,
"created_at": "2021-11-10T15:24:38.155824",
"device_type": "MOCK_DEVICE",
"project_id": "00000000-0000-0000-0000-000000000001",
"id": "00000000-0000-0000-0000-000000000001",
"priority": 10,
"sequence_builder": "pulser_test_sequence",
"status": "PENDING",
"updated_at": "2021-11-10T15:27:44.110274",
"user_id": "EQZj1ZQE",
"webhook": "10.0.1.5",
"configuration": {"dt": 10.0, "precision": "normal"},
"start_datetime": "2023-03-23T10:42:27.611384+00:00",
"end_datetime": "2023-03-23T10:42:27.611384+00:00",
"jobs": [
{
"batch_id": "00000000-0000-0000-0000-000000000001",
"id": "00000000-0000-0000-0000-000000022010",
"project_id": "00000000-0000-0000-0000-000000022111",
"runs": 50,
"status": "PENDING",
"created_at": "2021-11-10T15:27:06.698066",
"errors": [],
"updated_at": "2021-11-10T15:27:06.698066",
"variables": {
"Omega_max": 14.4,
"last_target": "q1",
"ts": [200, 500],
},
}
],
},
"message": "OK.",
"status": "success",
}
15 changes: 6 additions & 9 deletions tests/test_batch.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,12 +22,9 @@

from tests.test_doubles.authentication import FakeAuth0AuthenticationSuccess

from requests import HTTPError
from tests.conftest import mock_core_response
import requests_mock

from tests.conftest import mock_core_response
from unittest.mock import patch
from requests.models import Response


class TestBatch:
Expand Down Expand Up @@ -97,7 +94,7 @@ def test_batch_create_exception(
self, mock_request_exception: Generator[Any, Any, None]
):
"""
Assert the correct exception is raised when failign to create a batch
Assert the correct exception is raised when failing to create a batch
and that the correct methods and URLs are used.
"""
with pytest.raises(BatchCreationError):
Expand Down Expand Up @@ -173,7 +170,7 @@ def test_batch_add_jobs_failure(
):
"""
When trying to add jobs to a batch, we test that we catch
an exception JobCreationError while later validationg the HTTP method
an exception JobCreationError while later validating the HTTP method
and URL executed.
"""
with pytest.raises(JobCreationError):
Expand All @@ -192,6 +189,7 @@ def test_batch_add_jobs_and_wait_for_results(
mock_request: Generator[Any, Any, None],
load_mock_batch_json_response: Dict[str, Any],
):
mock_request.reset_mock()
# Override the batch id so that we load the right API fixtures
batch.id = "00000000-0000-0000-0000-000000000002"

Expand Down Expand Up @@ -222,7 +220,6 @@ def custom_get_batch_mock(request, _):
"GET", f"/core-fast/api/v1/batches/{batch.id}", json=custom_get_batch_mock
)

# Reset history so that we can count calls later
mock_request.register_uri(
"POST",
f"/core-fast/api/v1/batches/{batch.id}/jobs",
Expand Down Expand Up @@ -318,7 +315,7 @@ def test_cancel_batch_sdk_error(
self, mock_request_exception: Generator[Any, Any, None]
):
"""
Assert that a BatchCancellingError is raised appropriatrely for
Assert that a BatchCancellingError is raised appropriately for
failling requests when calling sdk.cancel_batch(...)
This test also assert the most recently used HTTP method and URL
Expand Down Expand Up @@ -555,7 +552,7 @@ def test_rebatch_success(
assert batch.parent_id == self.batch_id
assert batch.ordered_jobs[0].parent_id

def test_rebatch_sdk_error(self, mock_request_exception):
def test_rebatch_sdk_error(self, mock_request_exception: Generator[Any, Any, None]):
"""
As a user using the SDK with proper credentials,
if my request for rebatching returns a non 200 status code,
Expand Down
3 changes: 2 additions & 1 deletion tests/test_client.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
FakeAuth0AuthenticationFailure,
FakeAuth0AuthenticationSuccess,
)
from typing import Any, Generator


class TestSDKCommonAttributes:
Expand Down Expand Up @@ -165,7 +166,7 @@ class TestEnvSDK(TestSDKCommonAttributes):
("dev", "https://apis.dev.pasqal.cloud/core-fast"),
],
)
def test_select_env(self, env, core_endpoint_expected):
def test_select_env(self, env: str, core_endpoint_expected: str):
sdk = SDK(
project_id=self.project_id,
username=self.username,
Expand Down

0 comments on commit 0798242

Please sign in to comment.