From 5b6e6ce20257c210b8330055e166fe37b953461c Mon Sep 17 00:00:00 2001 From: Cameron Yick Date: Mon, 29 Apr 2019 23:17:02 -0400 Subject: [PATCH 1/4] [errors] Validate arguments to get_dataframe --- tiingo/api.py | 34 ++++++++++++++-------------------- tiingo/exceptions.py | 15 +++++++++++++++ 2 files changed, 29 insertions(+), 20 deletions(-) create mode 100644 tiingo/exceptions.py diff --git a/tiingo/api.py b/tiingo/api.py index f2ec61b..a3e3079 100644 --- a/tiingo/api.py +++ b/tiingo/api.py @@ -1,15 +1,16 @@ # -*- coding: utf-8 -*- -import os -import sys -import pkg_resources +from collections import namedtuple import csv import json -from collections import namedtuple -from zipfile import ZipFile -from tiingo.restclient import RestClient -import requests +import os import re +import sys +import pkg_resources +from zipfile import ZipFile + +from tiingo.restclient import RestClient +from tiingo.exceptions import InstallPandasException, APIColumnNameError, InvalidFrequencyError, MissingRequiredArgumentError try: import pandas as pd @@ -49,17 +50,6 @@ def dict_to_object(item, object_name): object_hook=lambda d: namedtuple(object_name, fields)(*values)) -class InstallPandasException(Exception): - pass - - -class APIColumnNameError(Exception): - pass - - -class InvalidFrequencyError(Exception): - pass - class TiingoClient(RestClient): """Class for managing interactions with the Tiingo REST API @@ -227,12 +217,16 @@ class TiingoClient(RestClient): frequency (string): Resample frequency (defaults to daily). """ - valid_columns = ['open', 'high', 'low', 'close', 'volume', 'adjOpen', 'adjHigh', 'adjLow', - 'adjClose', 'adjVolume', 'divCash', 'splitFactor'] + valid_columns = {'open', 'high', 'low', 'close', 'volume', 'adjOpen', 'adjHigh', 'adjLow', + 'adjClose', 'adjVolume', 'divCash', 'splitFactor'} if metric_name is not None and metric_name not in valid_columns: raise APIColumnNameError('Valid data items are: ' + str(valid_columns)) + if metric_name is None and type(tickers) is not str: + raise MissingRequiredArgumentError("""When tickers is provided as a list, metric_name is a required argument. + Please provide a metric_name, or call this method with one ticker at a time.""") + params = { 'format': 'json', 'resampleFreq': frequency diff --git a/tiingo/exceptions.py b/tiingo/exceptions.py new file mode 100644 index 0000000..81ff713 --- /dev/null +++ b/tiingo/exceptions.py @@ -0,0 +1,15 @@ +# Exception Clasess +class InstallPandasException(Exception): + pass + + +class APIColumnNameError(Exception): + pass + + +class InvalidFrequencyError(Exception): + pass + + +class MissingRequiredArgumentError(Exception): + pass From 61708c3291098ad591763fa7545db1cbebb6705a Mon Sep 17 00:00:00 2001 From: Cameron Yick Date: Mon, 29 Apr 2019 23:17:32 -0400 Subject: [PATCH 2/4] [dev] Update imports for custom exception classes --- tests/test_tiingo.py | 2 +- tests/test_tiingo_pandas.py | 6 +++++- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/tests/test_tiingo.py b/tests/test_tiingo.py index 0d0da23..9d920c2 100644 --- a/tests/test_tiingo.py +++ b/tests/test_tiingo.py @@ -6,7 +6,7 @@ from unittest import TestCase import vcr from tiingo import TiingoClient -from tiingo.api import InvalidFrequencyError +from tiingo.exceptions import InvalidFrequencyError from tiingo.restclient import RestClientError diff --git a/tests/test_tiingo_pandas.py b/tests/test_tiingo_pandas.py index 54ed91e..7d22ba7 100644 --- a/tests/test_tiingo_pandas.py +++ b/tests/test_tiingo_pandas.py @@ -4,7 +4,7 @@ import vcr from unittest import TestCase from tiingo import TiingoClient -from tiingo.api import APIColumnNameError, InstallPandasException +from tiingo.exceptions import APIColumnNameError, InstallPandasException, MissingRequiredArgumentError try: import pandas as pd pandas_is_installed = True @@ -69,6 +69,10 @@ class TestTiingoWithPython(TestCase): self._client.get_dataframe(['GOOGL', 'AAPL'], startDate='2018-01-05', endDate='2018-01-19', metric_name='xopen', frequency='weekly') + def test_metric_name_missing_when_multiple_tickers(self): + with self.assertRaises(MissingRequiredArgumentError): + self._client.get_dataframe(['GOOGL', 'AAPL'], frequency='weekly') + @vcr.use_cassette('tests/fixtures/ticker_price_pandas_single.yaml') def test_pandas_edge_case(self): """Test single price/date being returned as a frame""" From 922812a026d838c400667562f20ef519fe7ebaf9 Mon Sep 17 00:00:00 2001 From: Cameron Yick Date: Mon, 29 Apr 2019 23:19:49 -0400 Subject: [PATCH 3/4] [errors] Be more specific about requiring tickers as list --- tiingo/api.py | 10 ++++++++-- tiingo/exceptions.py | 1 - 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/tiingo/api.py b/tiingo/api.py index a3e3079..b8b3467 100644 --- a/tiingo/api.py +++ b/tiingo/api.py @@ -9,8 +9,14 @@ import sys import pkg_resources from zipfile import ZipFile +import requests + from tiingo.restclient import RestClient -from tiingo.exceptions import InstallPandasException, APIColumnNameError, InvalidFrequencyError, MissingRequiredArgumentError +from tiingo.exceptions import ( + InstallPandasException, + APIColumnNameError, + InvalidFrequencyError, + MissingRequiredArgumentError) try: import pandas as pd @@ -223,7 +229,7 @@ class TiingoClient(RestClient): if metric_name is not None and metric_name not in valid_columns: raise APIColumnNameError('Valid data items are: ' + str(valid_columns)) - if metric_name is None and type(tickers) is not str: + if metric_name is None and isinstance(tickers, list): raise MissingRequiredArgumentError("""When tickers is provided as a list, metric_name is a required argument. Please provide a metric_name, or call this method with one ticker at a time.""") diff --git a/tiingo/exceptions.py b/tiingo/exceptions.py index 81ff713..b510b75 100644 --- a/tiingo/exceptions.py +++ b/tiingo/exceptions.py @@ -10,6 +10,5 @@ class APIColumnNameError(Exception): class InvalidFrequencyError(Exception): pass - class MissingRequiredArgumentError(Exception): pass From 03e7b53d0577a1d75a5461fdca6889a526ab678e Mon Sep 17 00:00:00 2001 From: Cameron Yick Date: Sun, 5 May 2019 15:43:18 -0400 Subject: [PATCH 4/4] [documentation] Update changelog --- HISTORY.rst | 2 ++ 1 file changed, 2 insertions(+) diff --git a/HISTORY.rst b/HISTORY.rst index 615e5ce..ade7552 100644 --- a/HISTORY.rst +++ b/HISTORY.rst @@ -6,6 +6,8 @@ History 0.10.x (2019-XX-XX) ------------------ * Documentation: Added a "Peer Comparison Analysis" Jupyter Notebook under "/examples" (@i3creations #197) +* Minor: Update error message to clarify multiple tickers only work with single metrics +* Updated development dependencies 0.9.x (2019-01-30)