Skip to content
Snippets Groups Projects
Commit 769814ad authored by Manon Blanco's avatar Manon Blanco
Browse files

Do not create an Arkindex client on import

parent e6bc13a4
No related branches found
No related tags found
1 merge request!16Do not create an Arkindex client on import
Pipeline #173960 passed
arkindex-client==1.0.15
arkindex-client==1.0.16
lxml==5.2.1
PyYAML>=5.4.1
tenacity==8.2.3
......@@ -4,18 +4,14 @@ from urllib.parse import urlparse
import requests
import urllib3
from apistar.exceptions import ErrorResponse
from tenacity import (
before_sleep_log,
retry,
retry_if_exception,
retry_if_exception_type,
stop_after_attempt,
wait_exponential,
wait_fixed,
)
from arkindex import ArkindexClient, options_from_env
from arkindex import ArkindexClient
logger = logging.getLogger(__name__)
......@@ -31,9 +27,7 @@ def should_verify_cert(url: str) -> bool:
return not host.endswith("ark.localhost")
def _get_arkindex_client() -> ArkindexClient:
options = options_from_env()
def get_arkindex_client(**options) -> ArkindexClient:
# Skip SSL verification in Arkindex API client for local development hosts
verify = should_verify_cert(options.get("base_url"))
if not verify:
......@@ -43,40 +37,6 @@ def _get_arkindex_client() -> ArkindexClient:
return ArkindexClient(verify=verify, **options)
DEFAULT_CLIENT = _get_arkindex_client()
def _is_500_error(exc: Exception) -> bool:
"""
Check if an Arkindex API error is a 50x
This is used to retry most API calls implemented here
"""
if not isinstance(exc, ErrorResponse):
return False
return 500 <= exc.status_code < 600
@retry(
retry=retry_if_exception(_is_500_error),
wait=wait_exponential(multiplier=2, min=3),
reraise=True,
stop=stop_after_attempt(5),
before_sleep=before_sleep_log(logger, logging.INFO),
)
def retried_request(*args, **kwargs):
"""
Proxy all Arkindex API requests with a retry mechanism
in case of 50X errors
The same API call will be retried 5 times, with an exponential sleep time
going through 3, 4, 8 and 16 seconds of wait between call.
If the 5th call still gives a 50x, the exception is re-raised
and the caller should catch it
Log messages are displayed before sleeping (when at least one exception occurred)
"""
return DEFAULT_CLIENT.request(*args, **kwargs)
# Time to wait before retrying the IIIF image information fetching
HTTP_GET_RETRY_BACKOFF = 10
......
from unittest import TestCase
from unittest.mock import patch
import requests_mock
from apistar.exceptions import ErrorResponse
from teklia_toolbox.requests import retried_request
@requests_mock.Mocker()
@patch(
"teklia_toolbox.requests.retried_request.retry.wait",
0,
)
class TestRetriedRequest(TestCase):
def test_retried_request_only_500(self, mock):
mock.get("https://arkindex.teklia.com/api/v1/corpus/notfound/", status_code=404)
with self.assertRaises(ErrorResponse) as e:
retried_request("RetrieveCorpus", id="notfound")
self.assertEqual(e.exception.status_code, 404)
self.assertListEqual(
[(req.method, req.url) for req in mock.request_history],
[
("GET", "https://arkindex.teklia.com/api/v1/corpus/notfound/"),
],
)
def test_retried_request_5_attempts(self, mock):
mock.get("https://arkindex.teklia.com/api/v1/corpus/corpusid/", status_code=500)
with self.assertRaises(ErrorResponse) as e:
retried_request("RetrieveCorpus", id="corpusid")
self.assertEqual(e.exception.status_code, 500)
self.assertListEqual(
[(req.method, req.url) for req in mock.request_history],
[
("GET", "https://arkindex.teklia.com/api/v1/corpus/corpusid/"),
("GET", "https://arkindex.teklia.com/api/v1/corpus/corpusid/"),
("GET", "https://arkindex.teklia.com/api/v1/corpus/corpusid/"),
("GET", "https://arkindex.teklia.com/api/v1/corpus/corpusid/"),
("GET", "https://arkindex.teklia.com/api/v1/corpus/corpusid/"),
],
)
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment