FMP Data Client
A Python client for the Financial Modeling Prep (FMP) API with comprehensive logging, rate limiting, and error handling.
Features
- 🚀 Simple and intuitive interface
- 🔒 Built-in rate limiting
- 📝 Comprehensive logging
- ⚡ Async support
- 🏷️ Type hints and validation with Pydantic
- 🔄 Automatic retries with exponential backoff
- 🎯 100% test coverage (excluding predefined endpoints)
- 🛡️ Secure API key handling
- 📊 Support for all major FMP endpoints
- 🔍 Detailed error messages
- 🚦 Configurable retry strategies
- 🤖 NEW: Langchain Integration
Getting an API Key
To use this library, you'll need an API key from Financial Modeling Prep (FMP). You can:
- Get a free API key from FMP
- All paid plans come with a 10% discount.
Installation
# Using pip
pip install fmp-data
# Using poetry
poetry add fmp-data
# For Langchain integration
pip install fmp-data[langchain]
# or
poetry add fmp-data --extras langchain
Langchain Integration
Prerequisites
- FMP API Key (
FMP_API_KEY) - Get one here - OpenAI API Key (
OPENAI_API_KEY) - Required for embeddings
Quick Start with Vector Store
from fmp_data import create_vector_store
# Initialize the vector store
vector_store = create_vector_store(
fmp_api_key="YOUR_FMP_API_KEY", # pragma: allowlist secret
openai_api_key="YOUR_OPENAI_API_KEY" # pragma: allowlist secret
)
# Example queries
queries = [
"what is the price of Apple stock?",
"what was the revenue of Tesla last year?",
"what's new in the market?"
]
# Search for relevant endpoints and tools
for query in queries:
print(f"\nQuery: {query}")
# Get tools formatted for OpenAI
tools = vector_store.get_tools(query, provider="openai")
print("\nMatching Tools:")
for tool in tools:
print(f"Name: {tool.get('name')}")
print(f"Description: {tool.get('description')}")
print("Parameters:", tool.get('parameters'))
print()
# You can also search endpoints directly
results = vector_store.search(query)
print("\nRelevant Endpoints:")
for result in results:
print(f"Endpoint: {result.name}")
print(f"Score: {result.score:.2f}")
print()
Alternative Setup: Using Configuration
from fmp_data import FMPDataClient, ClientConfig
from fmp_data.lc.config import LangChainConfig
from fmp_data.lc.embedding import EmbeddingProvider
# Configure with LangChain support
config = LangChainConfig(
api_key="YOUR_FMP_API_KEY", # pragma: allowlist secret
embedding_provider=EmbeddingProvider.OPENAI,
embedding_api_key="YOUR_OPENAI_API_KEY", # pragma: allowlist secret
embedding_model="text-embedding-3-small"
)
# Create client with LangChain config
client = FMPDataClient(config=config)
# Create vector store using the client
vector_store = client.create_vector_store()
# Search for relevant endpoints
results = vector_store.search("show me Tesla's financial metrics")
for result in results:
print(f"Found endpoint: {result.name}")
print(f"Relevance score: {result.score:.2f}")
Interactive Example
Try out the LangChain integration in our interactive Colab notebook:
This notebook demonstrates how to:
- Build an intelligent financial agent using fmp-data and LangChain
- Access real-time market data through natural language queries
- Use semantic search to select relevant financial tools
- Create multi-turn conversations about financial data
Environment Variables
You can also configure the integration using environment variables:
# Required
export FMP_API_KEY=your_fmp_api_key_here
export OPENAI_API_KEY=your_openai_api_key_here
# Optional
export FMP_EMBEDDING_PROVIDER=openai
export FMP_EMBEDDING_MODEL=text-embedding-3-small
Features
- 🔍 Semantic search across all FMP endpoints
- 🤖 Auto-conversion to LangChain tools
- 📊 Query endpoints using natural language
- 🎯 Relevance scoring for search results
- 🔄 Automatic caching of embeddings
- 💾 Persistent vector store for faster lookups
Quick Start
from fmp_data import FMPDataClient, ClientConfig, LoggingConfig
from fmp_data.exceptions import FMPError, RateLimitError, AuthenticationError
# Method 1: Initialize with direct API key
client = FMPDataClient(api_key="your_api_key_here") # pragma: allowlist secret
# Method 2: Initialize from environment variable (FMP_API_KEY)
client = FMPDataClient.from_env()
# Method 3: Initialize with custom configuration
config = ClientConfig(
api_key="your_api_key_here", #pragma: allowlist secret
timeout=30,
max_retries=3,
base_url="https://financialmodelingprep.com/api",
logging=LoggingConfig(level="INFO")
)
client = FMPDataClient(config=config)
# Using with context manager (recommended)
with FMPDataClient(api_key="your_api_key_here") as client: # pragma: allowlist secret
try:
# Get company profile
profile = client.company.get_profile("AAPL")
print(f"Company: {profile.company_name}")
print(f"Industry: {profile.industry}")
print(f"Market Cap: ${profile.mkt_cap:,.2f}")
# Search companies
results = client.company.search("Tesla", limit=5)
for company in results:
print(f"{company.symbol}: {company.name}")
except RateLimitError as e:
print(f"Rate limit exceeded. Wait {e.retry_after} seconds")
except AuthenticationError:
print("Invalid API key")
except FMPError as e:
print(f"API error: {e}")
# Client is automatically closed after the with block
Key Components
1. Company Information
from fmp_data import FMPDataClient
with FMPDataClient.from_env() as client:
# Get company profile
profile = client.company.get_profile("AAPL")
# Get company executives
executives = client.company.get_executives("AAPL")
# Search companies
results = client.company.search("Tesla", limit=5)
# Get employee count history
employees = client.company.get_employee_count("AAPL")
2. Financial Statements
from fmp_data import FMPDataClient
with FMPDataClient.from_env() as client:
# Get income statements
income_stmt = client.fundamental.get_income_statement(
"AAPL",
period="quarter", # or "annual"
limit=4
)
# Get balance sheets
balance_sheet = client.fundamental.get_balance_sheet(
"AAPL",
period="annual"
)
# Get cash flow statements
cash_flow = client.fundamental.get_cash_flow_statement("AAPL")
3. Market Data
from fmp_data import FMPDataClient
with FMPDataClient.from_env() as client:
# Get real-time quote
quote = client.market.get_quote("TSLA")
# Get historical prices
history = client.market.get_historical_price(
"TSLA",
from_date="2023-01-01",
to_date="2023-12-31"
)
4. Async Support
import asyncio
from fmp_data import FMPDataClient
async def get_multiple_profiles(symbols):
async with FMPDataClient.from_env() as client:
tasks = [client.company.get_profile_async(symbol)
for symbol in symbols]
return await asyncio.gather(*tasks)
# Run async function
symbols = ["AAPL", "MSFT", "GOOGL"]
profiles = asyncio.run(get_multiple_profiles(symbols))
Configuration
Environment Variables
# Required
FMP_API_KEY=your_api_key_here
# Optional
FMP_BASE_URL=https://financialmodelingprep.com/api
FMP_TIMEOUT=30
FMP_MAX_RETRIES=3
# Rate Limiting
FMP_DAILY_LIMIT=250
FMP_REQUESTS_PER_SECOND=10
FMP_REQUESTS_PER_MINUTE=300
# Logging
FMP_LOG_LEVEL=INFO
FMP_LOG_PATH=/path/to/logs
FMP_LOG_MAX_BYTES=10485760
FMP_LOG_BACKUP_COUNT=5
Custom Configuration
from fmp_data import FMPDataClient, ClientConfig, LoggingConfig, RateLimitConfig, LogHandlerConfig
config = ClientConfig(
api_key="your_api_key_here", # pragma: allowlist secret
timeout=30,
max_retries=3,
base_url="https://financialmodelingprep.com/api",
rate_limit=RateLimitConfig(
daily_limit=250,
requests_per_second=10,
requests_per_minute=300
),
logging=LoggingConfig(
level="DEBUG",
handlers={
"console": LogHandlerConfig(
class_name="StreamHandler",
level="INFO",
format="%(asctime)s - %(name)s - %(levelname)s - %(message)s"
),
"file": LogHandlerConfig(
class_name="RotatingFileHandler",
level="DEBUG",
format="%(asctime)s - %(name)s - %(levelname)s - %(message)s",
handler_kwargs={
"filename": "fmp.log",
"maxBytes": 10485760,
"backupCount": 5
}
)
}
)
)
client = FMPDataClient(config=config)
Error Handling
from fmp_data import FMPDataClient
from fmp_data.exceptions import (
FMPError,
RateLimitError,
AuthenticationError,
ValidationError,
ConfigError
)
try:
with FMPDataClient.from_env() as client:
profile = client.company.get_profile("INVALID")
except RateLimitError as e:
print(f"Rate limit exceeded. Wait {e.retry_after} seconds")
print(f"Status code: {e.status_code}")
print(f"Response: {e.response}")
except AuthenticationError as e:
print("Invalid API key or authentication failed")
print(f"Status code: {e.status_code}")
except ValidationError as e:
print(f"Invalid parameters: {e.message}")
except ConfigError as e:
print(f"Configuration error: {e.message}")
except FMPError as e:
print(f"General API error: {e.message}")
Development Setup
- Clone the repository:
git clone https://github.com/MehdiZare/fmp-data.git
cd fmp-data
- Install dependencies using Poetry:
poetry install
- Set up pre-commit hooks:
poetry run pre-commit install
Running Tests
# Run all tests with coverage
poetry run pytest --cov=fmp_data
# Run specific test file
poetry run pytest tests/test_client.py
# Run integration tests (requires API key)
FMP_TEST_API_KEY=your_test_api_key poetry run pytest tests/integration/
View the latest test coverage report here.
Contributing
- Fork the repository
- Create a feature branch:
git checkout -b feature-name - Make your changes
- Run tests:
poetry run pytest - Create a pull request
Please ensure:
- Tests pass
- Code is formatted with black
- Type hints are included
- Documentation is updated
- Commit messages follow conventional commits
License
This project is licensed under the MIT License - see the LICENSE file for details.
Acknowledgments
- Financial Modeling Prep for providing the API
- Contributors to the project
- Open source packages used in this project
Support
- GitHub Issues: Create an issue
- Documentation: Read the docs
Examples
Interactive Notebooks
- Financial Agent Tutorial: Build an intelligent financial agent with LangChain integration
- Basic Usage Examples: Simple code examples demonstrating key features
Code Examples
# Basic usage example
from fmp_data import FMPDataClient
with FMPDataClient.from_env() as client:
# Get company profile
profile = client.company.get_profile("AAPL")
print(f"Company: {profile.company_name}")
Release Notes
See CHANGELOG.md for a list of changes in each release.
Metadata
Release files for fmp-data 0.3.3.post10
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| fmp_data-0.3.3.post10.tar.gz | 139.7 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| fmp_data-0.3.3.post10-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 308.8 kB
Release files / fmp_data-0.3.3.post10.tar.gz
| Download URL | fmp_data-0.3.3.post10.tar.gz |
|---|---|
| Size | 139.7 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
67be6f7b0a7efb010b7acc5f798770b04ab66241e3b4760727eb30afd5424bda
|
|
BLAKE2b-256 checksum How to use checksums |
d340eb1769fbf77e236230474f0816c7708d80bd50605ed061018dca6495ba1a
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.1.0 CPython/3.12.11
|
Release files / fmp_data-0.3.3.post10-py3-none-any.whl
| Download URL | fmp_data-0.3.3.post10-py3-none-any.whl |
|---|---|
| Size | 169.1 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
25e866c642d28c197ece2a3ca9160593e436451ae637a0b7ff3c3bef629c34ef
|
|
BLAKE2b-256 checksum How to use checksums |
3ab4e0c887ff7c3076f125462d828f0a39797ba8222dcc1933ffeb01b6648527
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.1.0 CPython/3.12.11
|