def test_build_request(self, mock): ApiConfig.api_key = 'api_token' ApiConfig.api_version = '2015-04-09' params = {'per_page': 10, 'page': 2} headers = {'x-custom-header': 'header value'} Connection.request('get', 'databases', headers=headers, params=params) expected = call('get', 'https://www.quandl.com/api/v3/databases', headers={ 'x-custom-header': 'header value', 'x-api-token': 'api_token', 'accept': ('application/json, ' 'application/vnd.quandl+json;version=2015-04-09'), 'request-source': 'python', 'request-source-version': VERSION }, params={ 'per_page': 10, 'page': 2 }) print(mock.call_args) print(expected) self.assertEqual(mock.call_args, expected)
def test_build_request(self, mock): ApiConfig.api_key = 'api_token' ApiConfig.api_version = '2015-04-09' params = {'per_page': 10, 'page': 2} headers = {'x-custom-header': 'header value'} Connection.request('get', 'databases', headers=headers, params=params) expected = call('get', 'https://www.quandl.com/api/v3/databases', headers={'x-custom-header': 'header value', 'x-api-token': 'api_token', 'accept': ('application/json, ' 'application/vnd.quandl+json;version=2015-04-09'), 'request-source': 'python', 'request-source-version': '3.0.1'}, params={'per_page': 10, 'page': 2}) self.assertEqual(mock.call_args, expected)
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_quandl_exceptions(self): quandl_errors = [('QELx04', 429, LimitExceededError), ('QEMx01', 500, InternalServerError), ('QEAx01', 400, AuthenticationError), ('QEPx02', 403, ForbiddenError), ('QESx03', 422, InvalidRequestError), ('QECx05', 404, NotFoundError), ('QEXx01', 503, ServiceUnavailableError), ('QEZx02', 400, QuandlError)] httpretty.register_uri(httpretty.GET, "https://www.quandl.com/api/v3/databases", responses=[ httpretty.Response(body=json.dumps({ 'quandl_error': { 'code': x[0], 'message': 'something went wrong' } }), status=x[1]) for x in quandl_errors ]) for expected_error in quandl_errors: self.assertRaises(expected_error[2], lambda: Connection.request('get', 'databases'))
def test_parse_error(self): httpretty.register_uri(httpretty.GET, "https://www.quandl.com/api/v3/databases", body="not json", status=500) self.assertRaises(QuandlError, lambda: Connection.request('get', 'databases'))
def _request_file_info(self, file_or_folder_path, **options): url = self._download_request_path() code_name = self.code options['params']['qopts.export'] = 'true' request_type = RequestType.get_request_type(url, **options) updated_options = Util.convert_options(request_type=request_type, **options) r = Connection.request(request_type, url, **updated_options) response_data = r.json() file_info = response_data['datatable_bulk_download']['file'] status = file_info['status'] if status == 'fresh': file_link = file_info['link'] self._download_file_with_link(file_or_folder_path, file_link, code_name) return True else: return False
def test_parse_error(self, request_method): ApiConfig.retry_backoff_factor = 0 httpretty.register_uri(getattr(httpretty, request_method), "https://www.quandl.com/api/v3/databases", body="not json", status=500) self.assertRaises( QuandlError, lambda: Connection.request(request_method, 'databases'))
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)
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_non_quandl_error(self): httpretty.register_uri(httpretty.GET, "https://www.quandl.com/api/v3/databases", body=json.dumps( {'foobar': {'code': 'blah', 'message': 'something went wrong'}}), status=500) self.assertRaises( QuandlError, lambda: Connection.request('get', 'databases'))
def page(cls, datatable, **options): params = {'id': str(datatable.code)} path = Util.constructed_path(datatable.default_path(), params) r = Connection.request('get', path, **options) response_data = r.json() Util.convert_to_dates(response_data) resource = cls.create_datatable_list_from_response(response_data) return resource
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 all(cls, **options): if 'params' not in options: options['params'] = {} path = Util.constructed_path(cls.list_path(), options['params']) r = Connection.request('get', path, **options) response_data = r.json() Util.convert_to_dates(response_data) resource = cls.create_list_from_response(response_data) return resource
def test_non_quandl_error(self, request_method): ApiConfig.retry_backoff_factor = 0 httpretty.register_uri(getattr(httpretty, request_method), "https://www.quandl.com/api/v3/databases", body=json.dumps( {'foobar': {'code': 'blah', 'message': 'something went wrong'}}), status=500) self.assertRaises( QuandlError, lambda: Connection.request(request_method, 'databases'))
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)
def __get_raw_data__(self): if self._raw_data: return self._raw_data cls = self.__class__ params = {'id': str(self.code)} options = Util.merge_options('params', params, **self.options) path = Util.constructed_path(cls.get_path(), options['params']) r = Connection.request('get', path, **options) response_data = r.json() Util.convert_to_dates(response_data) self._raw_data = response_data[singularize(cls.lookup_key())] return self._raw_data
def bulk_download_to_file(self, file_or_folder_path, **options): if not isinstance(file_or_folder_path, str): raise QuandlError(Message.ERROR_FOLDER_ISSUE) path_url = self._bulk_download_path() options['stream'] = True r = Connection.request('get', path_url, **options) file_path = file_or_folder_path if os.path.isdir(file_or_folder_path): file_path = file_or_folder_path + '/' + os.path.basename(urlparse(r.url).path) with open(file_path, 'wb') as fd: for chunk in r.iter_content(self.BULK_CHUNK_SIZE): fd.write(chunk) return file_path
def bulk_download_to_file(self, file_or_folder_path, **options): if not isinstance(file_or_folder_path, str): raise QuandlError(Message.ERROR_FOLDER_ISSUE) path_url = self._bulk_download_path() options['stream'] = True r = Connection.request('get', path_url, **options) file_path = file_or_folder_path if os.path.isdir(file_or_folder_path): file_path = file_or_folder_path + '/' + os.path.basename( urlparse(r.url).path) with open(file_path, 'wb') as fd: for chunk in r.iter_content(self.BULK_CHUNK_SIZE): fd.write(chunk) return file_path
def test_quandl_exceptions(self): quandl_errors = [('QELx04', 429, LimitExceededError), ('QEMx01', 500, InternalServerError), ('QEAx01', 400, AuthenticationError), ('QEPx02', 403, ForbiddenError), ('QESx03', 422, InvalidRequestError), ('QECx05', 404, NotFoundError), ('QEXx01', 503, ServiceUnavailableError), ('QEZx02', 400, QuandlError)] httpretty.register_uri(httpretty.GET, "https://www.quandl.com/api/v3/databases", responses=[httpretty.Response(body=json.dumps( {'quandl_error': {'code': x[0], 'message': 'something went wrong'}}), status=x[1]) for x in quandl_errors] ) for expected_error in quandl_errors: self.assertRaises( expected_error[2], lambda: Connection.request('get', 'databases'))
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)
def test_parse_error(self): httpretty.register_uri(httpretty.GET, "https://www.quandl.com/api/v3/databases", body="not json", status=500) self.assertRaises( QuandlError, lambda: Connection.request('get', 'databases'))
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)