mirror of
https://github.com/hwchase17/langchain.git
synced 2025-06-25 16:13:25 +00:00
Mehdi zare/fmp data doc (#29219)
Title: community: add Financial Modeling Prep (FMP) API integration Description: Adding LangChain integration for Financial Modeling Prep (FMP) API to enable semantic search and structured tool creation for financial data endpoints. This integration provides semantic endpoint search using vector stores and automatic tool creation with proper typing and error handling. Users can discover relevant financial endpoints using natural language queries and get properly typed LangChain tools for discovered endpoints. Issue: N/A Dependencies: fmp-data>=0.3.1 langchain-core>=0.1.0 faiss-cpu tiktoken Twitter handle: @mehdizarem Unit tests and example notebook have been added: Tests are in tests/integration_tests/est_tools.py and tests/unit_tests/test_tools.py Example notebook is in docs/tools.ipynb All format, lint and test checks pass: pytest mypy . Dependencies are imported within functions and not added to pyproject.toml. The changes are backwards compatible and only affect the community package. --------- Co-authored-by: mehdizare <mehdizare@users.noreply.github.com> Co-authored-by: Chester Curme <chester.curme@gmail.com>
This commit is contained in:
parent
288613d361
commit
1a38948ee3
21
docs/docs/integrations/providers/fmp-data.mdx
Normal file
21
docs/docs/integrations/providers/fmp-data.mdx
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
# FMP Data (Financial Data Prep)
|
||||||
|
|
||||||
|
> [FMP-Data](https://pypi.org/project/fmp-data/) is a python package for connecting to
|
||||||
|
> Financial Data Prep API. It simplifies how you can access production quality data.
|
||||||
|
|
||||||
|
|
||||||
|
## Installation and Setup
|
||||||
|
|
||||||
|
Get an `FMP Data` API key by
|
||||||
|
visiting [this page](https://site.financialmodelingprep.com/pricing-plans?couponCode=mehdi).
|
||||||
|
and set it as an environment variable (`FMP_API_KEY`).
|
||||||
|
|
||||||
|
Then, install [langchain-fmp-data](https://pypi.org/project/langchain-fmp-data/).
|
||||||
|
|
||||||
|
## Tools
|
||||||
|
|
||||||
|
See an [example](https://github.com/MehdiZare/langchain-fmp-data/tree/main/docs).
|
||||||
|
|
||||||
|
```python
|
||||||
|
from langchain_fmp_data import FMPDataTool, FMPDataToolkit
|
||||||
|
```
|
412
docs/docs/integrations/tools/fmp-data.ipynb
Normal file
412
docs/docs/integrations/tools/fmp-data.ipynb
Normal file
@ -0,0 +1,412 @@
|
|||||||
|
{
|
||||||
|
"cells": [
|
||||||
|
{
|
||||||
|
"cell_type": "markdown",
|
||||||
|
"id": "62828c19159a0da8",
|
||||||
|
"metadata": {},
|
||||||
|
"source": [
|
||||||
|
"# FMP Data\n",
|
||||||
|
"\n",
|
||||||
|
"Access financial market data through natural language queries.\n",
|
||||||
|
"\n",
|
||||||
|
"## Overview\n",
|
||||||
|
"\n",
|
||||||
|
"The FMP (Financial Modeling Prep) LangChain integration provides a seamless way to access financial market data through natural language queries. This integration offers two main components:\n",
|
||||||
|
"\n",
|
||||||
|
"- `FMPDataToolkit`: Creates collections of tools based on natural language queries\n",
|
||||||
|
"- `FMPDataTool`: A single unified tool that automatically selects and uses the appropriate endpoints\n",
|
||||||
|
"\n",
|
||||||
|
"The integration leverages LangChain's semantic search capabilities to match user queries with the most relevant FMP API endpoints, making financial data access more intuitive and efficient.\n",
|
||||||
|
"## Setup"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "code",
|
||||||
|
"execution_count": null,
|
||||||
|
"id": "3faf15d8ae5f8500",
|
||||||
|
"metadata": {},
|
||||||
|
"outputs": [],
|
||||||
|
"source": [
|
||||||
|
"!pip install -U langchain-fmp-data"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "code",
|
||||||
|
"execution_count": null,
|
||||||
|
"id": "647f66796446eb0f",
|
||||||
|
"metadata": {},
|
||||||
|
"outputs": [],
|
||||||
|
"source": [
|
||||||
|
"import os\n",
|
||||||
|
"\n",
|
||||||
|
"# Replace with your actual API keys\n",
|
||||||
|
"os.environ[\"FMP_API_KEY\"] = \"your-fmp-api-key\" # pragma: allowlist secret\n",
|
||||||
|
"os.environ[\"OPENAI_API_KEY\"] = \"your-openai-api-key\" # pragma: allowlist secret"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "markdown",
|
||||||
|
"id": "b5de291f5c2f67a2",
|
||||||
|
"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": "eb86baf3da526812",
|
||||||
|
"metadata": {},
|
||||||
|
"outputs": [],
|
||||||
|
"source": [
|
||||||
|
"# os.environ[\"LANGCHAIN_TRACING_V2\"] = \"true\"\n",
|
||||||
|
"# os.environ[\"LANGCHAIN_API_KEY\"] = getpass.getpass()"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "markdown",
|
||||||
|
"id": "d4d6a4b9ac69569f",
|
||||||
|
"metadata": {},
|
||||||
|
"source": [
|
||||||
|
"## Instantiation\n",
|
||||||
|
"There are two main ways to instantiate the FMP LangChain integration:\n",
|
||||||
|
"1. Using FMPDataToolkit"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "code",
|
||||||
|
"execution_count": null,
|
||||||
|
"id": "ff5f451182995407",
|
||||||
|
"metadata": {},
|
||||||
|
"outputs": [],
|
||||||
|
"source": [
|
||||||
|
"from langchain_fmp_data import FMPDataToolkit\n",
|
||||||
|
"\n",
|
||||||
|
"query = \"Get stock market prices and technical indicators\"\n",
|
||||||
|
"# Basic instantiation\n",
|
||||||
|
"toolkit = FMPDataToolkit(query=query)\n",
|
||||||
|
"\n",
|
||||||
|
"# Instantiation with specific query focus\n",
|
||||||
|
"market_toolkit = FMPDataToolkit(\n",
|
||||||
|
" query=query,\n",
|
||||||
|
" num_results=5,\n",
|
||||||
|
")\n",
|
||||||
|
"\n",
|
||||||
|
"# Instantiation with custom configuration\n",
|
||||||
|
"custom_toolkit = FMPDataToolkit(\n",
|
||||||
|
" query=\"Financial analysis\",\n",
|
||||||
|
" num_results=3,\n",
|
||||||
|
" similarity_threshold=0.4,\n",
|
||||||
|
" cache_dir=\"/custom/cache/path\",\n",
|
||||||
|
")"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "markdown",
|
||||||
|
"id": "8cd16450e03ea000",
|
||||||
|
"metadata": {},
|
||||||
|
"source": [
|
||||||
|
"2. Using FMPDataTool"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "code",
|
||||||
|
"execution_count": null,
|
||||||
|
"id": "c924dd0e34b3db9",
|
||||||
|
"metadata": {},
|
||||||
|
"outputs": [],
|
||||||
|
"source": [
|
||||||
|
"from langchain_fmp_data import FMPDataTool\n",
|
||||||
|
"from langchain_fmp_data.tools import ResponseFormat\n",
|
||||||
|
"\n",
|
||||||
|
"# Basic instantiation\n",
|
||||||
|
"tool = FMPDataTool()\n",
|
||||||
|
"\n",
|
||||||
|
"# Advanced instantiation with custom settings\n",
|
||||||
|
"advanced_tool = FMPDataTool(\n",
|
||||||
|
" max_iterations=50,\n",
|
||||||
|
" temperature=0.2,\n",
|
||||||
|
")"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "markdown",
|
||||||
|
"id": "499dde5c011b44b6",
|
||||||
|
"metadata": {},
|
||||||
|
"source": [
|
||||||
|
"## Invocation\n",
|
||||||
|
"The tools can be invoked in several ways:\n",
|
||||||
|
"\n",
|
||||||
|
"### Direct Invocation"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "code",
|
||||||
|
"execution_count": null,
|
||||||
|
"id": "d2fc685c536bdc54",
|
||||||
|
"metadata": {},
|
||||||
|
"outputs": [],
|
||||||
|
"source": [
|
||||||
|
"# Using FMPDataTool\n",
|
||||||
|
"tool_direct = FMPDataTool()\n",
|
||||||
|
"\n",
|
||||||
|
"# Basic query\n",
|
||||||
|
"# fmt: off\n",
|
||||||
|
"result = tool.invoke({\"query\": \"What's Apple's current stock price?\"})\n",
|
||||||
|
"# fmt: on\n",
|
||||||
|
"\n",
|
||||||
|
"# Advanced query with specific format\n",
|
||||||
|
"# fmt: off\n",
|
||||||
|
"detailed_result = tool_direct.invoke(\n",
|
||||||
|
" {\n",
|
||||||
|
" \"query\": \"Compare Tesla and Ford's profit margins\",\n",
|
||||||
|
" \"response_format\": ResponseFormat.BOTH,\n",
|
||||||
|
" }\n",
|
||||||
|
")\n",
|
||||||
|
"# fmt: on"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "markdown",
|
||||||
|
"id": "3735e50bdeb55c4",
|
||||||
|
"metadata": {},
|
||||||
|
"source": [
|
||||||
|
"### Using with LangChain Agents"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "code",
|
||||||
|
"execution_count": null,
|
||||||
|
"id": "73b3684edd3ddbce",
|
||||||
|
"metadata": {},
|
||||||
|
"outputs": [],
|
||||||
|
"source": [
|
||||||
|
"from langchain.agents import AgentExecutor, create_openai_functions_agent\n",
|
||||||
|
"from langchain_openai import ChatOpenAI\n",
|
||||||
|
"\n",
|
||||||
|
"# Setup\n",
|
||||||
|
"llm = ChatOpenAI(temperature=0)\n",
|
||||||
|
"toolkit = FMPDataToolkit(\n",
|
||||||
|
" query=\"Stock analysis\",\n",
|
||||||
|
" num_results=3,\n",
|
||||||
|
")\n",
|
||||||
|
"tools = toolkit.get_tools()\n",
|
||||||
|
"\n",
|
||||||
|
"# Create agent\n",
|
||||||
|
"prompt = \"You are a helpful assistant. Answer the user's questions based on the provided context.\"\n",
|
||||||
|
"agent = create_openai_functions_agent(llm, tools, prompt)\n",
|
||||||
|
"agent_executor = AgentExecutor(\n",
|
||||||
|
" agent=agent,\n",
|
||||||
|
" tools=tools,\n",
|
||||||
|
")\n",
|
||||||
|
"\n",
|
||||||
|
"# Run query\n",
|
||||||
|
"# fmt: off\n",
|
||||||
|
"response = agent_executor.invoke({\"input\": \"What's the PE ratio of Microsoft?\"})\n",
|
||||||
|
"# fmt: on"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "markdown",
|
||||||
|
"id": "73654bed2bd79c50",
|
||||||
|
"metadata": {},
|
||||||
|
"source": [
|
||||||
|
"## Advanced Usage\n",
|
||||||
|
"You can customize the tool's behavior:\n",
|
||||||
|
"\n"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "code",
|
||||||
|
"execution_count": null,
|
||||||
|
"id": "20fa3c2ed5204299",
|
||||||
|
"metadata": {},
|
||||||
|
"outputs": [],
|
||||||
|
"source": [
|
||||||
|
"# Initialize with custom settings\n",
|
||||||
|
"advanced_tool = FMPDataTool(\n",
|
||||||
|
" max_iterations=50, # Increase max iterations for complex queries\n",
|
||||||
|
" temperature=0.2, # Adjust temperature for more/less focused responses\n",
|
||||||
|
")\n",
|
||||||
|
"\n",
|
||||||
|
"# Example of a complex multi-part analysis\n",
|
||||||
|
"query = \"\"\"\n",
|
||||||
|
"Analyze Apple's financial health by:\n",
|
||||||
|
"1. Examining current ratios and debt levels\n",
|
||||||
|
"2. Comparing profit margins to industry average\n",
|
||||||
|
"3. Looking at cash flow trends\n",
|
||||||
|
"4. Assessing growth metrics\n",
|
||||||
|
"\"\"\"\n",
|
||||||
|
"# fmt: off\n",
|
||||||
|
"response = advanced_tool.invoke(\n",
|
||||||
|
" {\n",
|
||||||
|
" \"query\": query,\n",
|
||||||
|
" \"response_format\": ResponseFormat.BOTH}\n",
|
||||||
|
")\n",
|
||||||
|
"# fmt: on\n",
|
||||||
|
"print(\"Detailed Financial Analysis:\")\n",
|
||||||
|
"print(response)"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "markdown",
|
||||||
|
"id": "f2d5e31becc88d70",
|
||||||
|
"metadata": {},
|
||||||
|
"source": [
|
||||||
|
"## Chaining\n",
|
||||||
|
"You can chain the tool similar to other tools simply by creating a chain with desired model."
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "code",
|
||||||
|
"execution_count": null,
|
||||||
|
"id": "ad1d8e8575c7bc7",
|
||||||
|
"metadata": {},
|
||||||
|
"outputs": [],
|
||||||
|
"source": [
|
||||||
|
"from langchain_core.output_parsers import StrOutputParser\n",
|
||||||
|
"from langchain_openai import ChatOpenAI\n",
|
||||||
|
"\n",
|
||||||
|
"# Setup\n",
|
||||||
|
"llm = ChatOpenAI(temperature=0)\n",
|
||||||
|
"toolkit = FMPDataToolkit(query=\"Stock analysis\", num_results=3)\n",
|
||||||
|
"tools = toolkit.get_tools()\n",
|
||||||
|
"\n",
|
||||||
|
"llm_with_tools = llm.bind(functions=tools)\n",
|
||||||
|
"output_parser = StrOutputParser()\n",
|
||||||
|
"# Create chain\n",
|
||||||
|
"runner = llm_with_tools | output_parser\n",
|
||||||
|
"\n",
|
||||||
|
"# Run chain\n",
|
||||||
|
"# fmt: off\n",
|
||||||
|
"response = runner.invoke(\n",
|
||||||
|
" {\n",
|
||||||
|
" \"input\": \"What's the PE ratio of Microsoft?\"\n",
|
||||||
|
" }\n",
|
||||||
|
")\n",
|
||||||
|
"# fmt: on"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "markdown",
|
||||||
|
"id": "2fe9b99e6bd5d3bb",
|
||||||
|
"metadata": {},
|
||||||
|
"source": [
|
||||||
|
"## API reference\n",
|
||||||
|
"\n",
|
||||||
|
"### FMPDataToolkit\n",
|
||||||
|
"Main class for creating collections of FMP API tools:"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "code",
|
||||||
|
"execution_count": null,
|
||||||
|
"id": "dd71cf7dda4e1579",
|
||||||
|
"metadata": {},
|
||||||
|
"outputs": [],
|
||||||
|
"source": [
|
||||||
|
"from typing import Any\n",
|
||||||
|
"\n",
|
||||||
|
"from langchain.tools import Tool\n",
|
||||||
|
"\n",
|
||||||
|
"\n",
|
||||||
|
"class FMPDataToolkit:\n",
|
||||||
|
" \"\"\"Creates a collection of FMP data tools based on queries.\"\"\"\n",
|
||||||
|
"\n",
|
||||||
|
" def __init__(\n",
|
||||||
|
" self,\n",
|
||||||
|
" query: str | None = None,\n",
|
||||||
|
" num_results: int = 3,\n",
|
||||||
|
" similarity_threshold: float = 0.3,\n",
|
||||||
|
" cache_dir: str | None = None,\n",
|
||||||
|
" ): ...\n",
|
||||||
|
"\n",
|
||||||
|
" def get_tools(self) -> list[Tool]:\n",
|
||||||
|
" \"\"\"Returns a list of relevant FMP API tools based on the query.\"\"\"\n",
|
||||||
|
" ..."
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "markdown",
|
||||||
|
"id": "8fe43c9a7cf7216c",
|
||||||
|
"metadata": {},
|
||||||
|
"source": [
|
||||||
|
"### FMPDataTool\n",
|
||||||
|
"Unified tool that automatically selects appropriate FMP endpoints:"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "code",
|
||||||
|
"execution_count": null,
|
||||||
|
"id": "5fbd891b3798e529",
|
||||||
|
"metadata": {},
|
||||||
|
"outputs": [],
|
||||||
|
"source": [
|
||||||
|
"# fmt: off\n",
|
||||||
|
"class FMPDataTool:\n",
|
||||||
|
" \"\"\"Single unified tool for accessing FMP data through natural language.\"\"\"\n",
|
||||||
|
"\n",
|
||||||
|
" def __init__(\n",
|
||||||
|
" self,\n",
|
||||||
|
" max_iterations: int = 3,\n",
|
||||||
|
" temperature: float = 0.0,\n",
|
||||||
|
" ): ...\n",
|
||||||
|
"\n",
|
||||||
|
" def invoke(\n",
|
||||||
|
" self,\n",
|
||||||
|
" input: dict[str, Any],\n",
|
||||||
|
" ) -> str | dict[str, Any]:\n",
|
||||||
|
" \"\"\"Execute a natural language query against FMP API.\"\"\"\n",
|
||||||
|
" ...\n",
|
||||||
|
"\n",
|
||||||
|
"# fmt: on"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "markdown",
|
||||||
|
"id": "6b336afd0cdf2bd5",
|
||||||
|
"metadata": {},
|
||||||
|
"source": [
|
||||||
|
"### ResponseFormat\n",
|
||||||
|
"Enum for controlling response format:"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "code",
|
||||||
|
"execution_count": null,
|
||||||
|
"id": "eb57dbcb88d8d118",
|
||||||
|
"metadata": {},
|
||||||
|
"outputs": [],
|
||||||
|
"source": [
|
||||||
|
"from enum import Enum\n",
|
||||||
|
"\n",
|
||||||
|
"\n",
|
||||||
|
"class ResponseFormat(str, Enum):\n",
|
||||||
|
" RAW = \"raw\" # Raw API response\n",
|
||||||
|
" ANALYSIS = \"text\" # Natural language analysis\n",
|
||||||
|
" BOTH = \"both\" # Both raw data and analysis"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"metadata": {
|
||||||
|
"kernelspec": {
|
||||||
|
"display_name": "Python 3",
|
||||||
|
"language": "python",
|
||||||
|
"name": "python3"
|
||||||
|
},
|
||||||
|
"language_info": {
|
||||||
|
"codemirror_mode": {
|
||||||
|
"name": "ipython",
|
||||||
|
"version": 2
|
||||||
|
},
|
||||||
|
"file_extension": ".py",
|
||||||
|
"mimetype": "text/x-python",
|
||||||
|
"name": "python",
|
||||||
|
"nbconvert_exporter": "python",
|
||||||
|
"pygments_lexer": "ipython2",
|
||||||
|
"version": "2.7.6"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"nbformat": 4,
|
||||||
|
"nbformat_minor": 5
|
||||||
|
}
|
@ -342,3 +342,7 @@ packages:
|
|||||||
path: .
|
path: .
|
||||||
repo: hyperbrowserai/langchain-hyperbrowser
|
repo: hyperbrowserai/langchain-hyperbrowser
|
||||||
downloads: 0
|
downloads: 0
|
||||||
|
- name: langchain-fmp-data
|
||||||
|
path: .
|
||||||
|
repo: MehdiZare/langchain-fmp-data
|
||||||
|
downloads: 0
|
||||||
|
Loading…
Reference in New Issue
Block a user