diff --git a/docs/docs/integrations/tools/alpha_vantage.ipynb b/docs/docs/integrations/tools/alpha_vantage.ipynb index 958ae9e49591b..0a420bfb25f0f 100644 --- a/docs/docs/integrations/tools/alpha_vantage.ipynb +++ b/docs/docs/integrations/tools/alpha_vantage.ipynb @@ -21,15 +21,7 @@ "metadata": { "id": "34bb5968" }, - "outputs": [ - { - "name": "stdin", - "output_type": "stream", - "text": [ - " ········\n" - ] - } - ], + "outputs": [], "source": [ "import getpass\n", "import os\n", @@ -56,14 +48,172 @@ "metadata": { "id": "84b8f773" }, + "outputs": [ + { + "data": { + "text/plain": [ + "{'Realtime Currency Exchange Rate': {'1. From_Currency Code': 'USD',\n", + " '2. From_Currency Name': 'United States Dollar',\n", + " '3. To_Currency Code': 'JPY',\n", + " '4. To_Currency Name': 'Japanese Yen',\n", + " '5. Exchange Rate': '148.19900000',\n", + " '6. Last Refreshed': '2023-11-30 21:43:02',\n", + " '7. Time Zone': 'UTC',\n", + " '8. Bid Price': '148.19590000',\n", + " '9. Ask Price': '148.20420000'}}" + ] + }, + "execution_count": 3, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "alpha_vantage = AlphaVantageAPIWrapper()\n", + "alpha_vantage._get_exchange_rate(\"USD\", \"JPY\")" + ] + }, + { + "cell_type": "markdown", + "id": "8309d09d", + "metadata": {}, + "source": [ + "The `_get_time_series_daily` method returns the date, daily open, daily high, daily low, daily close, and daily volume of the global equity specified, covering the 100 latest data points." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "811ae207", + "metadata": {}, + "outputs": [], + "source": [ + "alpha_vantage._get_time_series_daily(\"IBM\")" + ] + }, + { + "cell_type": "markdown", + "id": "b5e46a71", + "metadata": {}, + "source": [ + "The `_get_time_series_weekly` method returns the last trading day of the week, weekly open, weekly high, weekly low, weekly close, and weekly volume of the global equity specified, covering 20+ years of historical data." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "f0dfe35b", + "metadata": {}, "outputs": [], "source": [ - "alpha_vantage = AlphaVantageAPIWrapper()" + "alpha_vantage._get_time_series_weekly(\"IBM\")" + ] + }, + { + "cell_type": "markdown", + "id": "66cc06a7", + "metadata": {}, + "source": [ + "The `_get_quote_endpoint` method is a lightweight alternative to the time series APIs and returns the latest price and volume info for the specified symbol." ] }, { "cell_type": "code", - "execution_count": 5, + "execution_count": 6, + "id": "98d012ef", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "{'Global Quote': {'01. symbol': 'IBM',\n", + " '02. open': '156.9000',\n", + " '03. high': '158.6000',\n", + " '04. low': '156.8900',\n", + " '05. price': '158.5400',\n", + " '06. volume': '6640217',\n", + " '07. latest trading day': '2023-11-30',\n", + " '08. previous close': '156.4100',\n", + " '09. change': '2.1300',\n", + " '10. change percent': '1.3618%'}}" + ] + }, + "execution_count": 6, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "alpha_vantage._get_quote_endpoint(\"IBM\")" + ] + }, + { + "cell_type": "markdown", + "id": "3429ce50", + "metadata": {}, + "source": [ + "The `search_symbol` method returns a list of symbols and the matching company information based on the text entered." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "0ccd55b0", + "metadata": {}, + "outputs": [], + "source": [ + "alpha_vantage.search_symbols(\"IB\")" + ] + }, + { + "cell_type": "markdown", + "id": "96e1fd97", + "metadata": {}, + "source": [ + "The `_get_market_news_sentiment` method returns live and historical market news sentiment for a given asset." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "42995acb", + "metadata": {}, + "outputs": [], + "source": [ + "alpha_vantage._get_market_news_sentiment(\"IBM\")" + ] + }, + { + "cell_type": "markdown", + "id": "2fdbd888", + "metadata": {}, + "source": [ + "The `_get_top_gainers_losers` method returns the top 20 gainers, losers and most active stocks in the US market." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "61c3cb1c", + "metadata": {}, + "outputs": [], + "source": [ + "alpha_vantage._get_top_gainers_losers()" + ] + }, + { + "cell_type": "markdown", + "id": "3d1cf3d8", + "metadata": {}, + "source": [ + "The `run` method of the wrapper takes the following parameters: from_currency, to_currency. \n", + "\n", + "It Gets the currency exchange rates for the given currency pair." + ] + }, + { + "cell_type": "code", + "execution_count": 9, "id": "068991a6", "metadata": { "id": "068991a6", @@ -77,14 +227,14 @@ " '2. From_Currency Name': 'United States Dollar',\n", " '3. To_Currency Code': 'JPY',\n", " '4. To_Currency Name': 'Japanese Yen',\n", - " '5. Exchange Rate': '144.93000000',\n", - " '6. Last Refreshed': '2023-08-11 21:31:01',\n", + " '5. Exchange Rate': '148.19900000',\n", + " '6. Last Refreshed': '2023-11-30 21:43:02',\n", " '7. Time Zone': 'UTC',\n", - " '8. Bid Price': '144.92600000',\n", - " '9. Ask Price': '144.93400000'}" + " '8. Bid Price': '148.19590000',\n", + " '9. Ask Price': '148.20420000'}" ] }, - "execution_count": 5, + "execution_count": 9, "metadata": {}, "output_type": "execute_result" } @@ -92,14 +242,6 @@ "source": [ "alpha_vantage.run(\"USD\", \"JPY\")" ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "84fc2b66-c08f-4cd3-ae13-494c54789c09", - "metadata": {}, - "outputs": [], - "source": [] } ], "metadata": { diff --git a/libs/community/langchain_community/utilities/alpha_vantage.py b/libs/community/langchain_community/utilities/alpha_vantage.py index db51abf96da92..926eec137d5f8 100644 --- a/libs/community/langchain_community/utilities/alpha_vantage.py +++ b/libs/community/langchain_community/utilities/alpha_vantage.py @@ -30,6 +30,117 @@ def validate_environment(cls, values: Dict) -> Dict: ) return values + def search_symbols(self, keywords: str) -> Dict[str, Any]: + """Make a request to the AlphaVantage API to search for symbols.""" + response = requests.get( + "https://www.alphavantage.co/query/", + params={ + "function": "SYMBOL_SEARCH", + "keywords": keywords, + "apikey": self.alphavantage_api_key, + }, + ) + response.raise_for_status() + data = response.json() + + if "Error Message" in data: + raise ValueError(f"API Error: {data['Error Message']}") + + return data + + def _get_market_news_sentiment(self, symbol: str) -> Dict[str, Any]: + """Make a request to the AlphaVantage API to get market news sentiment for a + given symbol.""" + response = requests.get( + "https://www.alphavantage.co/query/", + params={ + "function": "NEWS_SENTIMENT", + "symbol": symbol, + "apikey": self.alphavantage_api_key, + }, + ) + response.raise_for_status() + data = response.json() + + if "Error Message" in data: + raise ValueError(f"API Error: {data['Error Message']}") + + return data + + def _get_time_series_daily(self, symbol: str) -> Dict[str, Any]: + """Make a request to the AlphaVantage API to get the daily time series.""" + response = requests.get( + "https://www.alphavantage.co/query/", + params={ + "function": "TIME_SERIES_DAILY", + "symbol": symbol, + "apikey": self.alphavantage_api_key, + }, + ) + response.raise_for_status() + data = response.json() + + if "Error Message" in data: + raise ValueError(f"API Error: {data['Error Message']}") + + return data + + def _get_quote_endpoint(self, symbol: str) -> Dict[str, Any]: + """Make a request to the AlphaVantage API to get the + latest price and volume information.""" + response = requests.get( + "https://www.alphavantage.co/query/", + params={ + "function": "GLOBAL_QUOTE", + "symbol": symbol, + "apikey": self.alphavantage_api_key, + }, + ) + response.raise_for_status() + data = response.json() + + if "Error Message" in data: + raise ValueError(f"API Error: {data['Error Message']}") + + return data + + def _get_time_series_weekly(self, symbol: str) -> Dict[str, Any]: + """Make a request to the AlphaVantage API + to get the Weekly Time Series.""" + response = requests.get( + "https://www.alphavantage.co/query/", + params={ + "function": "TIME_SERIES_WEEKLY", + "symbol": symbol, + "apikey": self.alphavantage_api_key, + }, + ) + response.raise_for_status() + data = response.json() + + if "Error Message" in data: + raise ValueError(f"API Error: {data['Error Message']}") + + return data + + def _get_top_gainers_losers(self) -> Dict[str, Any]: + """Make a request to the AlphaVantage API to get the top gainers, losers, + and most actively traded tickers in the US market.""" + response = requests.get( + "https://www.alphavantage.co/query/", + params={ + "function": "TOP_GAINERS_LOSERS", + "apikey": self.alphavantage_api_key, + }, + ) + response.raise_for_status() + data = response.json() + + if "Error Message" in data: + raise ValueError(f"API Error: {data['Error Message']}") + + return data + def _get_exchange_rate( self, from_currency: str, to_currency: str ) -> Dict[str, Any]: diff --git a/libs/community/tests/integration_tests/utilities/test_alpha_vantage.py b/libs/community/tests/integration_tests/utilities/test_alpha_vantage.py new file mode 100644 index 0000000000000..69583a78a18bc --- /dev/null +++ b/libs/community/tests/integration_tests/utilities/test_alpha_vantage.py @@ -0,0 +1,66 @@ +"""Integration test for Alpha Vantage API Wrapper.""" +import pytest + +from langchain_community.utilities.alpha_vantage import AlphaVantageAPIWrapper + + +@pytest.fixture +def api_wrapper() -> AlphaVantageAPIWrapper: + # Ensure that the ALPHAVANTAGE_API_KEY environment variable is set + return AlphaVantageAPIWrapper() + + +def test_search_symbols(api_wrapper: AlphaVantageAPIWrapper) -> None: + """Test the search symbols API call for successful response.""" + response = api_wrapper.search_symbols("AAPL") + assert response is not None + assert isinstance(response, dict) + + +def test_market_news_sentiment(api_wrapper: AlphaVantageAPIWrapper) -> None: + """Test the market news sentiment API call for successful response.""" + response = api_wrapper._get_market_news_sentiment("AAPL") + assert response is not None + assert isinstance(response, dict) + + +def test_time_series_daily(api_wrapper: AlphaVantageAPIWrapper) -> None: + """Test the time series daily API call for successful response.""" + response = api_wrapper._get_time_series_daily("AAPL") + assert response is not None + assert isinstance(response, dict) + + +def test_quote_endpoint(api_wrapper: AlphaVantageAPIWrapper) -> None: + """Test the quote endpoint API call for successful response.""" + response = api_wrapper._get_quote_endpoint("AAPL") + assert response is not None + assert isinstance(response, dict) + + +def test_time_series_weekly(api_wrapper: AlphaVantageAPIWrapper) -> None: + """Test the time series weekly API call for successful response.""" + response = api_wrapper._get_time_series_weekly("AAPL") + assert response is not None + assert isinstance(response, dict) + + +def test_top_gainers_losers(api_wrapper: AlphaVantageAPIWrapper) -> None: + """Test the top gainers and losers API call for successful response.""" + response = api_wrapper._get_top_gainers_losers() + assert response is not None + assert isinstance(response, dict) + + +def test_exchange_rate(api_wrapper: AlphaVantageAPIWrapper) -> None: + """Test the exchange rate API call for successful response.""" + response = api_wrapper._get_exchange_rate("USD", "EUR") + assert response is not None + assert isinstance(response, dict) + + +def test_run_method(api_wrapper: AlphaVantageAPIWrapper) -> None: + """Test the run method for successful response.""" + response = api_wrapper.run("USD", "EUR") + assert response is not None + assert isinstance(response, dict)