community: Add PolygonLastQuote Tool and Toolkit (#15990)

**Description:** 
In this PR, I am adding a `PolygonLastQuote` Tool, which can be used to
get the latest price quote for a given ticker / stock.

Additionally, I've added a Polygon Toolkit, which we can use to
encapsulate future tools that we build for Polygon.

**Twitter handle:** [@virattt](https://twitter.com/virattt)

---------

Co-authored-by: Harrison Chase <hw.chase.17@gmail.com>
pull/13389/head
Virat Singh 5 months ago committed by GitHub
parent ef75bb63ce
commit c2a614eddc
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

@ -294,7 +294,7 @@
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.11.1"
"version": "3.10.1"
}
},
"nbformat": 4,

@ -0,0 +1,187 @@
{
"cells": [
{
"cell_type": "markdown",
"id": "e6fd05db-21c2-4227-9900-0840bc62cb31",
"metadata": {},
"source": [
"# Polygon IO Toolkit\n",
"\n",
"This notebook shows how to use agents to interact with the [Polygon IO](https://polygon.io/) toolkit. The toolkit provides access to Polygon's Stock Market Data API."
]
},
{
"cell_type": "markdown",
"id": "a4da342d",
"metadata": {},
"source": [
"## Example Use\n",
"\n",
"\n",
"### Setup"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "c17b33e0",
"metadata": {},
"outputs": [],
"source": [
"%pip install --upgrade --quiet langchain-community > /dev/null"
]
},
{
"cell_type": "markdown",
"id": "3cd00ad2",
"metadata": {},
"source": [
"Get your Polygon IO API key [here](https://polygon.io/), and then set it below.\n",
"Note that the tool used in this example requires a \"Stocks Advanced\" subscription"
]
},
{
"cell_type": "code",
"execution_count": 6,
"id": "a180a2b8",
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"········\n"
]
}
],
"source": [
"import getpass\n",
"import os\n",
"\n",
"os.environ[\"POLYGON_API_KEY\"] = getpass.getpass()"
]
},
{
"cell_type": "markdown",
"id": "ed6f89fa",
"metadata": {},
"source": [
"It's also helpful (but not needed) to set up [LangSmith](https://smith.langchain.com/) for best-in-class observability"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "56670cf6",
"metadata": {},
"outputs": [],
"source": [
"# os.environ[\"LANGCHAIN_TRACING_V2\"] = \"true\"\n",
"# os.environ[\"LANGCHAIN_API_KEY\"] = getpass.getpass()"
]
},
{
"cell_type": "markdown",
"id": "7d93e6bd-03d7-4d3c-b915-8b73164e2ad8",
"metadata": {},
"source": [
"### Initializing the agent"
]
},
{
"cell_type": "code",
"execution_count": 7,
"id": "648a2cb2-308e-4b2e-9b73-37109be4e258",
"metadata": {
"is_executing": true
},
"outputs": [],
"source": [
"from langchain import hub\n",
"from langchain.agents import AgentExecutor, create_openai_functions_agent\n",
"from langchain_community.agent_toolkits.polygon.toolkit import PolygonToolkit\n",
"from langchain_community.utilities.polygon import PolygonAPIWrapper\n",
"from langchain_openai import ChatOpenAI\n",
"\n",
"llm = ChatOpenAI(temperature=0)\n",
"\n",
"instructions = \"\"\"You are an assistant.\"\"\"\n",
"base_prompt = hub.pull(\"langchain-ai/openai-functions-template\")\n",
"prompt = base_prompt.partial(instructions=instructions)"
]
},
{
"cell_type": "code",
"execution_count": 8,
"id": "18650040-0ff8-4c0f-a4f2-be6aad7fe63e",
"metadata": {},
"outputs": [],
"source": [
"polygon = PolygonAPIWrapper()\n",
"toolkit = PolygonToolkit.from_polygon_api_wrapper(polygon)\n",
"agent = create_openai_functions_agent(llm, toolkit.get_tools(), prompt)"
]
},
{
"cell_type": "code",
"execution_count": 11,
"id": "fd7463e4-8716-4d1d-860a-770533eaa742",
"metadata": {},
"outputs": [],
"source": [
"agent_executor = AgentExecutor(\n",
" agent=agent,\n",
" tools=toolkit.get_tools(),\n",
" verbose=True,\n",
")"
]
},
{
"cell_type": "markdown",
"id": "71f05fc9-d80d-4614-b9a3-e0a5e43cbbbb",
"metadata": {},
"source": [
"### Get the last price quote for a stock"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "b97409f3-dc87-425d-b555-406cf8466a28",
"metadata": {},
"outputs": [],
"source": [
"agent_executor.invoke({\"input\": \"What is the latest stock price for AAPL?\"})"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "9e666ee1",
"metadata": {},
"outputs": [],
"source": []
}
],
"metadata": {
"kernelspec": {
"display_name": "Python 3 (ipykernel)",
"language": "python",
"name": "python3"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.10.1"
}
},
"nbformat": 4,
"nbformat_minor": 5
}

@ -40,6 +40,7 @@
},
"outputs": [],
"source": [
"from langchain_community.tools.polygon.last_quote import PolygonLastQuote\n",
"from langchain_community.utilities.polygon import PolygonAPIWrapper"
]
},
@ -52,7 +53,7 @@
},
"outputs": [],
"source": [
"polygon = PolygonAPIWrapper()"
"tool = PolygonLastQuote(api_wrapper=PolygonAPIWrapper())"
]
},
{
@ -63,20 +64,20 @@
"id": "068991a6",
"outputId": "c5cdc6ec-03cf-4084-cc6f-6ae792d91d39"
},
"outputs": [
{
"data": {
"text/plain": [
"{'results': {'P': 185.86, 'S': 1, 'T': 'AAPL', 'X': 11, 'i': [604], 'p': 185.81, 'q': 106551669, 's': 2, 't': 1705098436014023700, 'x': 12, 'y': 1705098436014009300, 'z': 3}}"
]
},
"execution_count": 1,
"metadata": {},
"output_type": "execute_result"
}
],
"outputs": [
{
"data": {
"text/plain": [
"{'results': {'P': 185.86, 'S': 1, 'T': 'AAPL', 'X': 11, 'i': [604], 'p': 185.81, 'q': 106551669, 's': 2, 't': 1705098436014023700, 'x': 12, 'y': 1705098436014009300, 'z': 3}}"
]
},
"execution_count": 1,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"polygon.run(\"get_last_quote\", \"AAPL\")"
"tool.run(\"AAPL\")"
]
}
],

@ -34,6 +34,7 @@ from langchain_community.agent_toolkits.openapi.toolkit import OpenAPIToolkit
from langchain_community.agent_toolkits.playwright.toolkit import (
PlayWrightBrowserToolkit,
)
from langchain_community.agent_toolkits.polygon.toolkit import PolygonToolkit
from langchain_community.agent_toolkits.powerbi.base import create_pbi_agent
from langchain_community.agent_toolkits.powerbi.chat_base import create_pbi_chat_agent
from langchain_community.agent_toolkits.powerbi.toolkit import PowerBIToolkit
@ -59,6 +60,7 @@ __all__ = [
"O365Toolkit",
"OpenAPIToolkit",
"PlayWrightBrowserToolkit",
"PolygonToolkit",
"PowerBIToolkit",
"SlackToolkit",
"SteamToolkit",

@ -0,0 +1,27 @@
from typing import List
from langchain_community.agent_toolkits.base import BaseToolkit
from langchain_community.tools import BaseTool
from langchain_community.tools.polygon import PolygonLastQuote
from langchain_community.utilities.polygon import PolygonAPIWrapper
class PolygonToolkit(BaseToolkit):
"""Polygon Toolkit."""
tools: List[BaseTool] = []
@classmethod
def from_polygon_api_wrapper(
cls, polygon_api_wrapper: PolygonAPIWrapper
) -> "PolygonToolkit":
tools = [
PolygonLastQuote(
api_wrapper=polygon_api_wrapper,
)
]
return cls(tools=tools)
def get_tools(self) -> List[BaseTool]:
"""Get the tools in the toolkit."""
return self.tools

@ -472,6 +472,12 @@ def _import_plugin() -> Any:
return AIPluginTool
def _import_polygon_tool_PolygonLastQuote() -> Any:
from langchain_community.tools.polygon.last_quote import PolygonLastQuote
return PolygonLastQuote
def _import_powerbi_tool_InfoPowerBITool() -> Any:
from langchain_community.tools.powerbi.tool import InfoPowerBITool
@ -907,6 +913,8 @@ def __getattr__(name: str) -> Any:
return _import_playwright_NavigateTool()
elif name == "AIPluginTool":
return _import_plugin()
elif name == "PolygonLastQuote":
return _import_polygon_tool_PolygonLastQuote()
elif name == "InfoPowerBITool":
return _import_powerbi_tool_InfoPowerBITool()
elif name == "ListPowerBITool":
@ -1085,6 +1093,7 @@ __all__ = [
"OpenAPISpec",
"OpenWeatherMapQueryRun",
"PubmedQueryRun",
"PolygonLastQuote",
"RedditSearchRun",
"QueryCheckerTool",
"QueryPowerBITool",

@ -0,0 +1,7 @@
"""Polygon IO tools."""
from langchain_community.tools.polygon.last_quote import PolygonLastQuote
__all__ = [
"PolygonLastQuote",
]

@ -0,0 +1,34 @@
from typing import Optional, Type
from langchain_core.callbacks import CallbackManagerForToolRun
from langchain_core.pydantic_v1 import BaseModel
from langchain_core.tools import BaseTool
from langchain_community.utilities.polygon import PolygonAPIWrapper
class Inputs(BaseModel):
query: str
class PolygonLastQuote(BaseTool):
"""Tool that gets the last quote of a ticker from Polygon"""
mode: str = "get_last_quote"
name: str = "polygon_last_quote"
description: str = (
"A wrapper around Polygon's Last Quote API. "
"This tool is useful for fetching the latest price of a stock. "
"Input should be the ticker that you want to query the last price quote for."
)
args_schema: Type[BaseModel] = Inputs
api_wrapper: PolygonAPIWrapper
def _run(
self,
query: str,
run_manager: Optional[CallbackManagerForToolRun] = None,
) -> str:
"""Use the Polygon API tool."""
return self.api_wrapper.run(self.mode, ticker=query)

@ -14,6 +14,7 @@ EXPECTED_ALL = [
"O365Toolkit",
"OpenAPIToolkit",
"PlayWrightBrowserToolkit",
"PolygonToolkit",
"PowerBIToolkit",
"SlackToolkit",
"SteamToolkit",

@ -79,6 +79,7 @@ EXPECTED_ALL = [
"OpenAPISpec",
"OpenWeatherMapQueryRun",
"PubmedQueryRun",
"PolygonLastQuote",
"RedditSearchRun",
"QueryCheckerTool",
"QueryPowerBITool",

@ -81,6 +81,7 @@ _EXPECTED = [
"OpenAPISpec",
"OpenWeatherMapQueryRun",
"PubmedQueryRun",
"PolygonLastQuote",
"RedditSearchRun",
"QueryCheckerTool",
"QueryPowerBITool",

Loading…
Cancel
Save