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.
Files changed (84) hide show
  1. fmp_data/__init__.py +138 -0
  2. fmp_data/alternative/__init__.py +34 -0
  3. fmp_data/alternative/client.py +150 -0
  4. fmp_data/alternative/endpoints.py +533 -0
  5. fmp_data/alternative/mapping.py +737 -0
  6. fmp_data/alternative/models.py +296 -0
  7. fmp_data/alternative/schema.py +165 -0
  8. fmp_data/base.py +316 -0
  9. fmp_data/client.py +269 -0
  10. fmp_data/company/__init__.py +40 -0
  11. fmp_data/company/client.py +238 -0
  12. fmp_data/company/endpoints.py +711 -0
  13. fmp_data/company/hints.py +77 -0
  14. fmp_data/company/mapping.py +1361 -0
  15. fmp_data/company/models.py +543 -0
  16. fmp_data/company/schema.py +132 -0
  17. fmp_data/config.py +207 -0
  18. fmp_data/economics/__init__.py +16 -0
  19. fmp_data/economics/client.py +52 -0
  20. fmp_data/economics/endpoints.py +164 -0
  21. fmp_data/economics/mapping.py +641 -0
  22. fmp_data/economics/models.py +75 -0
  23. fmp_data/economics/schema.py +91 -0
  24. fmp_data/exceptions.py +54 -0
  25. fmp_data/fundamental/__init__.py +40 -0
  26. fmp_data/fundamental/client.py +87 -0
  27. fmp_data/fundamental/endpoints.py +403 -0
  28. fmp_data/fundamental/mapping.py +867 -0
  29. fmp_data/fundamental/models.py +913 -0
  30. fmp_data/fundamental/schema.py +40 -0
  31. fmp_data/institutional/__init__.py +26 -0
  32. fmp_data/institutional/client.py +141 -0
  33. fmp_data/institutional/endpoints.py +321 -0
  34. fmp_data/institutional/mapping.py +749 -0
  35. fmp_data/institutional/models.py +301 -0
  36. fmp_data/institutional/schema.py +99 -0
  37. fmp_data/intelligence/__init__.py +58 -0
  38. fmp_data/intelligence/client.py +331 -0
  39. fmp_data/intelligence/endpoints.py +788 -0
  40. fmp_data/intelligence/mapping.py +1677 -0
  41. fmp_data/intelligence/models.py +707 -0
  42. fmp_data/intelligence/schema.py +57 -0
  43. fmp_data/investment/__init__.py +24 -0
  44. fmp_data/investment/client.py +104 -0
  45. fmp_data/investment/endpoints.py +241 -0
  46. fmp_data/investment/mapping.py +658 -0
  47. fmp_data/investment/models.py +220 -0
  48. fmp_data/investment/schema.py +106 -0
  49. fmp_data/lc/__init__.py +256 -0
  50. fmp_data/lc/config.py +88 -0
  51. fmp_data/lc/embedding.py +140 -0
  52. fmp_data/lc/hints.py +66 -0
  53. fmp_data/lc/mapping.py +107 -0
  54. fmp_data/lc/models.py +98 -0
  55. fmp_data/lc/registry.py +693 -0
  56. fmp_data/lc/utils.py +35 -0
  57. fmp_data/lc/validation.py +267 -0
  58. fmp_data/lc/vector_store.py +592 -0
  59. fmp_data/logger.py +358 -0
  60. fmp_data/market/__init__.py +18 -0
  61. fmp_data/market/client.py +106 -0
  62. fmp_data/market/endpoints.py +358 -0
  63. fmp_data/market/hints.py +22 -0
  64. fmp_data/market/mapping.py +854 -0
  65. fmp_data/market/models.py +310 -0
  66. fmp_data/market/schema.py +186 -0
  67. fmp_data/mcp/__init__.py +0 -0
  68. fmp_data/mcp/server.py +101 -0
  69. fmp_data/mcp/tool_loader.py +74 -0
  70. fmp_data/mcp/tools_manifest.py +17 -0
  71. fmp_data/models.py +265 -0
  72. fmp_data/rate_limit.py +136 -0
  73. fmp_data/schema.py +158 -0
  74. fmp_data/technical/__init__.py +28 -0
  75. fmp_data/technical/client.py +214 -0
  76. fmp_data/technical/endpoints.py +102 -0
  77. fmp_data/technical/mapping.py +452 -0
  78. fmp_data/technical/models.py +87 -0
  79. fmp_data/technical/schema.py +261 -0
  80. fmp_data-0.0.0.dist-info/METADATA +732 -0
  81. fmp_data-0.0.0.dist-info/RECORD +84 -0
  82. fmp_data-0.0.0.dist-info/WHEEL +4 -0
  83. fmp_data-0.0.0.dist-info/entry_points.txt +10 -0
  84. 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
+ [![CI](https://github.com/MehdiZare/fmp-data/actions/workflows/ci.yml/badge.svg)](https://github.com/MehdiZare/fmp-data/actions/workflows/ci.yml)
48
+ [![Release](https://github.com/MehdiZare/fmp-data/actions/workflows/release.yml/badge.svg)](https://github.com/MehdiZare/fmp-data/actions/workflows/release.yml)
49
+ [![codecov](https://codecov.io/gh/MehdiZare/fmp-data/branch/main/graph/badge.svg)](https://codecov.io/gh/MehdiZare/fmp-data)
50
+ [![Python](https://img.shields.io/pypi/pyversions/fmp-data.svg)](https://pypi.org/project/fmp-data/)
51
+ [![Poetry](https://img.shields.io/endpoint?url=https://python-poetry.org/badge/v0.json)](https://python-poetry.org/)
52
+ [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](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
+ [![Open In Colab](https://colab.research.google.com/assets/colab-badge.svg)](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.