This repository has been archived by the owner on Apr 30, 2022. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 339
Cp 7117/add retries to api calls #124
Merged
Merged
Changes from 10 commits
Commits
Show all changes
16 commits
Select commit
Hold shift + click to select a range
2617a3a
Automatically retry failed 5xx api calls
664ffd9
Add additional tests for retries
bb30e8a
Fix test failing on CI by using different way to compare json response
9b03b91
Increase test case speed by modifying backoff_factor to 0 for tests w…
4cad092
Allow test_retries tests to pass even when user has toggled use_retri…
6039064
Dont wait on retry-after headers to keep current functionality intact
7311822
Merge branch 'master' into CP-7117/add-retries-to-api-calls
jjmar b392dad
Add documentation for retry configuration
76b537a
Update failing datatable export test following merge
a8ce966
Reduce default retry settings so retries will be less aggressive
4d11b4b
Uncaptialize retry status codes config
9e786df
Allow retries on 429's
cebe9f4
Update readme retry examples to have default values
c4948ba
Bump version
81a699f
Update changelog
e68c90b
Remove debug statements
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,112 @@ | ||
import unittest | ||
import json | ||
|
||
from quandl.connection import Connection | ||
from quandl.api_config import ApiConfig | ||
from test.factories.datatable import DatatableFactory | ||
from test.helpers.httpretty_extension import httpretty | ||
from quandl.errors.quandl_error import InternalServerError | ||
|
||
|
||
class ModifyRetrySettingsTestCase(unittest.TestCase): | ||
|
||
def setUp(self): | ||
self.default_use_retries = ApiConfig.use_retries | ||
self.default_number_of_retries = ApiConfig.number_of_retries | ||
self.default_retry_backoff_factor = ApiConfig.retry_backoff_factor | ||
self.default_max_wait_between_retries = ApiConfig.max_wait_between_retries | ||
self.DEFAULT_RETRY_STATUS_CODES = ApiConfig.RETRY_STATUS_CODES | ||
|
||
def tearDown(self): | ||
ApiConfig.use_retries = self.default_use_retries | ||
ApiConfig.number_of_retries = self.default_number_of_retries | ||
ApiConfig.retry_backoff_factor = self.default_retry_backoff_factor | ||
ApiConfig.max_wait_between_retries = self.default_max_wait_between_retries | ||
ApiConfig.RETRY_STATUS_CODES = self.DEFAULT_RETRY_STATUS_CODES | ||
|
||
|
||
class TestRetries(ModifyRetrySettingsTestCase): | ||
|
||
def setUp(self): | ||
ApiConfig.use_retries = True | ||
super(TestRetries, self).setUp() | ||
|
||
@classmethod | ||
def setUpClass(cls): | ||
cls.datatable = {'datatable': DatatableFactory.build( | ||
vendor_code='ZACKS', | ||
datatable_code='FC')} | ||
|
||
cls.error_response = httpretty.Response( | ||
body=json.dumps({'quandl_error': {'code': 'QEMx01', | ||
'message': 'something went wrong'}}), | ||
status=500) | ||
cls.success_response = httpretty.Response(body=json.dumps(cls.datatable), status=200) | ||
|
||
def test_modifying_use_retries(self): | ||
ApiConfig.use_retries = False | ||
|
||
retries = Connection.get_session().get_adapter(ApiConfig.api_protocol).max_retries | ||
self.assertEqual(retries.total, 0) | ||
|
||
def test_modifying_number_of_retries(self): | ||
ApiConfig.number_of_retries = 3000 | ||
|
||
retries = Connection.get_session().get_adapter(ApiConfig.api_protocol).max_retries | ||
|
||
self.assertEqual(retries.total, ApiConfig.number_of_retries) | ||
self.assertEqual(retries.connect, ApiConfig.number_of_retries) | ||
self.assertEqual(retries.read, ApiConfig.number_of_retries) | ||
|
||
def test_modifying_retry_backoff_factor(self): | ||
ApiConfig.retry_backoff_factor = 3000 | ||
|
||
retries = Connection.get_session().get_adapter(ApiConfig.api_protocol).max_retries | ||
self.assertEqual(retries.backoff_factor, ApiConfig.retry_backoff_factor) | ||
|
||
def test_modifying_retry_status_codes(self): | ||
ApiConfig.RETRY_STATUS_CODES = [1, 2, 3] | ||
|
||
retries = Connection.get_session().get_adapter(ApiConfig.api_protocol).max_retries | ||
self.assertEqual(retries.status_forcelist, ApiConfig.RETRY_STATUS_CODES) | ||
|
||
def test_modifying_max_wait_between_retries(self): | ||
ApiConfig.max_wait_between_retries = 3000 | ||
|
||
retries = Connection.get_session().get_adapter(ApiConfig.api_protocol).max_retries | ||
self.assertEqual(retries.BACKOFF_MAX, ApiConfig.max_wait_between_retries) | ||
|
||
@httpretty.activate | ||
def test_correct_response_returned_if_retries_succeed(self): | ||
ApiConfig.number_of_retries = 3 | ||
ApiConfig.RETRY_STATUS_CODES = [self.error_response.status] | ||
|
||
mock_responses = [self.error_response] + [self.error_response] + [self.success_response] | ||
httpretty.register_uri(httpretty.GET, | ||
"https://www.quandl.com/api/v3/databases", | ||
responses=mock_responses) | ||
|
||
response = Connection.request('get', 'databases') | ||
self.assertEqual(response.json(), self.datatable) | ||
self.assertEqual(response.status_code, self.success_response.status) | ||
|
||
@httpretty.activate | ||
def test_correct_response_exception_raised_if_retries_fail(self): | ||
ApiConfig.number_of_retries = 2 | ||
ApiConfig.RETRY_STATUS_CODES = [self.error_response.status] | ||
mock_responses = [self.error_response] * 3 | ||
httpretty.register_uri(httpretty.GET, | ||
"https://www.quandl.com/api/v3/databases", | ||
responses=mock_responses) | ||
|
||
self.assertRaises(InternalServerError, Connection.request, 'get', 'databases') | ||
|
||
@httpretty.activate | ||
def test_correct_response_exception_raised_for_errors_not_in_retry_status_codes(self): | ||
ApiConfig.RETRY_STATUS_CODES = [] | ||
mock_responses = [self.error_response] | ||
httpretty.register_uri(httpretty.GET, | ||
"https://www.quandl.com/api/v3/databases", | ||
responses=mock_responses) | ||
|
||
self.assertRaises(InternalServerError, Connection.request, 'get', 'databases') |
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
How many columns does this table have. Looks like yours are 3 and the ones above are 4.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Theres 3 columns rendered. The top two rows specifying contents for a fourth column aren't being shown to the user - looks to be more of documentation for the dev. The rows I added already have a sufficient explanation so I wont be adding any comments to them