diff --git a/alpaca/data/models/news.py b/alpaca/data/models/news.py index f49f12de..e553d4bf 100644 --- a/alpaca/data/models/news.py +++ b/alpaca/data/models/news.py @@ -66,9 +66,9 @@ class NewsSet(BaseDataSet, TimeSeriesMixin): Attributes: data (Dict[str, List[News]]): The collection of News articles. + next_page_token (Optional[str]): The token to get the next page of data. """ - news: List[News] next_page_token: Optional[str] def __init__(self, raw_data: RawData) -> None: @@ -81,9 +81,10 @@ def __init__(self, raw_data: RawData) -> None: articles = [] for article in raw_data.get("news", []): - articles.append(News(raw_data=article)) + news = News(raw_data=article) + articles.append(news) parsed_news["news"] = articles - parsed_news["next_page_token"] = raw_data.get("next_page_token") + next_page_token = raw_data.get("next_page_token") - super().__init__(**parsed_news) + super().__init__(data=parsed_news, next_page_token=next_page_token) diff --git a/tests/conftest.py b/tests/conftest.py index 33f2bbcb..cafabbc5 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -7,6 +7,7 @@ from alpaca.broker.client import BrokerClient from alpaca.data.historical import StockHistoricalDataClient from alpaca.data.historical.crypto import CryptoHistoricalDataClient +from alpaca.data.historical.news import NewsClient from alpaca.data.historical.option import OptionHistoricalDataClient from alpaca.data.historical.screener import ScreenerClient from alpaca.trading.client import TradingClient @@ -48,6 +49,12 @@ def stock_client(): return client +@pytest.fixture +def news_client(): + client = NewsClient("key-id", "secret-key") + return client + + @pytest.fixture def raw_stock_client(): raw_client = StockHistoricalDataClient("key-id", "secret-key", raw_data=True) diff --git a/tests/data/test_historical_news_data.py b/tests/data/test_historical_news_data.py new file mode 100644 index 00000000..e3da9081 --- /dev/null +++ b/tests/data/test_historical_news_data.py @@ -0,0 +1,72 @@ +import urllib.parse +from datetime import datetime, timezone + +from alpaca.data.historical import NewsClient +from alpaca.data.models.news import NewsSet +from alpaca.data.requests import NewsRequest + + +def test_get_news(reqmock, news_client: NewsClient): + # Test single symbol request + + symbols = "AAPL" + next_page_token = "MTcyNDAwMjIyNDAwMDAwMDAwMHw0MDQzMTg4MQ==" + _next_page_token_in_url = urllib.parse.quote_plus(next_page_token) + + start = datetime(2022, 2, 1) + _start_in_url = urllib.parse.quote_plus( + start.replace(tzinfo=timezone.utc).isoformat() + ) + reqmock.get( + f"https://data.alpaca.markets/v1beta1/news?symbols={symbols}&start={_start_in_url}&page_token={_next_page_token_in_url}", + text=""" +{ + "news": [ + { + "author": "John", + "content": "", + "created_at": "2024-08-18T20:15:44Z", + "headline": "headline", + "id": 40432158, + "images": [ + { + "size": "large", + "url": "https://" + }, + { + "size": "small", + "url": "https://" + }, + { + "size": "thumb", + "url": "https://" + } + ], + "source": "source", + "summary": "summary", + "symbols": [ + "AAPL", + "QCOM" + ], + "updated_at": "2024-08-18T20:15:44Z", + "url": "https://" + } + ], + "next_page_token": "MTcyNDAwMjIyNDAwMDAwMDAwMHw0MDQzMTg4MQ==" +} + """, + ) + request = NewsRequest( + symbols=symbols, + start=start, + page_token=next_page_token, + ) + newsset = news_client.get_news(request_params=request) + + assert isinstance(newsset, NewsSet) + + assert newsset["news"][0].id == 40432158 + + assert newsset.df.index.nlevels == 1 + + assert reqmock.called_once