Hello community, here is the log from the commit of package python-Quandl for openSUSE:Factory checked in at 2018-12-14 20:53:18 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/python-Quandl (Old) and /work/SRC/openSUSE:Factory/.python-Quandl.new.28833 (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "python-Quandl" Fri Dec 14 20:53:18 2018 rev:8 rq:653691 version:3.4.4 Changes: -------- --- /work/SRC/openSUSE:Factory/python-Quandl/python-Quandl.changes 2018-09-03 10:36:39.484910582 +0200 +++ /work/SRC/openSUSE:Factory/.python-Quandl.new.28833/python-Quandl.changes 2018-12-14 20:56:08.472819337 +0100 @@ -1,0 +2,9 @@ +Tue Nov 13 19:43:00 UTC 2018 - Sebastian Wagner <sebix+novell....@sebix.at> + +- remove remove_unittest2.patch, merged upstream. +- update to version 3.4.4: + * Add functionality to automatically retry failed API calls https://github.com/quandl/quandl-python/pull/124 +- update to version 3.4.3: + * Allow for exporting of datatables https://github.com/quandl/quandl-python/pull/120 + +------------------------------------------------------------------- Old: ---- Quandl-3.4.2.tar.gz remove_unittest2.patch New: ---- Quandl-3.4.4.tar.gz ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ python-Quandl.spec ++++++ --- /var/tmp/diff_new_pack.qouICN/_old 2018-12-14 20:56:08.940818756 +0100 +++ /var/tmp/diff_new_pack.qouICN/_new 2018-12-14 20:56:08.944818751 +0100 @@ -12,22 +12,19 @@ # license that conforms to the Open Source Definition (Version 1.9) # published by the Open Source Initiative. -# Please submit bugfixes or comments via http://bugs.opensuse.org/ +# Please submit bugfixes or comments via https://bugs.opensuse.org/ # %{?!python_module:%define python_module() python-%{**} python3-%{**}} Name: python-Quandl -Version: 3.4.2 +Version: 3.4.4 Release: 0 Summary: Package for quandl API access License: MIT Group: Development/Languages/Python URL: https://github.com/quandl/quandl-python Source: https://files.pythonhosted.org/packages/source/Q/Quandl/Quandl-%{version}.tar.gz -# PATCH-FIX-UPSTREAM mc...@suse.cz -# https://github.com/quandl/quandl-python/issues/113 -Patch0: remove_unittest2.patch BuildRequires: %{python_module devel} BuildRequires: %{python_module setuptools} BuildRequires: fdupes @@ -67,7 +64,6 @@ %prep %setup -q -n Quandl-%{version} -%autopatch -p1 %build %python_build ++++++ Quandl-3.4.2.tar.gz -> Quandl-3.4.4.tar.gz ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Quandl-3.4.2/CHANGELOG.md new/Quandl-3.4.4/CHANGELOG.md --- old/Quandl-3.4.2/CHANGELOG.md 2018-08-21 17:53:49.000000000 +0200 +++ new/Quandl-3.4.4/CHANGELOG.md 2018-10-24 21:24:58.000000000 +0200 @@ -1,3 +1,14 @@ +### unreleased +* Remove dependency on unittest2, use unittest instead (#113) + +### 3.4.4 - 2018-10-24 + +* Add functionality to automatically retry failed API calls https://github.com/quandl/quandl-python/pull/124 + +### 3.4.3 - 2018-10-19 + +* Allow for exporting of datatables https://github.com/quandl/quandl-python/pull/120 + ### 3.4.2 - 2018-08-21 * Fix typos in our warning messages https://github.com/quandl/quandl-python/pull/114 diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Quandl-3.4.2/FOR_ANALYSTS.md new/Quandl-3.4.4/FOR_ANALYSTS.md --- old/Quandl-3.4.2/FOR_ANALYSTS.md 2017-03-07 17:12:24.000000000 +0100 +++ new/Quandl-3.4.4/FOR_ANALYSTS.md 2018-10-24 21:24:58.000000000 +0200 @@ -135,6 +135,33 @@ In this query we are asking for more pages of data, `ticker` values of either `AAPL` or `MSFT` and a `per_end_date` that is greater than or equal to `2015-01-01`. We are also filtering the returned columns on `ticker`, `per_end_date` and `comp_name` rather than all available columns. The output format is `pandas`. +Download table data as a zip file. You can download all the table data in a data table in a single call. The following will download the entire F1 table data as a zip file to your current working directory: + +```python +import quandl +data = quandl.export_table('MER/F1') +``` + +You can also specify where to download the zip file: + +```python +import quandl +data = quandl.export_table('MER/F1', filename='/my/path/db.zip') +``` + +Note that if you are downloading the whole table, it will take longer to generate the zip file. + +You can also specify what data you want to download with filters and parameters.(`cursor_id` and `paginate` are not supported for exporting table zip file): + +```python +import quandl +quandl.export_table('ZACKS/FC', ticker=['AAPL', 'MSFT'], per_end_date={'gte': '2015-01-01'}, qopts={'columns':['ticker', 'per_end_date']}) +``` + +After the download is finished, the filename of the downloaded zip file will be printed. + +Sometimes it takes a while to generate the zip file, you'll get a message while the file is being generated. Once the file is generated, it will start the download of the zip file. + #### Available parameters: The following additional parameters can be specified for a datatable call: diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Quandl-3.4.2/FOR_DEVELOPERS.md new/Quandl-3.4.4/FOR_DEVELOPERS.md --- old/Quandl-3.4.2/FOR_DEVELOPERS.md 2017-03-07 17:12:24.000000000 +0100 +++ new/Quandl-3.4.4/FOR_DEVELOPERS.md 2018-10-24 21:24:58.000000000 +0200 @@ -72,6 +72,34 @@ break ``` +Download table data as a zip file. You can download all the table data in a data table in a single call. The following will download the entire F1 table data as a zip file to your current working directory: + +```python +import quandl +data = quandl.export_table('MER/F1') +``` + +You can also specify where to download the zip file: + +```python +import quandl +data = quandl.export_table('MER/F1', filename='/my/path/db.zip') +``` + +Note that if you are downloading the whole table, it will take longer to generate the zip file. + +You can also specify what data you want to download with filters and parameters.(`cursor_id` and `paginate` are not supported for exporting table zip file): + +```python +import quandl +quandl.export_table('ZACKS/FC', ticker=['AAPL', 'MSFT'], per_end_date={'gte': '2015-01-01'}, qopts={'columns':['ticker', 'per_end_date']}) +``` + +After the download is finished, the filename of the downloaded zip file will be printed. + +Sometimes it takes a while to generate the zip file, you'll get a message while the file is being generated. Once the file is generated, it will start the download of the zip file. + + ### Download Entire Database (Bulk Download) To get the url for downloading all dataset data in a database: diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Quandl-3.4.2/PKG-INFO new/Quandl-3.4.4/PKG-INFO --- old/Quandl-3.4.2/PKG-INFO 2018-08-21 17:54:21.000000000 +0200 +++ new/Quandl-3.4.4/PKG-INFO 2018-10-24 21:27:57.000000000 +0200 @@ -1,6 +1,6 @@ Metadata-Version: 1.2 Name: Quandl -Version: 3.4.2 +Version: 3.4.4 Summary: Package for quandl API access Home-page: https://github.com/quandl/quandl-python Author: Quandl diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Quandl-3.4.2/Quandl.egg-info/PKG-INFO new/Quandl-3.4.4/Quandl.egg-info/PKG-INFO --- old/Quandl-3.4.2/Quandl.egg-info/PKG-INFO 2018-08-21 17:54:21.000000000 +0200 +++ new/Quandl-3.4.4/Quandl.egg-info/PKG-INFO 2018-10-24 21:27:56.000000000 +0200 @@ -1,6 +1,6 @@ Metadata-Version: 1.2 Name: Quandl -Version: 3.4.2 +Version: 3.4.4 Summary: Package for quandl API access Home-page: https://github.com/quandl/quandl-python Author: Quandl diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Quandl-3.4.2/Quandl.egg-info/SOURCES.txt new/Quandl-3.4.4/Quandl.egg-info/SOURCES.txt --- old/Quandl-3.4.2/Quandl.egg-info/SOURCES.txt 2018-08-21 17:54:21.000000000 +0200 +++ new/Quandl-3.4.4/Quandl.egg-info/SOURCES.txt 2018-10-24 21:27:56.000000000 +0200 @@ -18,6 +18,7 @@ quandl/api_config.py quandl/bulkdownload.py quandl/connection.py +quandl/export_table.py quandl/get.py quandl/get_table.py quandl/message.py @@ -45,103 +46,54 @@ quandl/utils/__init__.py quandl/utils/api_key_util.py test/__init__.py -test/__init__.pyc test/test_connection.py -test/test_connection.pyc test/test_data.py -test/test_data.pyc test/test_database.py -test/test_database.pyc test/test_dataset.py -test/test_dataset.pyc test/test_datatable.py test/test_datatable_data.py test/test_get.py test/test_get_table.py test/test_merged_dataset.py -test/test_merged_dataset.pyc test/test_model.py -test/test_model.pyc +test/test_retries.py test/test_util.py -test/test_util.pyc -test/__pycache__/__init__.cpython-34.pyc -test/__pycache__/__init__.cpython-35.pyc -test/__pycache__/__init__.cpython-36.pyc -test/__pycache__/test_connection.cpython-34.pyc -test/__pycache__/test_connection.cpython-35.pyc -test/__pycache__/test_connection.cpython-36.pyc -test/__pycache__/test_data.cpython-34.pyc -test/__pycache__/test_data.cpython-35.pyc -test/__pycache__/test_data.cpython-36.pyc -test/__pycache__/test_database.cpython-34.pyc -test/__pycache__/test_database.cpython-35.pyc -test/__pycache__/test_database.cpython-36.pyc -test/__pycache__/test_dataset.cpython-34.pyc -test/__pycache__/test_dataset.cpython-35.pyc -test/__pycache__/test_dataset.cpython-36.pyc -test/__pycache__/test_datatable.cpython-35.pyc -test/__pycache__/test_datatable.cpython-36.pyc -test/__pycache__/test_datatable_data.cpython-35.pyc -test/__pycache__/test_datatable_data.cpython-36.pyc -test/__pycache__/test_get.cpython-35.pyc -test/__pycache__/test_get.cpython-36.pyc -test/__pycache__/test_get_table.cpython-35.pyc -test/__pycache__/test_get_table.cpython-36.pyc -test/__pycache__/test_merged_dataset.cpython-34.pyc -test/__pycache__/test_merged_dataset.cpython-35.pyc -test/__pycache__/test_merged_dataset.cpython-36.pyc -test/__pycache__/test_model.cpython-34.pyc -test/__pycache__/test_model.cpython-35.pyc -test/__pycache__/test_model.cpython-36.pyc -test/__pycache__/test_util.cpython-34.pyc -test/__pycache__/test_util.cpython-35.pyc -test/__pycache__/test_util.cpython-36.pyc +test/__pycache__/__init__.cpython-37.pyc +test/__pycache__/test_connection.cpython-37.pyc +test/__pycache__/test_data.cpython-37.pyc +test/__pycache__/test_database.cpython-37.pyc +test/__pycache__/test_dataset.cpython-37.pyc +test/__pycache__/test_datatable.cpython-37.pyc +test/__pycache__/test_datatable_data.cpython-37.pyc +test/__pycache__/test_get.cpython-37.pyc +test/__pycache__/test_get_table.cpython-37.pyc +test/__pycache__/test_merged_dataset.cpython-37.pyc +test/__pycache__/test_model.cpython-37.pyc +test/__pycache__/test_retries.cpython-37.pyc +test/__pycache__/test_util.cpython-37.pyc test/factories/__init__.py -test/factories/__init__.pyc test/factories/database.py -test/factories/database.pyc test/factories/dataset.py -test/factories/dataset.pyc test/factories/dataset_data.py -test/factories/dataset_data.pyc test/factories/datatable.py test/factories/datatable_data.py test/factories/datatable_meta.py test/factories/meta.py -test/factories/meta.pyc -test/factories/__pycache__/__init__.cpython-34.pyc -test/factories/__pycache__/__init__.cpython-35.pyc -test/factories/__pycache__/__init__.cpython-36.pyc -test/factories/__pycache__/database.cpython-34.pyc -test/factories/__pycache__/database.cpython-35.pyc -test/factories/__pycache__/database.cpython-36.pyc -test/factories/__pycache__/dataset.cpython-34.pyc -test/factories/__pycache__/dataset.cpython-35.pyc -test/factories/__pycache__/dataset.cpython-36.pyc -test/factories/__pycache__/dataset_data.cpython-34.pyc -test/factories/__pycache__/dataset_data.cpython-35.pyc -test/factories/__pycache__/dataset_data.cpython-36.pyc -test/factories/__pycache__/datatable.cpython-35.pyc -test/factories/__pycache__/datatable.cpython-36.pyc -test/factories/__pycache__/datatable_data.cpython-35.pyc -test/factories/__pycache__/datatable_data.cpython-36.pyc -test/factories/__pycache__/datatable_meta.cpython-35.pyc -test/factories/__pycache__/datatable_meta.cpython-36.pyc -test/factories/__pycache__/meta.cpython-34.pyc -test/factories/__pycache__/meta.cpython-35.pyc -test/factories/__pycache__/meta.cpython-36.pyc +test/factories/__pycache__/__init__.cpython-37.pyc +test/factories/__pycache__/database.cpython-37.pyc +test/factories/__pycache__/dataset.cpython-37.pyc +test/factories/__pycache__/dataset_data.cpython-37.pyc +test/factories/__pycache__/datatable.cpython-37.pyc +test/factories/__pycache__/datatable_data.cpython-37.pyc +test/factories/__pycache__/datatable_meta.cpython-37.pyc +test/factories/__pycache__/meta.cpython-37.pyc test/helpers/__init__.py test/helpers/httpretty_extension.py test/helpers/merged_datasets_helper.py test/helpers/my_httpretty.py -test/helpers/__pycache__/__init__.cpython-35.pyc -test/helpers/__pycache__/__init__.cpython-36.pyc -test/helpers/__pycache__/httpretty_extension.cpython-35.pyc -test/helpers/__pycache__/httpretty_extension.cpython-36.pyc -test/helpers/__pycache__/merged_datasets_helper.cpython-35.pyc -test/helpers/__pycache__/merged_datasets_helper.cpython-36.pyc -test/helpers/__pycache__/my_httpretty.cpython-35.pyc -test/helpers/__pycache__/my_httpretty.cpython-36.pyc +test/helpers/__pycache__/__init__.cpython-37.pyc +test/helpers/__pycache__/httpretty_extension.cpython-37.pyc +test/helpers/__pycache__/merged_datasets_helper.cpython-37.pyc +test/helpers/__pycache__/my_httpretty.cpython-37.pyc test/test_operations/__init__.py -test/test_operations/__pycache__/__init__.cpython-35.pyc -test/test_operations/__pycache__/__init__.cpython-36.pyc \ No newline at end of file +test/test_operations/__pycache__/__init__.cpython-37.pyc \ No newline at end of file diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Quandl-3.4.2/README.md new/Quandl-3.4.4/README.md --- old/Quandl-3.4.2/README.md 2018-06-13 17:51:12.000000000 +0200 +++ new/Quandl-3.4.4/README.md 2018-10-24 21:24:58.000000000 +0200 @@ -28,7 +28,12 @@ |---|---|---| | api_key | Your access key | `tEsTkEy123456789` | Used to identify who you are and provide full access. | | api_version | The API version you wish to use | 2015-04-09 | Can be used to test your code against the latest version without committing to it. | - +| use_retries | Whether API calls which return statuses in `retry_status_codes` should be automatically retried | True +| number_of_retries | Maximum number of retries that should be attempted. Only used if `use_retries` is True | 5 +| max_wait_between_retries | Maximum amount of time in seconds that should be waited before attempting a retry. Only used if `use_retries` is True | 8 +| retry_backoff_factor | Determines the amount of time in seconds that should be waited before attempting another retry. Note that this factor is exponential so a `retry_backoff_factor` of 0.5 will cause waits of [0.5, 1, 2, 4, etc]. Only used if `use_retries` is True | 0.5 +| retry_status_codes | A list of HTTP status codes which will trigger a retry to occur. Only used if `use_retries` is True| [429, 500, 501, 502, 503, 504, 505, 506, 507, 508, 509, 510, 511] + ```python import quandl quandl.ApiConfig.api_key = 'tEsTkEy123456789' @@ -37,6 +42,34 @@ `quandl.ApiConfig.api_version` is optional however it is strongly recommended to avoid issues with rate-limiting. For premium databases, datasets and datatables `quandl.ApiConfig.api_key` will need to be set to identify you to our API. Please see [API Documentation](https://www.quandl.com/docs/api) for more detail. + +### Local API Key file +Save local key to `$HOME/.quandl_apikey` file +``` +import quandl +quandl.save_key("supersecret") +print(quandl.ApiConfig.api_key) +``` + +Load the API Key without exposing the key in the script or notebook +``` +import quandl +quandl.read_key() +print(quandl.ApiConfig.api_key) +``` + +Set a custom location for the API key file, e.g. store the externally outside a docker container +``` +import quandl +quandl.save_key("ourcorporateapikey", filename="/srv/data/somecontainer/.corporatequandlapikey") +``` +and call within the docker container with mount point at `/data` +``` +import quandl +quandl.read_key(filepath="/data/.corporatequandlapikey") +``` + + ## Retrieving Data There are two methods for retrieving data in Python: the Quick method and the Detailed method. The latter is more suitable to application programming. Both methods work with Quandl's two types of data structures: time-series (dataset) data and non-time series (datatable). @@ -89,6 +122,26 @@ `python setup.py install` 4. Run the following command to test the plugin in all versions of python we support: `tox` + +Once you have all required packages installed, you can run tests locally with: + +Running all tests locally + +```python +python -W always setup.py -q test +``` + +Running an individual test + +```python +python -m unittest test.[test file name].[class name].[individual test name]` +``` + +Example: + +```python +python -m unittest -v test.test_datatable.ExportDataTableTest.test_download_get_file_info +``` ## Recommended Usage @@ -97,6 +150,10 @@ See [this link](http://pandas.pydata.org/pandas-docs/dev/timeseries.html) for more information about timeseries in pandas. +## Release the Package + +To release the package, you can follow the instructions on this [page](https://packaging.python.org/tutorials/packaging-projects/#packaging-python-projects) + ## Additional Links * [Quandl](https://www.quandl.com) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Quandl-3.4.2/quandl/__init__.py new/Quandl-3.4.4/quandl/__init__.py --- old/Quandl-3.4.2/quandl/__init__.py 2016-05-18 19:52:25.000000000 +0200 +++ new/Quandl-3.4.4/quandl/__init__.py 2018-10-24 21:24:58.000000000 +0200 @@ -1,6 +1,6 @@ # -*- coding: utf-8 -*- -from .api_config import ApiConfig +from .api_config import ApiConfig, save_key, read_key from .errors.quandl_error import * @@ -11,4 +11,5 @@ from .model.merged_dataset import MergedDataset from .get import get from .bulkdownload import bulkdownload +from .export_table import export_table from .get_table import get_table \ No newline at end of file diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Quandl-3.4.2/quandl/api_config.py new/Quandl-3.4.4/quandl/api_config.py --- old/Quandl-3.4.2/quandl/api_config.py 2016-05-18 19:52:25.000000000 +0200 +++ new/Quandl-3.4.4/quandl/api_config.py 2018-10-24 21:24:58.000000000 +0200 @@ -1,5 +1,41 @@ class ApiConfig: api_key = None - api_base = 'https://www.quandl.com/api/v3' + api_protocol = 'https://' + api_base = '{}www.quandl.com/api/v3'.format(api_protocol) api_version = None page_limit = 100 + + use_retries = True + number_of_retries = 5 + retry_backoff_factor = 0.5 + max_wait_between_retries = 8 + retry_status_codes = [429] + list(range(500, 512)) + + +def save_key(apikey, filename=None): + if filename is None: + import pathlib + filename = str(pathlib.Path.home()) + "/.quandl_apikey" + + fileptr = open(filename, 'w') + fileptr.write(apikey) + fileptr.close() + ApiConfig.api_key = apikey + + +def read_key(filename=None): + if filename is None: + import pathlib + filename = str(pathlib.Path.home()) + "/.quandl_apikey" + + try: + fileptr = open(filename, 'r') + apikey = fileptr.read() + fileptr.close() + + if apikey: + ApiConfig.api_key = apikey + else: + raise Exception("File '{:s}' is empty.".format(filename)) + except ValueError: + raise Exception("File '{:s}' not found.".format(filename)) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Quandl-3.4.2/quandl/connection.py new/Quandl-3.4.4/quandl/connection.py --- old/Quandl-3.4.2/quandl/connection.py 2017-03-07 17:12:24.000000000 +0100 +++ new/Quandl-3.4.4/quandl/connection.py 2018-10-24 21:24:58.000000000 +0200 @@ -1,6 +1,8 @@ import re import requests +from urllib3.util.retry import Retry +from requests.adapters import HTTPAdapter from .util import Util from .version import VERSION @@ -37,9 +39,10 @@ @classmethod def execute_request(cls, http_verb, url, **options): + session = cls.get_session() + try: - func = getattr(requests, http_verb) - response = func(url, **options) + response = session.request(method=http_verb, url=url, **options) if response.status_code < 200 or response.status_code >= 300: cls.handle_api_error(response) else: @@ -50,6 +53,29 @@ raise e @classmethod + def get_session(cls): + session = requests.Session() + adapter = HTTPAdapter(max_retries=cls.get_retries()) + session.mount(ApiConfig.api_protocol, adapter) + + return session + + @classmethod + def get_retries(cls): + if not ApiConfig.use_retries: + return Retry(total=0) + + Retry.BACKOFF_MAX = ApiConfig.max_wait_between_retries + retries = Retry(total=ApiConfig.number_of_retries, + connect=ApiConfig.number_of_retries, + read=ApiConfig.number_of_retries, + status_forcelist=ApiConfig.retry_status_codes, + backoff_factor=ApiConfig.retry_backoff_factor, + raise_on_status=False) + + return retries + + @classmethod def parse(cls, response): try: return response.json() diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Quandl-3.4.2/quandl/export_table.py new/Quandl-3.4.4/quandl/export_table.py --- old/Quandl-3.4.2/quandl/export_table.py 1970-01-01 01:00:00.000000000 +0100 +++ new/Quandl-3.4.4/quandl/export_table.py 2018-10-24 21:24:58.000000000 +0200 @@ -0,0 +1,22 @@ +from quandl.errors.quandl_error import InvalidRequestError +from .utils.api_key_util import ApiKeyUtil +from .model.datatable import Datatable +from .message import Message + + +def export_table(datatable_code, **kwargs): + """Downloads an entire table as a zip file. + :param str datatable_code: The datatable code to download, such as MER/F1 + :param str filename: The filename for the download. \ + If not specified, will download to the current working directory + :param str api_key: Most databases require api_key for bulk download + """ + + # discourage users from using authtoken + if 'authtoken' in kwargs: + raise InvalidRequestError(Message.ERROR_AUTHTOKEN_NOT_SUPPORTED) + + ApiKeyUtil.init_api_key_from_args(kwargs) + + filename = kwargs.pop('filename', '.') + return Datatable(datatable_code).download_file(filename, **kwargs) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Quandl-3.4.2/quandl/message.py new/Quandl-3.4.4/quandl/message.py --- old/Quandl-3.4.2/quandl/message.py 2018-08-21 17:53:49.000000000 +0200 +++ new/Quandl-3.4.4/quandl/message.py 2018-10-24 21:24:58.000000000 +0200 @@ -31,3 +31,4 @@ quandl.get_table() call. For more information see our documentation: \ https://github.com/quandl/quandl-python/blob/master/FOR_ANALYSTS.md#things-to-note' WARN_PARAMS_NOT_SUPPORTED = '%s will no longer supported. Please use %s instead' + LONG_GENERATION_TIME = 'We are generating the zip file now, please wait...' diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Quandl-3.4.2/quandl/model/datatable.py new/Quandl-3.4.4/quandl/model/datatable.py --- old/Quandl-3.4.2/quandl/model/datatable.py 2016-05-18 19:52:25.000000000 +0200 +++ new/Quandl-3.4.4/quandl/model/datatable.py 2018-10-24 21:24:58.000000000 +0200 @@ -1,11 +1,25 @@ +try: + from urllib.request import urlopen +except ImportError: + from urllib import urlopen + +from time import sleep +import os + +from quandl.connection import Connection +from quandl.util import Util +from quandl.errors.quandl_error import QuandlError from quandl.operations.get import GetOperation from quandl.operations.list import ListOperation -from quandl.util import Util + from .model_base import ModelBase +from quandl.message import Message from .data import Data class Datatable(GetOperation, ListOperation, ModelBase): + BULK_CHUNK_SIZE = 16 * 1024 + WAIT_GENERATION_INTERVAL = 30 @classmethod def get_path(cls): @@ -14,3 +28,60 @@ def data(self, **options): updated_options = Util.convert_options(**options) return Data.page(self, **updated_options) + + def download_file(self, file_or_folder_path, **options): + if not isinstance(file_or_folder_path, str): + raise QuandlError(Message.ERROR_FOLDER_ISSUE) + + file_is_ready = False + + while not file_is_ready: + file_is_ready = self._request_file_info(file_or_folder_path, **options) + if not file_is_ready: + print(Message.LONG_GENERATION_TIME) + sleep(self.WAIT_GENERATION_INTERVAL) + + def _request_file_info(self, file_or_folder_path, **options): + url = self._download_request_path() + updated_options = Util.convert_options(params=options) + code_name = self.code + + updated_options['params']['qopts.export'] = 'true' + + r = Connection.request('get', 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 _download_file_with_link(self, file_or_folder_path, file_link, code_name): + file_path = file_or_folder_path + if os.path.isdir(file_or_folder_path): + file_path = os.path.join(file_or_folder_path, + '{}.{}'.format(code_name.replace('/', '_'), 'zip')) + + res = urlopen(file_link) + + with open(file_path, 'wb') as fd: + while True: + chunk = res.read(self.BULK_CHUNK_SIZE) + if not chunk: + break + fd.write(chunk) + + print(file_path) + + def _download_request_path(self): + url = self.default_path() + url = Util.constructed_path(url, {'id': self.code}) + url += '.json' + return url diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Quandl-3.4.2/quandl/version.py new/Quandl-3.4.4/quandl/version.py --- old/Quandl-3.4.2/quandl/version.py 2018-08-21 17:53:49.000000000 +0200 +++ new/Quandl-3.4.4/quandl/version.py 2018-10-24 21:24:58.000000000 +0200 @@ -1 +1 @@ -VERSION = '3.4.2' +VERSION = '3.4.4' diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Quandl-3.4.2/setup.py new/Quandl-3.4.4/setup.py --- old/Quandl-3.4.2/setup.py 2018-06-13 17:51:12.000000000 +0200 +++ new/Quandl-3.4.4/setup.py 2018-10-12 17:12:24.000000000 +0200 @@ -56,7 +56,6 @@ license='MIT', install_requires=install_requires, tests_require=[ - 'unittest2', 'flake8', 'nose', 'httpretty', Binary files old/Quandl-3.4.2/test/__init__.pyc and new/Quandl-3.4.4/test/__init__.pyc differ Binary files old/Quandl-3.4.2/test/__pycache__/__init__.cpython-34.pyc and new/Quandl-3.4.4/test/__pycache__/__init__.cpython-34.pyc differ Binary files old/Quandl-3.4.2/test/__pycache__/__init__.cpython-35.pyc and new/Quandl-3.4.4/test/__pycache__/__init__.cpython-35.pyc differ Binary files old/Quandl-3.4.2/test/__pycache__/__init__.cpython-36.pyc and new/Quandl-3.4.4/test/__pycache__/__init__.cpython-36.pyc differ Binary files old/Quandl-3.4.2/test/__pycache__/__init__.cpython-37.pyc and new/Quandl-3.4.4/test/__pycache__/__init__.cpython-37.pyc differ Binary files old/Quandl-3.4.2/test/__pycache__/test_connection.cpython-34.pyc and new/Quandl-3.4.4/test/__pycache__/test_connection.cpython-34.pyc differ Binary files old/Quandl-3.4.2/test/__pycache__/test_connection.cpython-35.pyc and new/Quandl-3.4.4/test/__pycache__/test_connection.cpython-35.pyc differ Binary files old/Quandl-3.4.2/test/__pycache__/test_connection.cpython-36.pyc and new/Quandl-3.4.4/test/__pycache__/test_connection.cpython-36.pyc differ Binary files old/Quandl-3.4.2/test/__pycache__/test_connection.cpython-37.pyc and new/Quandl-3.4.4/test/__pycache__/test_connection.cpython-37.pyc differ Binary files old/Quandl-3.4.2/test/__pycache__/test_data.cpython-34.pyc and new/Quandl-3.4.4/test/__pycache__/test_data.cpython-34.pyc differ Binary files old/Quandl-3.4.2/test/__pycache__/test_data.cpython-35.pyc and new/Quandl-3.4.4/test/__pycache__/test_data.cpython-35.pyc differ Binary files old/Quandl-3.4.2/test/__pycache__/test_data.cpython-36.pyc and new/Quandl-3.4.4/test/__pycache__/test_data.cpython-36.pyc differ Binary files old/Quandl-3.4.2/test/__pycache__/test_data.cpython-37.pyc and new/Quandl-3.4.4/test/__pycache__/test_data.cpython-37.pyc differ Binary files old/Quandl-3.4.2/test/__pycache__/test_database.cpython-34.pyc and new/Quandl-3.4.4/test/__pycache__/test_database.cpython-34.pyc differ Binary files old/Quandl-3.4.2/test/__pycache__/test_database.cpython-35.pyc and new/Quandl-3.4.4/test/__pycache__/test_database.cpython-35.pyc differ Binary files old/Quandl-3.4.2/test/__pycache__/test_database.cpython-36.pyc and new/Quandl-3.4.4/test/__pycache__/test_database.cpython-36.pyc differ Binary files old/Quandl-3.4.2/test/__pycache__/test_database.cpython-37.pyc and new/Quandl-3.4.4/test/__pycache__/test_database.cpython-37.pyc differ Binary files old/Quandl-3.4.2/test/__pycache__/test_dataset.cpython-34.pyc and new/Quandl-3.4.4/test/__pycache__/test_dataset.cpython-34.pyc differ Binary files old/Quandl-3.4.2/test/__pycache__/test_dataset.cpython-35.pyc and new/Quandl-3.4.4/test/__pycache__/test_dataset.cpython-35.pyc differ Binary files old/Quandl-3.4.2/test/__pycache__/test_dataset.cpython-36.pyc and new/Quandl-3.4.4/test/__pycache__/test_dataset.cpython-36.pyc differ Binary files old/Quandl-3.4.2/test/__pycache__/test_dataset.cpython-37.pyc and new/Quandl-3.4.4/test/__pycache__/test_dataset.cpython-37.pyc differ Binary files old/Quandl-3.4.2/test/__pycache__/test_datatable.cpython-35.pyc and new/Quandl-3.4.4/test/__pycache__/test_datatable.cpython-35.pyc differ Binary files old/Quandl-3.4.2/test/__pycache__/test_datatable.cpython-36.pyc and new/Quandl-3.4.4/test/__pycache__/test_datatable.cpython-36.pyc differ Binary files old/Quandl-3.4.2/test/__pycache__/test_datatable.cpython-37.pyc and new/Quandl-3.4.4/test/__pycache__/test_datatable.cpython-37.pyc differ Binary files old/Quandl-3.4.2/test/__pycache__/test_datatable_data.cpython-35.pyc and new/Quandl-3.4.4/test/__pycache__/test_datatable_data.cpython-35.pyc differ Binary files old/Quandl-3.4.2/test/__pycache__/test_datatable_data.cpython-36.pyc and new/Quandl-3.4.4/test/__pycache__/test_datatable_data.cpython-36.pyc differ Binary files old/Quandl-3.4.2/test/__pycache__/test_datatable_data.cpython-37.pyc and new/Quandl-3.4.4/test/__pycache__/test_datatable_data.cpython-37.pyc differ Binary files old/Quandl-3.4.2/test/__pycache__/test_get.cpython-35.pyc and new/Quandl-3.4.4/test/__pycache__/test_get.cpython-35.pyc differ Binary files old/Quandl-3.4.2/test/__pycache__/test_get.cpython-36.pyc and new/Quandl-3.4.4/test/__pycache__/test_get.cpython-36.pyc differ Binary files old/Quandl-3.4.2/test/__pycache__/test_get.cpython-37.pyc and new/Quandl-3.4.4/test/__pycache__/test_get.cpython-37.pyc differ Binary files old/Quandl-3.4.2/test/__pycache__/test_get_table.cpython-35.pyc and new/Quandl-3.4.4/test/__pycache__/test_get_table.cpython-35.pyc differ Binary files old/Quandl-3.4.2/test/__pycache__/test_get_table.cpython-36.pyc and new/Quandl-3.4.4/test/__pycache__/test_get_table.cpython-36.pyc differ Binary files old/Quandl-3.4.2/test/__pycache__/test_get_table.cpython-37.pyc and new/Quandl-3.4.4/test/__pycache__/test_get_table.cpython-37.pyc differ Binary files old/Quandl-3.4.2/test/__pycache__/test_merged_dataset.cpython-34.pyc and new/Quandl-3.4.4/test/__pycache__/test_merged_dataset.cpython-34.pyc differ Binary files old/Quandl-3.4.2/test/__pycache__/test_merged_dataset.cpython-35.pyc and new/Quandl-3.4.4/test/__pycache__/test_merged_dataset.cpython-35.pyc differ Binary files old/Quandl-3.4.2/test/__pycache__/test_merged_dataset.cpython-36.pyc and new/Quandl-3.4.4/test/__pycache__/test_merged_dataset.cpython-36.pyc differ Binary files old/Quandl-3.4.2/test/__pycache__/test_merged_dataset.cpython-37.pyc and new/Quandl-3.4.4/test/__pycache__/test_merged_dataset.cpython-37.pyc differ Binary files old/Quandl-3.4.2/test/__pycache__/test_model.cpython-34.pyc and new/Quandl-3.4.4/test/__pycache__/test_model.cpython-34.pyc differ Binary files old/Quandl-3.4.2/test/__pycache__/test_model.cpython-35.pyc and new/Quandl-3.4.4/test/__pycache__/test_model.cpython-35.pyc differ Binary files old/Quandl-3.4.2/test/__pycache__/test_model.cpython-36.pyc and new/Quandl-3.4.4/test/__pycache__/test_model.cpython-36.pyc differ Binary files old/Quandl-3.4.2/test/__pycache__/test_model.cpython-37.pyc and new/Quandl-3.4.4/test/__pycache__/test_model.cpython-37.pyc differ Binary files old/Quandl-3.4.2/test/__pycache__/test_retries.cpython-37.pyc and new/Quandl-3.4.4/test/__pycache__/test_retries.cpython-37.pyc differ Binary files old/Quandl-3.4.2/test/__pycache__/test_util.cpython-34.pyc and new/Quandl-3.4.4/test/__pycache__/test_util.cpython-34.pyc differ Binary files old/Quandl-3.4.2/test/__pycache__/test_util.cpython-35.pyc and new/Quandl-3.4.4/test/__pycache__/test_util.cpython-35.pyc differ Binary files old/Quandl-3.4.2/test/__pycache__/test_util.cpython-36.pyc and new/Quandl-3.4.4/test/__pycache__/test_util.cpython-36.pyc differ Binary files old/Quandl-3.4.2/test/__pycache__/test_util.cpython-37.pyc and new/Quandl-3.4.4/test/__pycache__/test_util.cpython-37.pyc differ Binary files old/Quandl-3.4.2/test/factories/__init__.pyc and new/Quandl-3.4.4/test/factories/__init__.pyc differ Binary files old/Quandl-3.4.2/test/factories/__pycache__/__init__.cpython-34.pyc and new/Quandl-3.4.4/test/factories/__pycache__/__init__.cpython-34.pyc differ Binary files old/Quandl-3.4.2/test/factories/__pycache__/__init__.cpython-35.pyc and new/Quandl-3.4.4/test/factories/__pycache__/__init__.cpython-35.pyc differ Binary files old/Quandl-3.4.2/test/factories/__pycache__/__init__.cpython-36.pyc and new/Quandl-3.4.4/test/factories/__pycache__/__init__.cpython-36.pyc differ Binary files old/Quandl-3.4.2/test/factories/__pycache__/__init__.cpython-37.pyc and new/Quandl-3.4.4/test/factories/__pycache__/__init__.cpython-37.pyc differ Binary files old/Quandl-3.4.2/test/factories/__pycache__/database.cpython-34.pyc and new/Quandl-3.4.4/test/factories/__pycache__/database.cpython-34.pyc differ Binary files old/Quandl-3.4.2/test/factories/__pycache__/database.cpython-35.pyc and new/Quandl-3.4.4/test/factories/__pycache__/database.cpython-35.pyc differ Binary files old/Quandl-3.4.2/test/factories/__pycache__/database.cpython-36.pyc and new/Quandl-3.4.4/test/factories/__pycache__/database.cpython-36.pyc differ Binary files old/Quandl-3.4.2/test/factories/__pycache__/database.cpython-37.pyc and new/Quandl-3.4.4/test/factories/__pycache__/database.cpython-37.pyc differ Binary files old/Quandl-3.4.2/test/factories/__pycache__/dataset.cpython-34.pyc and new/Quandl-3.4.4/test/factories/__pycache__/dataset.cpython-34.pyc differ Binary files old/Quandl-3.4.2/test/factories/__pycache__/dataset.cpython-35.pyc and new/Quandl-3.4.4/test/factories/__pycache__/dataset.cpython-35.pyc differ Binary files old/Quandl-3.4.2/test/factories/__pycache__/dataset.cpython-36.pyc and new/Quandl-3.4.4/test/factories/__pycache__/dataset.cpython-36.pyc differ Binary files old/Quandl-3.4.2/test/factories/__pycache__/dataset.cpython-37.pyc and new/Quandl-3.4.4/test/factories/__pycache__/dataset.cpython-37.pyc differ Binary files old/Quandl-3.4.2/test/factories/__pycache__/dataset_data.cpython-34.pyc and new/Quandl-3.4.4/test/factories/__pycache__/dataset_data.cpython-34.pyc differ Binary files old/Quandl-3.4.2/test/factories/__pycache__/dataset_data.cpython-35.pyc and new/Quandl-3.4.4/test/factories/__pycache__/dataset_data.cpython-35.pyc differ Binary files old/Quandl-3.4.2/test/factories/__pycache__/dataset_data.cpython-36.pyc and new/Quandl-3.4.4/test/factories/__pycache__/dataset_data.cpython-36.pyc differ Binary files old/Quandl-3.4.2/test/factories/__pycache__/dataset_data.cpython-37.pyc and new/Quandl-3.4.4/test/factories/__pycache__/dataset_data.cpython-37.pyc differ Binary files old/Quandl-3.4.2/test/factories/__pycache__/datatable.cpython-35.pyc and new/Quandl-3.4.4/test/factories/__pycache__/datatable.cpython-35.pyc differ Binary files old/Quandl-3.4.2/test/factories/__pycache__/datatable.cpython-36.pyc and new/Quandl-3.4.4/test/factories/__pycache__/datatable.cpython-36.pyc differ Binary files old/Quandl-3.4.2/test/factories/__pycache__/datatable.cpython-37.pyc and new/Quandl-3.4.4/test/factories/__pycache__/datatable.cpython-37.pyc differ Binary files old/Quandl-3.4.2/test/factories/__pycache__/datatable_data.cpython-35.pyc and new/Quandl-3.4.4/test/factories/__pycache__/datatable_data.cpython-35.pyc differ Binary files old/Quandl-3.4.2/test/factories/__pycache__/datatable_data.cpython-36.pyc and new/Quandl-3.4.4/test/factories/__pycache__/datatable_data.cpython-36.pyc differ Binary files old/Quandl-3.4.2/test/factories/__pycache__/datatable_data.cpython-37.pyc and new/Quandl-3.4.4/test/factories/__pycache__/datatable_data.cpython-37.pyc differ Binary files old/Quandl-3.4.2/test/factories/__pycache__/datatable_meta.cpython-35.pyc and new/Quandl-3.4.4/test/factories/__pycache__/datatable_meta.cpython-35.pyc differ Binary files old/Quandl-3.4.2/test/factories/__pycache__/datatable_meta.cpython-36.pyc and new/Quandl-3.4.4/test/factories/__pycache__/datatable_meta.cpython-36.pyc differ Binary files old/Quandl-3.4.2/test/factories/__pycache__/datatable_meta.cpython-37.pyc and new/Quandl-3.4.4/test/factories/__pycache__/datatable_meta.cpython-37.pyc differ Binary files old/Quandl-3.4.2/test/factories/__pycache__/meta.cpython-34.pyc and new/Quandl-3.4.4/test/factories/__pycache__/meta.cpython-34.pyc differ Binary files old/Quandl-3.4.2/test/factories/__pycache__/meta.cpython-35.pyc and new/Quandl-3.4.4/test/factories/__pycache__/meta.cpython-35.pyc differ Binary files old/Quandl-3.4.2/test/factories/__pycache__/meta.cpython-36.pyc and new/Quandl-3.4.4/test/factories/__pycache__/meta.cpython-36.pyc differ Binary files old/Quandl-3.4.2/test/factories/__pycache__/meta.cpython-37.pyc and new/Quandl-3.4.4/test/factories/__pycache__/meta.cpython-37.pyc differ Binary files old/Quandl-3.4.2/test/factories/database.pyc and new/Quandl-3.4.4/test/factories/database.pyc differ Binary files old/Quandl-3.4.2/test/factories/dataset.pyc and new/Quandl-3.4.4/test/factories/dataset.pyc differ Binary files old/Quandl-3.4.2/test/factories/dataset_data.pyc and new/Quandl-3.4.4/test/factories/dataset_data.pyc differ Binary files old/Quandl-3.4.2/test/factories/meta.pyc and new/Quandl-3.4.4/test/factories/meta.pyc differ Binary files old/Quandl-3.4.2/test/helpers/__pycache__/__init__.cpython-35.pyc and new/Quandl-3.4.4/test/helpers/__pycache__/__init__.cpython-35.pyc differ Binary files old/Quandl-3.4.2/test/helpers/__pycache__/__init__.cpython-36.pyc and new/Quandl-3.4.4/test/helpers/__pycache__/__init__.cpython-36.pyc differ Binary files old/Quandl-3.4.2/test/helpers/__pycache__/__init__.cpython-37.pyc and new/Quandl-3.4.4/test/helpers/__pycache__/__init__.cpython-37.pyc differ Binary files old/Quandl-3.4.2/test/helpers/__pycache__/httpretty_extension.cpython-35.pyc and new/Quandl-3.4.4/test/helpers/__pycache__/httpretty_extension.cpython-35.pyc differ Binary files old/Quandl-3.4.2/test/helpers/__pycache__/httpretty_extension.cpython-36.pyc and new/Quandl-3.4.4/test/helpers/__pycache__/httpretty_extension.cpython-36.pyc differ Binary files old/Quandl-3.4.2/test/helpers/__pycache__/httpretty_extension.cpython-37.pyc and new/Quandl-3.4.4/test/helpers/__pycache__/httpretty_extension.cpython-37.pyc differ Binary files old/Quandl-3.4.2/test/helpers/__pycache__/merged_datasets_helper.cpython-35.pyc and new/Quandl-3.4.4/test/helpers/__pycache__/merged_datasets_helper.cpython-35.pyc differ Binary files old/Quandl-3.4.2/test/helpers/__pycache__/merged_datasets_helper.cpython-36.pyc and new/Quandl-3.4.4/test/helpers/__pycache__/merged_datasets_helper.cpython-36.pyc differ Binary files old/Quandl-3.4.2/test/helpers/__pycache__/merged_datasets_helper.cpython-37.pyc and new/Quandl-3.4.4/test/helpers/__pycache__/merged_datasets_helper.cpython-37.pyc differ Binary files old/Quandl-3.4.2/test/helpers/__pycache__/my_httpretty.cpython-35.pyc and new/Quandl-3.4.4/test/helpers/__pycache__/my_httpretty.cpython-35.pyc differ Binary files old/Quandl-3.4.2/test/helpers/__pycache__/my_httpretty.cpython-36.pyc and new/Quandl-3.4.4/test/helpers/__pycache__/my_httpretty.cpython-36.pyc differ Binary files old/Quandl-3.4.2/test/helpers/__pycache__/my_httpretty.cpython-37.pyc and new/Quandl-3.4.4/test/helpers/__pycache__/my_httpretty.cpython-37.pyc differ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Quandl-3.4.2/test/test_connection.py new/Quandl-3.4.4/test/test_connection.py --- old/Quandl-3.4.2/test/test_connection.py 2018-08-21 17:53:49.000000000 +0200 +++ new/Quandl-3.4.4/test/test_connection.py 2018-10-24 21:24:58.000000000 +0200 @@ -4,17 +4,18 @@ QuandlError, LimitExceededError, InternalServerError, AuthenticationError, ForbiddenError, InvalidRequestError, NotFoundError, ServiceUnavailableError) -import unittest2 +from test.test_retries import ModifyRetrySettingsTestCase from test.helpers.httpretty_extension import httpretty import json from mock import patch, call from quandl.version import VERSION -class ConnectionTest(unittest2.TestCase): +class ConnectionTest(ModifyRetrySettingsTestCase): @httpretty.activate - def test_quandl_exceptions(self): + def test_quandl_exceptions_no_retries(self): + ApiConfig.use_retries = False quandl_errors = [('QELx04', 429, LimitExceededError), ('QEMx01', 500, InternalServerError), ('QEAx01', 400, AuthenticationError), @@ -38,6 +39,7 @@ @httpretty.activate def test_parse_error(self): + ApiConfig.retry_backoff_factor = 0 httpretty.register_uri(httpretty.GET, "https://www.quandl.com/api/v3/databases", body="not json", status=500) @@ -46,6 +48,7 @@ @httpretty.activate def test_non_quandl_error(self): + ApiConfig.retry_backoff_factor = 0 httpretty.register_uri(httpretty.GET, "https://www.quandl.com/api/v3/databases", body=json.dumps( @@ -70,6 +73,4 @@ '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) Binary files old/Quandl-3.4.2/test/test_connection.pyc and new/Quandl-3.4.4/test/test_connection.pyc differ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Quandl-3.4.2/test/test_data.py new/Quandl-3.4.4/test/test_data.py --- old/Quandl-3.4.2/test/test_data.py 2016-05-18 19:52:25.000000000 +0200 +++ new/Quandl-3.4.4/test/test_data.py 2018-10-19 21:55:16.000000000 +0200 @@ -1,5 +1,5 @@ import re -import unittest2 +import unittest from test.helpers.httpretty_extension import httpretty import json import datetime @@ -12,7 +12,7 @@ from quandl.errors.quandl_error import InvalidDataError -class DataTest(unittest2.TestCase): +class DataTest(unittest.TestCase): @classmethod def setUpClass(cls): @@ -48,7 +48,7 @@ self.assertIsNotNone(self.data_object.meta) -class ListDataTest(unittest2.TestCase): +class ListDataTest(unittest.TestCase): @classmethod def setUpClass(cls): @@ -99,24 +99,24 @@ def test_column_names_match(self): results = Data.all( params={'database_code': 'NSE', 'dataset_code': 'OIL'}) - self.assertItemsEqual( - results.column_names, ['Date', 'column.1', 'column.2', 'column.3']) + six.assertCountEqual(self, + results.column_names, ['Date', 'column.1', 'column.2', 'column.3']) def test_raw_data_is_zip_of_column_names_and_data(self): results = Data.all( params={'database_code': 'NSE', 'dataset_code': 'OIL'}) - self.assertItemsEqual(results[0].__get_raw_data__(), self.expected_list_values[0]) - self.assertItemsEqual(results[1].__get_raw_data__(), self.expected_list_values[1]) - self.assertItemsEqual(results[2].__get_raw_data__(), self.expected_list_values[2]) - self.assertItemsEqual(results[3].__get_raw_data__(), self.expected_list_values[3]) + six.assertCountEqual(self, results[0].__get_raw_data__(), self.expected_list_values[0]) + six.assertCountEqual(self, results[1].__get_raw_data__(), self.expected_list_values[1]) + six.assertCountEqual(self, results[2].__get_raw_data__(), self.expected_list_values[2]) + six.assertCountEqual(self, results[3].__get_raw_data__(), self.expected_list_values[3]) def test_data_to_list(self): list_data = Data.all( params={'database_code': 'NSE', 'dataset_code': 'OIL'}).to_list() - self.assertItemsEqual(list_data[0], self.expected_list_values[0]) - self.assertItemsEqual(list_data[1], self.expected_list_values[1]) - self.assertItemsEqual(list_data[2], self.expected_list_values[2]) - self.assertItemsEqual(list_data[3], self.expected_list_values[3]) + six.assertCountEqual(self, list_data[0], self.expected_list_values[0]) + six.assertCountEqual(self, list_data[1], self.expected_list_values[1]) + six.assertCountEqual(self, list_data[2], self.expected_list_values[2]) + six.assertCountEqual(self, list_data[3], self.expected_list_values[3]) def test_to_pandas_returns_pandas_dataframe_object(self): results = Data.all( Binary files old/Quandl-3.4.2/test/test_data.pyc and new/Quandl-3.4.4/test/test_data.pyc differ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Quandl-3.4.2/test/test_database.py new/Quandl-3.4.4/test/test_database.py --- old/Quandl-3.4.2/test/test_database.py 2016-05-18 19:52:25.000000000 +0200 +++ new/Quandl-3.4.4/test/test_database.py 2018-10-24 21:24:58.000000000 +0200 @@ -6,7 +6,7 @@ from cgi import parse_qs import re -import unittest2 +import unittest from test.helpers.httpretty_extension import httpretty import json import six @@ -14,12 +14,13 @@ from quandl.api_config import ApiConfig from quandl.model.database import Database from quandl.connection import Connection +from test.test_retries import ModifyRetrySettingsTestCase from mock import patch, call, mock_open from test.factories.database import DatabaseFactory from test.factories.meta import MetaFactory -class GetDatabaseTest(unittest2.TestCase): +class GetDatabaseTest(unittest.TestCase): @classmethod def setUpClass(cls): @@ -64,7 +65,7 @@ self.assertEqual(mock.call_args, expected) -class ListDatabasesTest(unittest2.TestCase): +class ListDatabasesTest(unittest.TestCase): @classmethod def setUpClass(cls): @@ -102,18 +103,17 @@ def test_databases_returns_expected_ids(self): results = Database.all() self.assertEqual(len(results), 10) - self.assertItemsEqual([x.id for x in results], - [x['id'] for x in self.expected_databases['databases']]) + six.assertCountEqual(self, [x.id for x in results], + [x['id'] for x in self.expected_databases['databases']]) def test_databases_has_more(self): results = Database.all() self.assertTrue(results.has_more_results()) -class BulkDownloadDatabaseTest(unittest2.TestCase): +class BulkDownloadDatabaseTest(ModifyRetrySettingsTestCase): - @classmethod - def setUpClass(cls): + def setUp(self): httpretty.enable() httpretty.register_uri(httpretty.GET, re.compile( @@ -125,17 +125,15 @@ httpretty.register_uri(httpretty.GET, re.compile('https://www.blah.com/'), body='{}') - @classmethod - def tearDownClass(cls): - httpretty.disable() - httpretty.reset() - - def setUp(self): database = {'database': DatabaseFactory.build(database_code='NSE')} self.database = Database(database['database']['database_code'], database['database']) ApiConfig.api_key = 'api_token' ApiConfig.api_version = '2015-04-09' + def tearDown(self): + httpretty.disable() + httpretty.reset() + def test_get_bulk_downnload_url_with_download_type(self): url = self.database.bulk_download_url(params={'download_type': 'partial'}) parsed_url = urlparse(url) @@ -179,6 +177,8 @@ QuandlError, lambda: self.database.bulk_download_to_file(None)) def test_bulk_download_raises_exception_when_error_response(self): + ApiConfig.retry_backoff_factor = 0 + httpretty.reset() httpretty.register_uri(httpretty.GET, re.compile( 'https://www.quandl.com/api/v3/databases/*'), @@ -186,5 +186,6 @@ {'quandl_error': {'code': 'QEMx01', 'message': 'something went wrong'}}), status=500) + self.assertRaises( InternalServerError, lambda: self.database.bulk_download_to_file('.')) Binary files old/Quandl-3.4.2/test/test_database.pyc and new/Quandl-3.4.4/test/test_database.pyc differ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Quandl-3.4.2/test/test_dataset.py new/Quandl-3.4.4/test/test_dataset.py --- old/Quandl-3.4.2/test/test_dataset.py 2016-05-18 19:52:25.000000000 +0200 +++ new/Quandl-3.4.4/test/test_dataset.py 2018-10-19 21:55:16.000000000 +0200 @@ -1,8 +1,9 @@ import re -import unittest2 +import unittest from test.helpers.httpretty_extension import httpretty import json import datetime +import six from quandl.model.dataset import Dataset from quandl.model.database import Database from mock import patch, call @@ -10,7 +11,7 @@ from test.factories.meta import MetaFactory -class GetDatasetTest(unittest2.TestCase): +class GetDatasetTest(unittest.TestCase): @classmethod def setUpClass(cls): @@ -48,8 +49,8 @@ def test_dataset_column_names_match_expected(self): dataset = Dataset('NSE/OIL') - self.assertItemsEqual( - dataset.column_names, ['Date', 'column.1', 'column.2', 'column.3']) + six.assertCountEqual(self, + dataset.column_names, ['Date', 'column.1', 'column.2', 'column.3']) def test_dataset_database_gives_instance_of_database(self): database = self.dataset_instance.database() @@ -65,7 +66,7 @@ self.assertEqual(mock.call_args, expected) -class ListDatasetsTest(unittest2.TestCase): +class ListDatasetsTest(unittest.TestCase): @classmethod def setUpClass(cls): Binary files old/Quandl-3.4.2/test/test_dataset.pyc and new/Quandl-3.4.4/test/test_dataset.pyc differ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Quandl-3.4.2/test/test_datatable.py new/Quandl-3.4.4/test/test_datatable.py --- old/Quandl-3.4.2/test/test_datatable.py 2016-05-18 19:52:25.000000000 +0200 +++ new/Quandl-3.4.4/test/test_datatable.py 2018-10-24 21:24:58.000000000 +0200 @@ -1,13 +1,22 @@ +try: + from urllib.parse import urlparse +except ImportError: + from urlparse import urlparse + import re -import unittest2 +import unittest import httpretty import json +import six from quandl.model.datatable import Datatable -from mock import patch, call +from mock import patch, call, mock_open from test.factories.datatable import DatatableFactory +from test.test_retries import ModifyRetrySettingsTestCase +from quandl.api_config import ApiConfig +from quandl.errors.quandl_error import (InternalServerError, QuandlError) -class GetDatatableDatasetTest(unittest2.TestCase): +class GetDatatableDatasetTest(ModifyRetrySettingsTestCase): @classmethod def setUpClass(cls): @@ -45,5 +54,78 @@ def test_dataset_column_names_match_expected(self): metadata = Datatable('ZACKS/FC').data_fields() - self.assertItemsEqual( - metadata, [u'datatable_code', u'id', u'name', u'vendor_code']) + six.assertCountEqual(self, + metadata, [u'datatable_code', u'id', u'name', u'vendor_code']) + + +class ExportDataTableTest(unittest.TestCase): + + @classmethod + def setUpClass(cls): + httpretty.enable() + datatable = {'datatable': DatatableFactory.build( + vendor_code='AUSBS', datatable_code='D')} + httpretty.register_uri(httpretty.GET, + re.compile( + 'https://www.quandl.com/api/v3/datatables/*'), + body=json.dumps(datatable)) + cls.datatable_instance = Datatable(datatable['datatable']) + + @classmethod + def tearDownClass(cls): + httpretty.disable() + httpretty.reset() + + def setUp(self): + datatable = {'datatable': DatatableFactory.build( + vendor_code='AUSBS', datatable_code='D')} + self.datatable = Datatable(datatable['datatable']['vendor_code'] + '/' + + datatable['datatable']['datatable_code'], datatable['datatable']) + ApiConfig.api_key = 'api_token' + ApiConfig.api_version = '2015-04-09' + + def test_download_get_file_info(self): + url = self.datatable._download_request_path() + parsed_url = urlparse(url) + self.assertEqual(parsed_url.path, 'datatables/AUSBS/D.json') + + def test_download_generated_file(self): + m = mock_open() + + httpretty.register_uri(httpretty.GET, + re.compile( + 'https://www.quandl.com/api/v3/datatables/*'), + body=json.dumps({ + 'datatable_bulk_download': { + 'file': { + 'status': 'fresh', + 'link': 'https://www.blah.com/download/db.zip' + } + } + }), + status=200) + + with patch('quandl.model.datatable.urlopen', m, create=True): + self.datatable.download_file('.') + + self.assertEqual(m.call_count, 1) + + def test_bulk_download_raises_exception_when_no_path(self): + self.assertRaises( + QuandlError, lambda: self.datatable.download_file(None)) + + def test_bulk_download_table_raises_exception_when_error_response(self): + httpretty.reset() + ApiConfig.number_of_retries = 2 + error_responses = [httpretty.Response( + body=json.dumps({'quandl_error': {'code': 'QEMx01', + 'message': 'something went wrong'}}), + status=500)] + + httpretty.register_uri(httpretty.GET, + re.compile( + 'https://www.quandl.com/api/v3/datatables/*'), + responses=error_responses) + + self.assertRaises( + InternalServerError, lambda: self.datatable.download_file('.')) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Quandl-3.4.2/test/test_datatable_data.py new/Quandl-3.4.4/test/test_datatable_data.py --- old/Quandl-3.4.2/test/test_datatable_data.py 2016-05-18 19:52:25.000000000 +0200 +++ new/Quandl-3.4.4/test/test_datatable_data.py 2018-10-19 21:55:16.000000000 +0200 @@ -1,5 +1,5 @@ import re -import unittest2 +import unittest import httpretty import json import pandas @@ -12,7 +12,7 @@ from test.factories.datatable_meta import DatatableMetaFactory -class DatatableDataTest(unittest2.TestCase): +class DatatableDataTest(unittest.TestCase): @classmethod def setUpClass(cls): @@ -52,7 +52,7 @@ self.assertIsNotNone(self.data_object.meta) -class ListDatatableDataTest(unittest2.TestCase): +class ListDatatableDataTest(unittest.TestCase): @classmethod def setUpClass(cls): diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Quandl-3.4.2/test/test_get.py new/Quandl-3.4.4/test/test_get.py --- old/Quandl-3.4.2/test/test_get.py 2017-06-14 22:05:37.000000000 +0200 +++ new/Quandl-3.4.4/test/test_get.py 2018-10-19 21:55:16.000000000 +0200 @@ -1,4 +1,4 @@ -import unittest2 +import unittest from test.helpers.httpretty_extension import httpretty from test.helpers.merged_datasets_helper import setupDatasetsTest import pandas @@ -11,7 +11,7 @@ from quandl.connection import Connection -class GetSingleDatasetTest(unittest2.TestCase): +class GetSingleDatasetTest(unittest.TestCase): @classmethod def setUp(self): # ensure api key is not set @@ -104,7 +104,7 @@ self.assertRaises(ValueError, lambda: get('NSE/OIL.notanumber')) -class GetMultipleDatasetsTest(unittest2.TestCase): +class GetMultipleDatasetsTest(unittest.TestCase): @classmethod def setUp(self): # ensure api key is not set diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Quandl-3.4.2/test/test_get_table.py new/Quandl-3.4.4/test/test_get_table.py --- old/Quandl-3.4.2/test/test_get_table.py 2017-03-07 17:12:24.000000000 +0100 +++ new/Quandl-3.4.4/test/test_get_table.py 2018-10-19 21:55:16.000000000 +0200 @@ -1,5 +1,5 @@ import re -import unittest2 +import unittest import httpretty import json from quandl.model.datatable import Datatable @@ -11,7 +11,7 @@ import quandl -class GetDataTableTest(unittest2.TestCase): +class GetDataTableTest(unittest.TestCase): @classmethod def setUpClass(cls): diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Quandl-3.4.2/test/test_merged_dataset.py new/Quandl-3.4.4/test/test_merged_dataset.py --- old/Quandl-3.4.2/test/test_merged_dataset.py 2018-08-21 16:07:11.000000000 +0200 +++ new/Quandl-3.4.4/test/test_merged_dataset.py 2018-10-19 21:55:16.000000000 +0200 @@ -1,4 +1,4 @@ -import unittest2 +import unittest from test.helpers.httpretty_extension import httpretty import six import datetime @@ -12,7 +12,7 @@ from test.helpers.merged_datasets_helper import setupDatasetsTest -class GetMergedDatasetTest(unittest2.TestCase): +class GetMergedDatasetTest(unittest.TestCase): @classmethod def setUp(self): @@ -57,8 +57,8 @@ ('WIKI/AAPL', {'column_index': [1]}), ('WIKI/MSFT')]) self.assertEqual(md._datasets, None) - self.assertItemsEqual([1, 2], md.dataset_codes[0][1]['column_index']) - self.assertItemsEqual([1], md.dataset_codes[1][1]['column_index']) + six.assertCountEqual(self, [1, 2], md.dataset_codes[0][1]['column_index']) + six.assertCountEqual(self, [1], md.dataset_codes[1][1]['column_index']) self.assertEqual('I', md.dataset_codes[2][1]) def test_sets_column_index_on_each_dataset(self): @@ -67,9 +67,9 @@ ('WIKI/AAPL', {'column_index': [1]}), ('WIKI/MSFT')]) md.data_fields() - self.assertItemsEqual([1, 2], md._datasets[0].requested_column_indexes) - self.assertItemsEqual([1], md._datasets[1].requested_column_indexes) - self.assertItemsEqual([], md._datasets[2].requested_column_indexes) + six.assertCountEqual(self, [1, 2], md._datasets[0].requested_column_indexes) + six.assertCountEqual(self, [1], md._datasets[1].requested_column_indexes) + six.assertCountEqual(self, [], md._datasets[2].requested_column_indexes) def test_merged_dataset_column_names(self): md = MergedDataset( @@ -82,7 +82,7 @@ six.u('WIKI/MSFT - column.1'), six.u('WIKI/MSFT - column.2'), six.u('WIKI/MSFT - column.3')] - self.assertItemsEqual(md.column_names, expected) + six.assertCountEqual(self, md.column_names, expected) def test_merged_dataset_oldest_available_date(self): md = MergedDataset( @@ -103,15 +103,15 @@ [('NSE/OIL', {'column_index': [1, 2]}), ('WIKI/AAPL', {'column_index': [1]}), ('WIKI/MSFT')]) - self.assertItemsEqual(md.database_code, ['NSE', 'WIKI']) + six.assertCountEqual(self, md.database_code, ['NSE', 'WIKI']) def test_merged_dataset_dataset_codes(self): md = MergedDataset( [('NSE/OIL', {'column_index': [1, 2]}), ('WIKI/AAPL', {'column_index': [1]}), ('WIKI/MSFT')]) - self.assertItemsEqual( - md.dataset_code, ['OIL', 'AAPL', 'MSFT']) + six.assertCountEqual(self, + md.dataset_code, ['OIL', 'AAPL', 'MSFT']) def test_get_returns_merged_dataset_obj(self): md = MergedDataset(['NSE/OIL']) @@ -187,7 +187,7 @@ six.u('WIKI/MSFT - column.1'), six.u('WIKI/MSFT - column.2'), six.u('WIKI/MSFT - column.3')] - self.assertItemsEqual(actual, expected) + six.assertCountEqual(self, actual, expected) def test_get_merged_dataset_data_to_list(self): data = MergedDataset( @@ -203,7 +203,7 @@ [datetime.datetime(2015, 7, 14, 0, 0), 437.5, 3, 437.5, 437.5, 3, 3], [datetime.datetime(2015, 7, 15, 0, 0), 440.0, 2, 440.0, 440.0, 2, 3]] for index, expected_item in enumerate(expected): - self.assertItemsEqual(expected_item, results[index]) + six.assertCountEqual(self, expected_item, results[index]) def test_get_merged_dataset_data_is_descending_when_specified_in_params(self): data = MergedDataset(['NSE/OIL', 'WIKI/AAPL', Binary files old/Quandl-3.4.2/test/test_merged_dataset.pyc and new/Quandl-3.4.4/test/test_merged_dataset.pyc differ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Quandl-3.4.2/test/test_model.py new/Quandl-3.4.4/test/test_model.py --- old/Quandl-3.4.2/test/test_model.py 2016-05-18 19:52:25.000000000 +0200 +++ new/Quandl-3.4.4/test/test_model.py 2018-10-19 21:55:16.000000000 +0200 @@ -1,15 +1,17 @@ -import unittest2 +import unittest from quandl.model.model_base import ModelBase +import six -class ModelTest(unittest2.TestCase): + +class ModelTest(unittest.TestCase): def setUp(self): self.model = ModelBase('foo', {'foo': 'bar', 'here': 1}) def test_data_fields_returns_list_of_attribute_keys(self): data_fields = self.model.data_fields() - self.assertItemsEqual(data_fields, ['foo', 'here']) + six.assertCountEqual(self, data_fields, ['foo', 'here']) def test_data_can_be_accessed_as_dict(self): self.assertEqual(self.model['foo'], 'bar') @@ -24,4 +26,4 @@ def test_to_list_returns_values(self): results = self.model.to_list() - self.assertItemsEqual(results, ['bar', 1]) + six.assertCountEqual(self, results, ['bar', 1]) Binary files old/Quandl-3.4.2/test/test_model.pyc and new/Quandl-3.4.4/test/test_model.pyc differ Binary files old/Quandl-3.4.2/test/test_operations/__pycache__/__init__.cpython-35.pyc and new/Quandl-3.4.4/test/test_operations/__pycache__/__init__.cpython-35.pyc differ Binary files old/Quandl-3.4.2/test/test_operations/__pycache__/__init__.cpython-36.pyc and new/Quandl-3.4.4/test/test_operations/__pycache__/__init__.cpython-36.pyc differ Binary files old/Quandl-3.4.2/test/test_operations/__pycache__/__init__.cpython-37.pyc and new/Quandl-3.4.4/test/test_operations/__pycache__/__init__.cpython-37.pyc differ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Quandl-3.4.2/test/test_retries.py new/Quandl-3.4.4/test/test_retries.py --- old/Quandl-3.4.2/test/test_retries.py 1970-01-01 01:00:00.000000000 +0100 +++ new/Quandl-3.4.4/test/test_retries.py 2018-10-24 21:24:58.000000000 +0200 @@ -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') diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Quandl-3.4.2/test/test_util.py new/Quandl-3.4.4/test/test_util.py --- old/Quandl-3.4.2/test/test_util.py 2016-05-18 19:52:25.000000000 +0200 +++ new/Quandl-3.4.4/test/test_util.py 2018-10-19 21:55:16.000000000 +0200 @@ -1,4 +1,4 @@ -import unittest2 +import unittest import datetime import six from quandl.util import Util @@ -11,7 +11,7 @@ return (a > b) - (a < b) -class UtilTest(unittest2.TestCase): +class UtilTest(unittest.TestCase): def test_methodize(self): self.assertEqual( Binary files old/Quandl-3.4.2/test/test_util.pyc and new/Quandl-3.4.4/test/test_util.pyc differ