Skip to content

Commit 6168651

Browse files
authored
Merge pull request #33 from NYPL/de-101-2/add-retry
DE-101 (Python Rewrite): Added retry functionality when fetching Avro schemas
2 parents 41ef2df + 2036f54 commit 6168651

3 files changed

Lines changed: 33 additions & 21 deletions

File tree

CHANGELOG.md

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,9 @@
11
# Changelog
2+
## v1.2.1 7/25/24
3+
- Add retry for fetching Avro schemas
4+
25
## v1.2.0 7/17/24
3-
- Generalized Avro functions and separated encoding/decoding behavior.
6+
- Generalized Avro functions and separated encoding/decoding behavior
47

58
## v1.1.6 7/12/24
69
- Add put functionality to Oauth2 Client

src/nypl_py_utils/classes/avro_client.py

Lines changed: 14 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,8 @@
55
from avro.io import BinaryDecoder, BinaryEncoder, DatumReader, DatumWriter
66
from io import BytesIO
77
from nypl_py_utils.functions.log_helper import create_log
8-
from requests.exceptions import JSONDecodeError, RequestException
8+
from requests.adapters import HTTPAdapter, Retry
9+
from requests.exceptions import JSONDecodeError
910

1011

1112
class AvroClient:
@@ -15,7 +16,13 @@ class AvroClient:
1516
"""
1617

1718
def __init__(self, platform_schema_url):
18-
self.logger = create_log("avro_encoder")
19+
self.logger = create_log("avro_client")
20+
retry_policy = Retry(total=3, backoff_factor=45,
21+
status_forcelist=[500, 502, 503, 504],
22+
allowed_methods=frozenset(['GET']))
23+
self.session = requests.Session()
24+
self.session.mount("https://",
25+
HTTPAdapter(max_retries=retry_policy))
1926
self.schema = avro.schema.parse(
2027
self.get_json_schema(platform_schema_url))
2128

@@ -27,9 +34,11 @@ def get_json_schema(self, platform_schema_url):
2734
self.logger.info(
2835
"Fetching Avro schema from {}".format(platform_schema_url))
2936
try:
30-
response = requests.get(platform_schema_url)
37+
38+
response = self.session.get(url=platform_schema_url,
39+
timeout=60)
3140
response.raise_for_status()
32-
except RequestException as e:
41+
except Exception as e:
3342
self.logger.error(
3443
"Failed to retrieve schema from {url}: {error}".format(
3544
url=platform_schema_url, error=e
@@ -39,7 +48,7 @@ def get_json_schema(self, platform_schema_url):
3948
"Failed to retrieve schema from {url}: {error}".format(
4049
url=platform_schema_url, error=e
4150
)
42-
) from None
51+
)
4352

4453
try:
4554
json_response = response.json()

tests/test_avro_client.py

Lines changed: 15 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -25,26 +25,26 @@ class TestAvroClient:
2525
@pytest.fixture
2626
def test_avro_encoder_instance(self, requests_mock):
2727
requests_mock.get(
28-
'https://test_schema_url', text=json.dumps(_TEST_SCHEMA))
29-
return AvroEncoder('https://test_schema_url')
28+
"https://test_schema_url", text=json.dumps(_TEST_SCHEMA))
29+
return AvroEncoder("https://test_schema_url")
3030

3131
@pytest.fixture
3232
def test_avro_decoder_instance(self, requests_mock):
3333
requests_mock.get(
34-
'https://test_schema_url', text=json.dumps(_TEST_SCHEMA))
35-
return AvroDecoder('https://test_schema_url')
36-
37-
def test_get_json_schema(self, test_avro_encoder_instance,
38-
test_avro_decoder_instance):
39-
assert test_avro_encoder_instance.schema == _TEST_SCHEMA['data'][
40-
'schema']
41-
assert test_avro_decoder_instance.schema == _TEST_SCHEMA['data'][
42-
'schema']
43-
44-
def test_request_error(self, requests_mock):
45-
requests_mock.get('https://test_schema_url', exc=ConnectTimeout)
34+
"https://test_schema_url", text=json.dumps(_TEST_SCHEMA))
35+
return AvroDecoder("https://test_schema_url")
36+
37+
def test_get_json_schema_success(self, test_avro_encoder_instance,
38+
test_avro_decoder_instance):
39+
assert test_avro_encoder_instance.schema == _TEST_SCHEMA["data"][
40+
"schema"]
41+
assert test_avro_decoder_instance.schema == _TEST_SCHEMA["data"][
42+
"schema"]
43+
44+
def test_get_json_schema_error(self, requests_mock):
45+
requests_mock.get("https://test_schema_url", exc=ConnectTimeout)
4646
with pytest.raises(AvroClientError):
47-
AvroEncoder('https://test_schema_url')
47+
AvroEncoder("https://test_schema_url")
4848

4949
def test_bad_json_error(self, requests_mock):
5050
requests_mock.get(

0 commit comments

Comments
 (0)