fmp-data 0.0.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- fmp_data/__init__.py +138 -0
- fmp_data/alternative/__init__.py +34 -0
- fmp_data/alternative/client.py +150 -0
- fmp_data/alternative/endpoints.py +533 -0
- fmp_data/alternative/mapping.py +737 -0
- fmp_data/alternative/models.py +296 -0
- fmp_data/alternative/schema.py +165 -0
- fmp_data/base.py +316 -0
- fmp_data/client.py +269 -0
- fmp_data/company/__init__.py +40 -0
- fmp_data/company/client.py +238 -0
- fmp_data/company/endpoints.py +711 -0
- fmp_data/company/hints.py +77 -0
- fmp_data/company/mapping.py +1361 -0
- fmp_data/company/models.py +543 -0
- fmp_data/company/schema.py +132 -0
- fmp_data/config.py +207 -0
- fmp_data/economics/__init__.py +16 -0
- fmp_data/economics/client.py +52 -0
- fmp_data/economics/endpoints.py +164 -0
- fmp_data/economics/mapping.py +641 -0
- fmp_data/economics/models.py +75 -0
- fmp_data/economics/schema.py +91 -0
- fmp_data/exceptions.py +54 -0
- fmp_data/fundamental/__init__.py +40 -0
- fmp_data/fundamental/client.py +87 -0
- fmp_data/fundamental/endpoints.py +403 -0
- fmp_data/fundamental/mapping.py +867 -0
- fmp_data/fundamental/models.py +913 -0
- fmp_data/fundamental/schema.py +40 -0
- fmp_data/institutional/__init__.py +26 -0
- fmp_data/institutional/client.py +141 -0
- fmp_data/institutional/endpoints.py +321 -0
- fmp_data/institutional/mapping.py +749 -0
- fmp_data/institutional/models.py +301 -0
- fmp_data/institutional/schema.py +99 -0
- fmp_data/intelligence/__init__.py +58 -0
- fmp_data/intelligence/client.py +331 -0
- fmp_data/intelligence/endpoints.py +788 -0
- fmp_data/intelligence/mapping.py +1677 -0
- fmp_data/intelligence/models.py +707 -0
- fmp_data/intelligence/schema.py +57 -0
- fmp_data/investment/__init__.py +24 -0
- fmp_data/investment/client.py +104 -0
- fmp_data/investment/endpoints.py +241 -0
- fmp_data/investment/mapping.py +658 -0
- fmp_data/investment/models.py +220 -0
- fmp_data/investment/schema.py +106 -0
- fmp_data/lc/__init__.py +256 -0
- fmp_data/lc/config.py +88 -0
- fmp_data/lc/embedding.py +140 -0
- fmp_data/lc/hints.py +66 -0
- fmp_data/lc/mapping.py +107 -0
- fmp_data/lc/models.py +98 -0
- fmp_data/lc/registry.py +693 -0
- fmp_data/lc/utils.py +35 -0
- fmp_data/lc/validation.py +267 -0
- fmp_data/lc/vector_store.py +592 -0
- fmp_data/logger.py +358 -0
- fmp_data/market/__init__.py +18 -0
- fmp_data/market/client.py +106 -0
- fmp_data/market/endpoints.py +358 -0
- fmp_data/market/hints.py +22 -0
- fmp_data/market/mapping.py +854 -0
- fmp_data/market/models.py +310 -0
- fmp_data/market/schema.py +186 -0
- fmp_data/mcp/__init__.py +0 -0
- fmp_data/mcp/server.py +101 -0
- fmp_data/mcp/tool_loader.py +74 -0
- fmp_data/mcp/tools_manifest.py +17 -0
- fmp_data/models.py +265 -0
- fmp_data/rate_limit.py +136 -0
- fmp_data/schema.py +158 -0
- fmp_data/technical/__init__.py +28 -0
- fmp_data/technical/client.py +214 -0
- fmp_data/technical/endpoints.py +102 -0
- fmp_data/technical/mapping.py +452 -0
- fmp_data/technical/models.py +87 -0
- fmp_data/technical/schema.py +261 -0
- fmp_data-0.0.0.dist-info/METADATA +732 -0
- fmp_data-0.0.0.dist-info/RECORD +84 -0
- fmp_data-0.0.0.dist-info/WHEEL +4 -0
- fmp_data-0.0.0.dist-info/entry_points.txt +10 -0
- fmp_data-0.0.0.dist-info/licenses/LICENSE +21 -0
|
@@ -0,0 +1,732 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: fmp-data
|
|
3
|
+
Version: 0.0.0
|
|
4
|
+
Summary: Python client for the Financial Modeling Prep API
|
|
5
|
+
Project-URL: Homepage, https://github.com/MehdiZare/fmp-data
|
|
6
|
+
Project-URL: Documentation, https://github.com/MehdiZare/fmp-data#readme
|
|
7
|
+
Project-URL: Source, https://github.com/MehdiZare/fmp-data
|
|
8
|
+
Project-URL: Issues, https://github.com/MehdiZare/fmp-data/issues
|
|
9
|
+
Author-email: Mehdi Zare <mehdizare@users.noreply.github.com>
|
|
10
|
+
Maintainer-email: Mehdi Zare <mehdizare@users.noreply.github.com>
|
|
11
|
+
License-Expression: MIT
|
|
12
|
+
License-File: LICENSE
|
|
13
|
+
Keywords: api,financial,financial data,fmp,market-data,stock market,stocks
|
|
14
|
+
Classifier: Development Status :: 4 - Beta
|
|
15
|
+
Classifier: Framework :: AsyncIO
|
|
16
|
+
Classifier: Intended Audience :: Developers
|
|
17
|
+
Classifier: Intended Audience :: Financial and Insurance Industry
|
|
18
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
19
|
+
Classifier: Operating System :: OS Independent
|
|
20
|
+
Classifier: Programming Language :: Python :: 3
|
|
21
|
+
Classifier: Programming Language :: Python :: 3 :: Only
|
|
22
|
+
Requires-Python: <4.0,>=3.10
|
|
23
|
+
Requires-Dist: cachetools>=6.1.0
|
|
24
|
+
Requires-Dist: httpx>=0.28.1
|
|
25
|
+
Requires-Dist: pandas<3.0.0,>=2.3.0
|
|
26
|
+
Requires-Dist: pydantic-settings>=2.6.0
|
|
27
|
+
Requires-Dist: pydantic<3.0.0,>=2.11.7
|
|
28
|
+
Requires-Dist: python-dotenv<2.0.0,>=1.1.1
|
|
29
|
+
Requires-Dist: structlog>=25.4.0
|
|
30
|
+
Requires-Dist: tenacity>=9.0.0
|
|
31
|
+
Requires-Dist: tqdm>=4.66.5
|
|
32
|
+
Provides-Extra: langchain
|
|
33
|
+
Requires-Dist: faiss-cpu>=1.11.0; extra == 'langchain'
|
|
34
|
+
Requires-Dist: langchain-community>=0.3.26; extra == 'langchain'
|
|
35
|
+
Requires-Dist: langchain-core>=0.3.66; extra == 'langchain'
|
|
36
|
+
Requires-Dist: langchain-openai>=0.3.25; extra == 'langchain'
|
|
37
|
+
Requires-Dist: langgraph>=0.4.10; extra == 'langchain'
|
|
38
|
+
Requires-Dist: openai>=1.92.0; extra == 'langchain'
|
|
39
|
+
Requires-Dist: tiktoken>=0.9.0; extra == 'langchain'
|
|
40
|
+
Provides-Extra: mcp-server
|
|
41
|
+
Requires-Dist: mcp[cli]>=1.0.0; extra == 'mcp-server'
|
|
42
|
+
Requires-Dist: pyyaml>=6.0.1; extra == 'mcp-server'
|
|
43
|
+
Description-Content-Type: text/markdown
|
|
44
|
+
|
|
45
|
+
# FMP Data Client
|
|
46
|
+
|
|
47
|
+
[](https://github.com/MehdiZare/fmp-data/actions/workflows/ci.yml)
|
|
48
|
+
[](https://github.com/MehdiZare/fmp-data/actions/workflows/release.yml)
|
|
49
|
+
[](https://codecov.io/gh/MehdiZare/fmp-data)
|
|
50
|
+
[](https://pypi.org/project/fmp-data/)
|
|
51
|
+
[](https://python-poetry.org/)
|
|
52
|
+
[](https://opensource.org/licenses/MIT)
|
|
53
|
+
|
|
54
|
+
A Python client for the Financial Modeling Prep (FMP) API with comprehensive logging, rate limiting, and error handling. Built with Poetry for reliable dependency management and modern Python development practices.
|
|
55
|
+
|
|
56
|
+
## Why Poetry?
|
|
57
|
+
|
|
58
|
+
This project uses Poetry as the primary package management tool for several key benefits:
|
|
59
|
+
- **Deterministic builds** with lock files ensuring reproducible environments
|
|
60
|
+
- **Dependency resolution** that prevents conflicts before they happen
|
|
61
|
+
- **Virtual environment management** that's transparent and reliable
|
|
62
|
+
- **Build system** that handles packaging and publishing seamlessly
|
|
63
|
+
- **Development workflow** integration with scripts and task runners
|
|
64
|
+
|
|
65
|
+
## Features
|
|
66
|
+
|
|
67
|
+
- Simple and intuitive interface
|
|
68
|
+
- Built-in rate limiting
|
|
69
|
+
- Comprehensive logging
|
|
70
|
+
- Async support
|
|
71
|
+
- Type hints and validation with Pydantic
|
|
72
|
+
- Automatic retries with exponential backoff
|
|
73
|
+
- 100% test coverage (excluding predefined endpoints)
|
|
74
|
+
- Secure API key handling
|
|
75
|
+
- Support for all major FMP endpoints
|
|
76
|
+
- Detailed error messages
|
|
77
|
+
- Configurable retry strategies
|
|
78
|
+
- **Langchain Integration**
|
|
79
|
+
- **MCP Server Support**
|
|
80
|
+
|
|
81
|
+
## Getting an API Key
|
|
82
|
+
|
|
83
|
+
To use this library, you'll need an API key from Financial Modeling Prep (FMP). You can:
|
|
84
|
+
- Get a [free API key from FMP](https://site.financialmodelingprep.com/pricing-plans?couponCode=mehdi)
|
|
85
|
+
- All paid plans come with a 10% discount.
|
|
86
|
+
|
|
87
|
+
## Installation
|
|
88
|
+
|
|
89
|
+
### Using Poetry (Recommended)
|
|
90
|
+
|
|
91
|
+
```bash
|
|
92
|
+
# Basic installation
|
|
93
|
+
poetry add fmp-data
|
|
94
|
+
|
|
95
|
+
# With Langchain integration
|
|
96
|
+
poetry add fmp-data --extras langchain
|
|
97
|
+
|
|
98
|
+
# With MCP server support
|
|
99
|
+
poetry add fmp-data --extras mcp
|
|
100
|
+
|
|
101
|
+
# With both integrations
|
|
102
|
+
poetry add fmp-data --extras "langchain,mcp"
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
### Using pip
|
|
106
|
+
|
|
107
|
+
```bash
|
|
108
|
+
# Basic installation
|
|
109
|
+
pip install fmp-data
|
|
110
|
+
|
|
111
|
+
# With extras
|
|
112
|
+
pip install fmp-data[langchain]
|
|
113
|
+
pip install fmp-data[mcp]
|
|
114
|
+
pip install fmp-data[langchain,mcp]
|
|
115
|
+
```
|
|
116
|
+
|
|
117
|
+
## MCP Server
|
|
118
|
+
|
|
119
|
+
Model Context Protocol (MCP) server provides financial data access through a standardized protocol, enabling AI assistants to query FMP data seamlessly.
|
|
120
|
+
|
|
121
|
+
### Quick Start
|
|
122
|
+
|
|
123
|
+
```bash
|
|
124
|
+
# Set your API key
|
|
125
|
+
export FMP_API_KEY=your_api_key_here
|
|
126
|
+
|
|
127
|
+
# Run the MCP server with Poetry
|
|
128
|
+
poetry run python -m fmp_data.mcp.server
|
|
129
|
+
|
|
130
|
+
# Or if you have the script defined in pyproject.toml
|
|
131
|
+
poetry run fmp-mcp-server
|
|
132
|
+
```
|
|
133
|
+
|
|
134
|
+
### Configuration
|
|
135
|
+
|
|
136
|
+
The MCP server can be configured using environment variables or a custom manifest:
|
|
137
|
+
|
|
138
|
+
```bash
|
|
139
|
+
# Environment variables
|
|
140
|
+
export FMP_API_KEY=your_api_key_here
|
|
141
|
+
export FMP_MCP_MANIFEST=/path/to/custom/manifest.py
|
|
142
|
+
|
|
143
|
+
# Custom manifest example (manifest.py)
|
|
144
|
+
TOOLS = [
|
|
145
|
+
"company.profile",
|
|
146
|
+
"company.search",
|
|
147
|
+
"market.quote",
|
|
148
|
+
"fundamental.income_statement",
|
|
149
|
+
"fundamental.balance_sheet"
|
|
150
|
+
]
|
|
151
|
+
```
|
|
152
|
+
|
|
153
|
+
### Integration with AI Assistants
|
|
154
|
+
|
|
155
|
+
The MCP server exposes FMP endpoints as tools that can be used by MCP-compatible AI assistants:
|
|
156
|
+
|
|
157
|
+
```python
|
|
158
|
+
from fmp_data.mcp.server import create_app
|
|
159
|
+
|
|
160
|
+
# Create MCP server with default tools
|
|
161
|
+
app = create_app()
|
|
162
|
+
|
|
163
|
+
# Create with custom tools
|
|
164
|
+
app = create_app(tools=["company.profile", "market.quote"])
|
|
165
|
+
|
|
166
|
+
# Create with manifest file
|
|
167
|
+
app = create_app(tools="/path/to/manifest.py")
|
|
168
|
+
```
|
|
169
|
+
|
|
170
|
+
### Available Tools
|
|
171
|
+
|
|
172
|
+
The server supports all FMP endpoints through a simple naming convention:
|
|
173
|
+
- `company.profile` - Get company profiles
|
|
174
|
+
- `company.search` - Search companies
|
|
175
|
+
- `market.quote` - Get real-time quotes
|
|
176
|
+
- `fundamental.income_statement` - Financial statements
|
|
177
|
+
- `technical.indicators` - Technical analysis
|
|
178
|
+
- And many more...
|
|
179
|
+
|
|
180
|
+
## Langchain Integration
|
|
181
|
+
|
|
182
|
+
### Prerequisites
|
|
183
|
+
- FMP API Key (`FMP_API_KEY`) - [Get one here](https://site.financialmodelingprep.com/pricing-plans?couponCode=mehdi)
|
|
184
|
+
- OpenAI API Key (`OPENAI_API_KEY`) - Required for embeddings
|
|
185
|
+
|
|
186
|
+
### Quick Start with Vector Store
|
|
187
|
+
|
|
188
|
+
```python
|
|
189
|
+
from fmp_data import create_vector_store
|
|
190
|
+
|
|
191
|
+
# Initialize the vector store
|
|
192
|
+
vector_store = create_vector_store(
|
|
193
|
+
fmp_api_key="YOUR_FMP_API_KEY", # pragma: allowlist secret
|
|
194
|
+
openai_api_key="YOUR_OPENAI_API_KEY" # pragma: allowlist secret
|
|
195
|
+
)
|
|
196
|
+
|
|
197
|
+
# Example queries
|
|
198
|
+
queries = [
|
|
199
|
+
"what is the price of Apple stock?",
|
|
200
|
+
"what was the revenue of Tesla last year?",
|
|
201
|
+
"what's new in the market?"
|
|
202
|
+
]
|
|
203
|
+
|
|
204
|
+
# Search for relevant endpoints and tools
|
|
205
|
+
for query in queries:
|
|
206
|
+
print(f"\nQuery: {query}")
|
|
207
|
+
|
|
208
|
+
# Get tools formatted for OpenAI
|
|
209
|
+
tools = vector_store.get_tools(query, provider="openai")
|
|
210
|
+
|
|
211
|
+
print("\nMatching Tools:")
|
|
212
|
+
for tool in tools:
|
|
213
|
+
print(f"Name: {tool.get('name')}")
|
|
214
|
+
print(f"Description: {tool.get('description')}")
|
|
215
|
+
print("Parameters:", tool.get('parameters'))
|
|
216
|
+
print()
|
|
217
|
+
|
|
218
|
+
# You can also search endpoints directly
|
|
219
|
+
results = vector_store.search(query)
|
|
220
|
+
print("\nRelevant Endpoints:")
|
|
221
|
+
for result in results:
|
|
222
|
+
print(f"Endpoint: {result.name}")
|
|
223
|
+
print(f"Score: {result.score:.2f}")
|
|
224
|
+
print()
|
|
225
|
+
```
|
|
226
|
+
|
|
227
|
+
### Alternative Setup: Using Configuration
|
|
228
|
+
|
|
229
|
+
```python
|
|
230
|
+
from fmp_data import FMPDataClient, ClientConfig
|
|
231
|
+
from fmp_data.lc.config import LangChainConfig
|
|
232
|
+
from fmp_data.lc.embedding import EmbeddingProvider
|
|
233
|
+
|
|
234
|
+
# Configure with LangChain support
|
|
235
|
+
config = LangChainConfig(
|
|
236
|
+
api_key="YOUR_FMP_API_KEY", # pragma: allowlist secret
|
|
237
|
+
embedding_provider=EmbeddingProvider.OPENAI,
|
|
238
|
+
embedding_api_key="YOUR_OPENAI_API_KEY", # pragma: allowlist secret
|
|
239
|
+
embedding_model="text-embedding-3-small"
|
|
240
|
+
)
|
|
241
|
+
|
|
242
|
+
# Create client with LangChain config
|
|
243
|
+
client = FMPDataClient(config=config)
|
|
244
|
+
|
|
245
|
+
# Create vector store using the client
|
|
246
|
+
vector_store = client.create_vector_store()
|
|
247
|
+
|
|
248
|
+
# Search for relevant endpoints
|
|
249
|
+
results = vector_store.search("show me Tesla's financial metrics")
|
|
250
|
+
for result in results:
|
|
251
|
+
print(f"Found endpoint: {result.name}")
|
|
252
|
+
print(f"Relevance score: {result.score:.2f}")
|
|
253
|
+
```
|
|
254
|
+
|
|
255
|
+
### Interactive Example
|
|
256
|
+
Try out the LangChain integration in our interactive Colab notebook:
|
|
257
|
+
[](link-to-your-colab-notebook)
|
|
258
|
+
|
|
259
|
+
This notebook demonstrates how to:
|
|
260
|
+
- Build an intelligent financial agent using fmp-data and LangChain
|
|
261
|
+
- Access real-time market data through natural language queries
|
|
262
|
+
- Use semantic search to select relevant financial tools
|
|
263
|
+
- Create multi-turn conversations about financial data
|
|
264
|
+
|
|
265
|
+
### Environment Variables
|
|
266
|
+
You can also configure the integration using environment variables:
|
|
267
|
+
```bash
|
|
268
|
+
# Required
|
|
269
|
+
export FMP_API_KEY=your_fmp_api_key_here
|
|
270
|
+
export OPENAI_API_KEY=your_openai_api_key_here
|
|
271
|
+
|
|
272
|
+
# Optional
|
|
273
|
+
export FMP_EMBEDDING_PROVIDER=openai
|
|
274
|
+
export FMP_EMBEDDING_MODEL=text-embedding-3-small
|
|
275
|
+
```
|
|
276
|
+
|
|
277
|
+
### Features
|
|
278
|
+
- Semantic search across all FMP endpoints
|
|
279
|
+
- Auto-conversion to LangChain tools
|
|
280
|
+
- Query endpoints using natural language
|
|
281
|
+
- Relevance scoring for search results
|
|
282
|
+
- Automatic caching of embeddings
|
|
283
|
+
- Persistent vector store for faster lookups
|
|
284
|
+
|
|
285
|
+
## Quick Start
|
|
286
|
+
|
|
287
|
+
```python
|
|
288
|
+
from fmp_data import FMPDataClient, ClientConfig, LoggingConfig
|
|
289
|
+
from fmp_data.exceptions import FMPError, RateLimitError, AuthenticationError
|
|
290
|
+
|
|
291
|
+
# Method 1: Initialize with direct API key
|
|
292
|
+
client = FMPDataClient(api_key="your_api_key_here") # pragma: allowlist secret
|
|
293
|
+
|
|
294
|
+
# Method 2: Initialize from environment variable (FMP_API_KEY)
|
|
295
|
+
client = FMPDataClient.from_env()
|
|
296
|
+
|
|
297
|
+
# Method 3: Initialize with custom configuration
|
|
298
|
+
config = ClientConfig(
|
|
299
|
+
api_key="your_api_key_here", #pragma: allowlist secret
|
|
300
|
+
timeout=30,
|
|
301
|
+
max_retries=3,
|
|
302
|
+
base_url="https://financialmodelingprep.com/api",
|
|
303
|
+
logging=LoggingConfig(level="INFO")
|
|
304
|
+
)
|
|
305
|
+
client = FMPDataClient(config=config)
|
|
306
|
+
|
|
307
|
+
# Using with context manager (recommended)
|
|
308
|
+
with FMPDataClient(api_key="your_api_key_here") as client: # pragma: allowlist secret
|
|
309
|
+
try:
|
|
310
|
+
# Get company profile
|
|
311
|
+
profile = client.company.get_profile("AAPL")
|
|
312
|
+
print(f"Company: {profile.company_name}")
|
|
313
|
+
print(f"Industry: {profile.industry}")
|
|
314
|
+
print(f"Market Cap: ${profile.mkt_cap:,.2f}")
|
|
315
|
+
|
|
316
|
+
# Search companies
|
|
317
|
+
results = client.company.search("Tesla", limit=5)
|
|
318
|
+
for company in results:
|
|
319
|
+
print(f"{company.symbol}: {company.name}")
|
|
320
|
+
|
|
321
|
+
except RateLimitError as e:
|
|
322
|
+
print(f"Rate limit exceeded. Wait {e.retry_after} seconds")
|
|
323
|
+
except AuthenticationError:
|
|
324
|
+
print("Invalid API key")
|
|
325
|
+
except FMPError as e:
|
|
326
|
+
print(f"API error: {e}")
|
|
327
|
+
|
|
328
|
+
# Client is automatically closed after the with block
|
|
329
|
+
```
|
|
330
|
+
|
|
331
|
+
## Key Components
|
|
332
|
+
|
|
333
|
+
### 1. Company Information
|
|
334
|
+
```python
|
|
335
|
+
from fmp_data import FMPDataClient
|
|
336
|
+
|
|
337
|
+
with FMPDataClient.from_env() as client:
|
|
338
|
+
# Get company profile
|
|
339
|
+
profile = client.company.get_profile("AAPL")
|
|
340
|
+
|
|
341
|
+
# Get company executives
|
|
342
|
+
executives = client.company.get_executives("AAPL")
|
|
343
|
+
|
|
344
|
+
# Search companies
|
|
345
|
+
results = client.company.search("Tesla", limit=5)
|
|
346
|
+
|
|
347
|
+
# Get employee count history
|
|
348
|
+
employees = client.company.get_employee_count("AAPL")
|
|
349
|
+
```
|
|
350
|
+
|
|
351
|
+
### 2. Financial Statements
|
|
352
|
+
```python
|
|
353
|
+
from fmp_data import FMPDataClient
|
|
354
|
+
|
|
355
|
+
with FMPDataClient.from_env() as client:
|
|
356
|
+
# Get income statements
|
|
357
|
+
income_stmt = client.fundamental.get_income_statement(
|
|
358
|
+
"AAPL",
|
|
359
|
+
period="quarter", # or "annual"
|
|
360
|
+
limit=4
|
|
361
|
+
)
|
|
362
|
+
|
|
363
|
+
# Get balance sheets
|
|
364
|
+
balance_sheet = client.fundamental.get_balance_sheet(
|
|
365
|
+
"AAPL",
|
|
366
|
+
period="annual"
|
|
367
|
+
)
|
|
368
|
+
|
|
369
|
+
# Get cash flow statements
|
|
370
|
+
cash_flow = client.fundamental.get_cash_flow_statement("AAPL")
|
|
371
|
+
```
|
|
372
|
+
|
|
373
|
+
### 3. Market Data
|
|
374
|
+
```python
|
|
375
|
+
from fmp_data import FMPDataClient
|
|
376
|
+
|
|
377
|
+
with FMPDataClient.from_env() as client:
|
|
378
|
+
# Get real-time quote
|
|
379
|
+
quote = client.market.get_quote("TSLA")
|
|
380
|
+
|
|
381
|
+
# Get historical prices
|
|
382
|
+
history = client.market.get_historical_price(
|
|
383
|
+
"TSLA",
|
|
384
|
+
from_date="2023-01-01",
|
|
385
|
+
to_date="2023-12-31"
|
|
386
|
+
)
|
|
387
|
+
```
|
|
388
|
+
|
|
389
|
+
### 4. Async Support
|
|
390
|
+
```python
|
|
391
|
+
import asyncio
|
|
392
|
+
from fmp_data import FMPDataClient
|
|
393
|
+
|
|
394
|
+
async def get_multiple_profiles(symbols):
|
|
395
|
+
async with FMPDataClient.from_env() as client:
|
|
396
|
+
tasks = [client.company.get_profile_async(symbol)
|
|
397
|
+
for symbol in symbols]
|
|
398
|
+
return await asyncio.gather(*tasks)
|
|
399
|
+
|
|
400
|
+
# Run async function
|
|
401
|
+
symbols = ["AAPL", "MSFT", "GOOGL"]
|
|
402
|
+
profiles = asyncio.run(get_multiple_profiles(symbols))
|
|
403
|
+
```
|
|
404
|
+
|
|
405
|
+
## Configuration
|
|
406
|
+
|
|
407
|
+
### Environment Variables
|
|
408
|
+
```bash
|
|
409
|
+
# Required
|
|
410
|
+
FMP_API_KEY=your_api_key_here
|
|
411
|
+
|
|
412
|
+
# Optional
|
|
413
|
+
FMP_BASE_URL=https://financialmodelingprep.com/api
|
|
414
|
+
FMP_TIMEOUT=30
|
|
415
|
+
FMP_MAX_RETRIES=3
|
|
416
|
+
|
|
417
|
+
# Rate Limiting
|
|
418
|
+
FMP_DAILY_LIMIT=250
|
|
419
|
+
FMP_REQUESTS_PER_SECOND=10
|
|
420
|
+
FMP_REQUESTS_PER_MINUTE=300
|
|
421
|
+
|
|
422
|
+
# Logging
|
|
423
|
+
FMP_LOG_LEVEL=INFO
|
|
424
|
+
FMP_LOG_PATH=/path/to/logs
|
|
425
|
+
FMP_LOG_MAX_BYTES=10485760
|
|
426
|
+
FMP_LOG_BACKUP_COUNT=5
|
|
427
|
+
|
|
428
|
+
# MCP Server
|
|
429
|
+
FMP_MCP_MANIFEST=/path/to/custom/manifest.py
|
|
430
|
+
```
|
|
431
|
+
|
|
432
|
+
### Custom Configuration
|
|
433
|
+
```python
|
|
434
|
+
from fmp_data import FMPDataClient, ClientConfig, LoggingConfig, RateLimitConfig, LogHandlerConfig
|
|
435
|
+
|
|
436
|
+
config = ClientConfig(
|
|
437
|
+
api_key="your_api_key_here", # pragma: allowlist secret
|
|
438
|
+
timeout=30,
|
|
439
|
+
max_retries=3,
|
|
440
|
+
base_url="https://financialmodelingprep.com/api",
|
|
441
|
+
rate_limit=RateLimitConfig(
|
|
442
|
+
daily_limit=250,
|
|
443
|
+
requests_per_second=10,
|
|
444
|
+
requests_per_minute=300
|
|
445
|
+
),
|
|
446
|
+
logging=LoggingConfig(
|
|
447
|
+
level="DEBUG",
|
|
448
|
+
handlers={
|
|
449
|
+
"console": LogHandlerConfig(
|
|
450
|
+
class_name="StreamHandler",
|
|
451
|
+
level="INFO",
|
|
452
|
+
format="%(asctime)s - %(name)s - %(levelname)s - %(message)s"
|
|
453
|
+
),
|
|
454
|
+
"file": LogHandlerConfig(
|
|
455
|
+
class_name="RotatingFileHandler",
|
|
456
|
+
level="DEBUG",
|
|
457
|
+
format="%(asctime)s - %(name)s - %(levelname)s - %(message)s",
|
|
458
|
+
handler_kwargs={
|
|
459
|
+
"filename": "fmp.log",
|
|
460
|
+
"maxBytes": 10485760,
|
|
461
|
+
"backupCount": 5
|
|
462
|
+
}
|
|
463
|
+
)
|
|
464
|
+
}
|
|
465
|
+
)
|
|
466
|
+
)
|
|
467
|
+
|
|
468
|
+
client = FMPDataClient(config=config)
|
|
469
|
+
```
|
|
470
|
+
|
|
471
|
+
## Error Handling
|
|
472
|
+
|
|
473
|
+
```python
|
|
474
|
+
from fmp_data import FMPDataClient
|
|
475
|
+
from fmp_data.exceptions import (
|
|
476
|
+
FMPError,
|
|
477
|
+
RateLimitError,
|
|
478
|
+
AuthenticationError,
|
|
479
|
+
ValidationError,
|
|
480
|
+
ConfigError
|
|
481
|
+
)
|
|
482
|
+
try:
|
|
483
|
+
with FMPDataClient.from_env() as client:
|
|
484
|
+
profile = client.company.get_profile("INVALID")
|
|
485
|
+
|
|
486
|
+
except RateLimitError as e:
|
|
487
|
+
print(f"Rate limit exceeded. Wait {e.retry_after} seconds")
|
|
488
|
+
print(f"Status code: {e.status_code}")
|
|
489
|
+
print(f"Response: {e.response}")
|
|
490
|
+
|
|
491
|
+
except AuthenticationError as e:
|
|
492
|
+
print("Invalid API key or authentication failed")
|
|
493
|
+
print(f"Status code: {e.status_code}")
|
|
494
|
+
|
|
495
|
+
except ValidationError as e:
|
|
496
|
+
print(f"Invalid parameters: {e.message}")
|
|
497
|
+
|
|
498
|
+
except ConfigError as e:
|
|
499
|
+
print(f"Configuration error: {e.message}")
|
|
500
|
+
|
|
501
|
+
except FMPError as e:
|
|
502
|
+
print(f"General API error: {e.message}")
|
|
503
|
+
```
|
|
504
|
+
|
|
505
|
+
## Development Setup
|
|
506
|
+
|
|
507
|
+
### Prerequisites
|
|
508
|
+
- Python 3.10+
|
|
509
|
+
- Poetry 1.4+
|
|
510
|
+
|
|
511
|
+
### Setup
|
|
512
|
+
|
|
513
|
+
1. Clone the repository:
|
|
514
|
+
```bash
|
|
515
|
+
git clone https://github.com/MehdiZare/fmp-data.git
|
|
516
|
+
cd fmp-data
|
|
517
|
+
```
|
|
518
|
+
|
|
519
|
+
2. Install dependencies with Poetry:
|
|
520
|
+
```bash
|
|
521
|
+
# Install all dependencies including dev dependencies
|
|
522
|
+
poetry install
|
|
523
|
+
|
|
524
|
+
# Install with specific extras for development
|
|
525
|
+
poetry install --extras "langchain mcp"
|
|
526
|
+
```
|
|
527
|
+
|
|
528
|
+
3. Activate the virtual environment:
|
|
529
|
+
```bash
|
|
530
|
+
poetry shell
|
|
531
|
+
```
|
|
532
|
+
|
|
533
|
+
4. Set up pre-commit hooks:
|
|
534
|
+
```bash
|
|
535
|
+
poetry run pre-commit install
|
|
536
|
+
```
|
|
537
|
+
|
|
538
|
+
5. Set up environment variables:
|
|
539
|
+
```bash
|
|
540
|
+
# Create .env file
|
|
541
|
+
echo "FMP_API_KEY=your_api_key_here" > .env
|
|
542
|
+
```
|
|
543
|
+
|
|
544
|
+
## Running Tests
|
|
545
|
+
|
|
546
|
+
### Basic Test Commands
|
|
547
|
+
|
|
548
|
+
```bash
|
|
549
|
+
# Run all tests with coverage
|
|
550
|
+
poetry run pytest --cov=fmp_data
|
|
551
|
+
|
|
552
|
+
# Run tests with coverage report
|
|
553
|
+
poetry run pytest --cov=fmp_data --cov-report=html
|
|
554
|
+
|
|
555
|
+
# Run specific test file
|
|
556
|
+
poetry run pytest tests/test_client.py
|
|
557
|
+
|
|
558
|
+
# Run tests with verbose output
|
|
559
|
+
poetry run pytest -v
|
|
560
|
+
|
|
561
|
+
# Run integration tests (requires API key)
|
|
562
|
+
FMP_TEST_API_KEY=your_test_api_key poetry run pytest tests/integration/
|
|
563
|
+
```
|
|
564
|
+
|
|
565
|
+
### Development Commands
|
|
566
|
+
|
|
567
|
+
```bash
|
|
568
|
+
# Format code with black
|
|
569
|
+
poetry run black fmp_data tests
|
|
570
|
+
|
|
571
|
+
# Sort imports with isort
|
|
572
|
+
poetry run isort fmp_data tests
|
|
573
|
+
|
|
574
|
+
# Type checking with mypy
|
|
575
|
+
poetry run mypy fmp_data
|
|
576
|
+
|
|
577
|
+
# Lint with flake8
|
|
578
|
+
poetry run flake8 fmp_data
|
|
579
|
+
|
|
580
|
+
# Run all quality checks
|
|
581
|
+
poetry run pre-commit run --all-files
|
|
582
|
+
```
|
|
583
|
+
|
|
584
|
+
### Building and Publishing
|
|
585
|
+
|
|
586
|
+
```bash
|
|
587
|
+
# Build the package
|
|
588
|
+
poetry build
|
|
589
|
+
|
|
590
|
+
# Check package before publishing
|
|
591
|
+
poetry check
|
|
592
|
+
|
|
593
|
+
# Publish to PyPI (maintainers only)
|
|
594
|
+
poetry publish
|
|
595
|
+
```
|
|
596
|
+
|
|
597
|
+
### Poetry Configuration
|
|
598
|
+
|
|
599
|
+
```bash
|
|
600
|
+
# Configure Poetry to create virtual environments in project directory
|
|
601
|
+
poetry config virtualenvs.in-project true
|
|
602
|
+
|
|
603
|
+
# Show current configuration
|
|
604
|
+
poetry config --list
|
|
605
|
+
|
|
606
|
+
# Update dependencies
|
|
607
|
+
poetry update
|
|
608
|
+
|
|
609
|
+
# Add development dependencies
|
|
610
|
+
poetry add --group dev pytest black mypy
|
|
611
|
+
|
|
612
|
+
# Export requirements.txt (if needed)
|
|
613
|
+
poetry export -f requirements.txt --output requirements.txt
|
|
614
|
+
```
|
|
615
|
+
|
|
616
|
+
View the latest test coverage report [here](https://codecov.io/gh/MehdiZare/fmp-data).
|
|
617
|
+
|
|
618
|
+
## Contributing
|
|
619
|
+
|
|
620
|
+
We welcome contributions! Please follow these steps:
|
|
621
|
+
|
|
622
|
+
### Getting Started
|
|
623
|
+
|
|
624
|
+
1. Fork the repository
|
|
625
|
+
2. Clone your fork:
|
|
626
|
+
```bash
|
|
627
|
+
git clone https://github.com/yourusername/fmp-data.git
|
|
628
|
+
cd fmp-data
|
|
629
|
+
```
|
|
630
|
+
|
|
631
|
+
3. Set up development environment:
|
|
632
|
+
```bash
|
|
633
|
+
# Install dependencies with Poetry
|
|
634
|
+
poetry install --extras "langchain mcp"
|
|
635
|
+
|
|
636
|
+
# Activate virtual environment
|
|
637
|
+
poetry shell
|
|
638
|
+
|
|
639
|
+
# Install pre-commit hooks
|
|
640
|
+
poetry run pre-commit install
|
|
641
|
+
```
|
|
642
|
+
|
|
643
|
+
### Making Changes
|
|
644
|
+
|
|
645
|
+
1. Create a feature branch:
|
|
646
|
+
```bash
|
|
647
|
+
git checkout -b feature/your-feature-name
|
|
648
|
+
```
|
|
649
|
+
|
|
650
|
+
2. Make your changes and ensure quality:
|
|
651
|
+
```bash
|
|
652
|
+
# Format code
|
|
653
|
+
poetry run black fmp_data tests
|
|
654
|
+
|
|
655
|
+
# Sort imports
|
|
656
|
+
poetry run isort fmp_data tests
|
|
657
|
+
|
|
658
|
+
# Run type checking
|
|
659
|
+
poetry run mypy fmp_data
|
|
660
|
+
|
|
661
|
+
# Run tests
|
|
662
|
+
poetry run pytest --cov=fmp_data
|
|
663
|
+
```
|
|
664
|
+
|
|
665
|
+
3. Commit your changes:
|
|
666
|
+
```bash
|
|
667
|
+
git add .
|
|
668
|
+
git commit -m "feat: add your feature description"
|
|
669
|
+
```
|
|
670
|
+
|
|
671
|
+
4. Push and create a pull request
|
|
672
|
+
|
|
673
|
+
### Requirements
|
|
674
|
+
|
|
675
|
+
Please ensure your contributions meet these requirements:
|
|
676
|
+
- Tests pass: `poetry run pytest`
|
|
677
|
+
- Code is formatted: `poetry run black fmp_data tests`
|
|
678
|
+
- Imports are sorted: `poetry run isort fmp_data tests`
|
|
679
|
+
- Type hints are included for all functions
|
|
680
|
+
- Documentation is updated for new features
|
|
681
|
+
- Commit messages follow [Conventional Commits](https://www.conventionalcommits.org/)
|
|
682
|
+
|
|
683
|
+
### Running Quality Checks
|
|
684
|
+
|
|
685
|
+
```bash
|
|
686
|
+
# Run all quality checks at once
|
|
687
|
+
poetry run pre-commit run --all-files
|
|
688
|
+
|
|
689
|
+
# Or run individual checks
|
|
690
|
+
poetry run black --check fmp_data tests
|
|
691
|
+
poetry run isort --check-only fmp_data tests
|
|
692
|
+
poetry run flake8 fmp_data
|
|
693
|
+
poetry run mypy fmp_data
|
|
694
|
+
poetry run pytest --cov=fmp_data
|
|
695
|
+
```
|
|
696
|
+
|
|
697
|
+
## License
|
|
698
|
+
|
|
699
|
+
This project is licensed under the MIT License - see the [LICENSE](./LICENSE) file for details.
|
|
700
|
+
|
|
701
|
+
## Acknowledgments
|
|
702
|
+
|
|
703
|
+
- Financial Modeling Prep for providing the API
|
|
704
|
+
- Contributors to the project
|
|
705
|
+
- Open source packages used in this project
|
|
706
|
+
|
|
707
|
+
## Support
|
|
708
|
+
|
|
709
|
+
- GitHub Issues: [Create an issue](https://github.com/MehdiZare/fmp-data/issues)
|
|
710
|
+
- Documentation: [Read the docs](./docs)
|
|
711
|
+
|
|
712
|
+
## Examples
|
|
713
|
+
|
|
714
|
+
### Interactive Notebooks
|
|
715
|
+
- [Financial Agent Tutorial](https://colab.research.google.com/drive/1cSyLX-j9XhyrXyVJ2HwMZJvPy1Lf2CuA?usp=sharing): Build an intelligent financial agent with LangChain integration
|
|
716
|
+
- [Basic Usage Examples](./examples): Simple code examples demonstrating key features
|
|
717
|
+
|
|
718
|
+
### Code Examples
|
|
719
|
+
|
|
720
|
+
```python
|
|
721
|
+
# Basic usage example
|
|
722
|
+
from fmp_data import FMPDataClient
|
|
723
|
+
|
|
724
|
+
with FMPDataClient.from_env() as client:
|
|
725
|
+
# Get company profile
|
|
726
|
+
profile = client.company.get_profile("AAPL")
|
|
727
|
+
print(f"Company: {profile.company_name}")
|
|
728
|
+
```
|
|
729
|
+
|
|
730
|
+
## Release Notes
|
|
731
|
+
|
|
732
|
+
See [CHANGELOG.md](./CHANGELOG.md) for a list of changes in each release.
|