From 14d3bb6bd3ee993d2d2b459fa71f3f4296c938dd Mon Sep 17 00:00:00 2001 From: Cameron Yick Date: Sun, 17 Sep 2017 15:17:03 -0400 Subject: [PATCH] Add support + Tests for using News API --- tests/test_tiingo.py | 37 +++++++++++++++++++++++++++-------- tiingo/api.py | 46 ++++++++++++++++++++++---------------------- 2 files changed, 52 insertions(+), 31 deletions(-) diff --git a/tests/test_tiingo.py b/tests/test_tiingo.py index dc83494..e238052 100644 --- a/tests/test_tiingo.py +++ b/tests/test_tiingo.py @@ -3,7 +3,7 @@ """Tests for `tiingo` package.""" import csv -import pytest + from unittest import TestCase from tiingo import TiingoClient from tiingo.restclient import RestClientError @@ -12,7 +12,7 @@ from tiingo.restclient import RestClientError # TODO # Add tests for # Invalid API key -# Invalid ticker, etc +# Invalid ticker # Use unittest asserts rather than regular asserts # Wrap server errors with client side descriptive errors # Coerce startDate/endDate to string if they are passed in as datetime @@ -70,21 +70,42 @@ class TestTickerPrices(TestCase): response = self._client.list_tickers() assert not response -# News Feed + # tiingo/news class TestNews(TestCase): def setUp(self): self._client = TiingoClient() + self.article_keys = [ # Properties every article should have. + 'description', + 'title', + 'url', + 'publishedDate', + 'tags', + 'source', + 'tickers', + 'crawlDate', + 'id' + ] def test_get_news_articles(self): - """Rewrite when method is implemented - """ - with self.assertRaises(NotImplementedError): - self._client.get_news() + """Confirm that news article work""" + search_params = { + "tickers": ["aapl", "googl"], + "tags": ["Technology", "Bitcoin"], + "startDate": "2016-01-01", + "endDate": "2017-08-31", + "sources": ['washingtonpost.com', 'altcointoday.com'], + "limit": 10 + } + + articles = self._client.get_news(**search_params) + for article in articles: + assert all(key in article for key in self.article_keys) def test_get_news_bulk(self): - """Will fail because this API key lacks institutional license""" + """Fails because this API key lacks institutional license""" + with self.assertRaises(RestClientError): value = self._client.get_bulk_news(file_id="1") assert value diff --git a/tiingo/api.py b/tiingo/api.py index 4acd22f..0019980 100644 --- a/tiingo/api.py +++ b/tiingo/api.py @@ -94,7 +94,7 @@ class TiingoClient(RestClient): """Return list of news articles matching given search terms https://api.tiingo.com/docs/tiingo/news - # If no tickers provided, just searches general tickers + # Dates are in YYYY-MM-DD Format. Args: tickers [string] : List of unique Stock Tickers to search @@ -105,28 +105,28 @@ class TiingoClient(RestClient): offset (int): Search results offset, used for paginating sortBy (string): "publishedDate" OR (#TODO: UPDATE THIS) """ - # url = "tiingo/news" - # params = { - # 'limit': limit, - # 'offset': offset, - # 'sortBy': sortBy - # } - # # TBD: whether these commas are necessary if just pass list instead - # if tickers: - # params['tickers'] = ",".join(tickers) - # if tags: - # params['tags'] = ",".join(tags) - # if sources: - # params['sources'] = ",".join(sources) + url = "tiingo/news" + params = { + 'limit': limit, + 'offset': offset, + 'sortBy': sortBy + } - # if startDate: - # params['startDate'] = startDate - # if endDate: - # params['endDate'] = endDate + # TBD: whether these commas are necessary if just pass list instead + if tickers: + params['tickers'] = ",".join(tickers) + if tags: + params['tags'] = ",".join(tags) + if sources: + params['sources'] = ",".join(sources) - # response = self._request('GET', url, params=params) - # return response.json() - raise NotImplementedError + if startDate: + params['startDate'] = startDate + if endDate: + params['endDate'] = endDate + + response = self._request('GET', url, params=params) + return response.json() def get_bulk_news(self, file_id=None): """Only available to institutional clients. @@ -135,9 +135,9 @@ class TiingoClient(RestClient): file, as well as some metadata about that file. """ if file_id: - url = "tiingo/news/bulk_download" + url = "tiingo/news/bulk_download/{}".format(file_id) else: - url = "tiingo/news/bulk_download{}".format(file_id) + url = "tiingo/news/bulk_download" response = self._request('GET', url) return response.json()