Skip to content

FMP Data

A robust Python client for Financial Modeling Prep API with comprehensive features including rate limiting, retry strategies, async support, and full type safety. Now with 100% coverage of the FMP stable endpoint catalog.

Features

Core Features - Rate limiting with automatic backoff - Retry strategies for failed requests - Comprehensive error handling - Async/await support - Opt-in response caching with memory, file, and Redis backends - Full type hints with Pydantic validation

🏢 API Coverage - Full coverage of FMP stable endpoints - Company profiles and financial data - Market data and quotes - Fundamental analysis (financial statements, ratios, metrics) - Technical analysis indicators - Market intelligence and research - Institutional holdings and insider trading - Investment funds data - Alternative markets data - Economic indicators - Batch market data - Earnings call transcripts - SEC filings and company profiles - Index constituents and historical changes

🔧 Developer Experience - Intuitive client interface with property-based access - Structured logging with configurable handlers - Environment-based configuration - LangChain integration for AI applications - Python 3.10-3.14 support

Quick Start

Installation

pip install fmp-data

For Redis-backed caching:

pip install "fmp-data[cache-redis]"

For LangChain integration:

pip install "fmp-data[langchain]"

LangChain integration requires LangChain v1 (langchain-core, langchain-openai) and LangGraph v1.

Basic Usage

from fmp_data import FMPDataClient

# Initialize from environment variables
with FMPDataClient.from_env() as client:
    # Get company profile
    profile = client.company.get_profile("AAPL")
    print(f"Company: {profile.company_name}")

    # Get financial statements
    income = client.fundamental.get_income_statement("AAPL", period="annual")
    print(f"Revenue: ${income[0].revenue:,.0f}")

    # Get market data
    quote = client.company.get_quote("AAPL")
    print(f"Current Price: ${quote.price}")

Async Usage

For async applications, use AsyncFMPDataClient:

import asyncio
from fmp_data import AsyncFMPDataClient

async def main():
    async with AsyncFMPDataClient.from_env() as client:
        # All methods are async - same names as sync client
        profile = await client.company.get_profile("AAPL")
        print(f"Company: {profile.company_name}")

        # Fetch multiple items concurrently
        quote, income = await asyncio.gather(
            client.company.get_quote("AAPL"),
            client.fundamental.get_income_statement("AAPL", period="annual")
        )
        print(f"Price: ${quote.price}, Revenue: ${income[0].revenue:,.0f}")

asyncio.run(main())

Response Caching

from fmp_data import CacheConfig, ClientConfig, FMPDataClient

config = ClientConfig(
    api_key="YOUR_FMP_API_KEY",  # pragma: allowlist secret
    cache=CacheConfig(
        backend="file",
        default_ttl=300,
        cache_dir=".cache/fmp-data",
        ttl_overrides={"get_quote": 30},
    ),
)

with FMPDataClient(config=config) as client:
    quote = client.company.get_quote("AAPL")
    fresh_quote = client.company.get_quote("AAPL", force_refresh=True)

Environment Configuration

Create a .env file in your project root:

FMP_API_KEY=your_api_key_here
FMP_TIMEOUT=30
FMP_MAX_RETRIES=3
# Note: Do NOT include /api in the base URL - it's added automatically
FMP_BASE_URL=https://financialmodelingprep.com
FMP_CACHE_ENABLED=true
FMP_CACHE_BACKEND=memory
FMP_CACHE_TTL=300

Use FMP_CACHE_DIR for the file backend and FMP_CACHE_REDIS_URL for the Redis backend.

Error Handling

from fmp_data import FMPDataClient
from fmp_data.exceptions import RateLimitError, AuthenticationError

try:
    with FMPDataClient.from_env() as client:
        profile = client.company.get_profile("AAPL")
except RateLimitError as e:
    print(f"Rate limit exceeded. Retry after: {e.retry_after}s")
except AuthenticationError:
    print("Invalid API key")

API Client Structure

Both FMPDataClient (sync) and AsyncFMPDataClient (async) provide organized access to different data categories through the same interface:

# Sync client
client = FMPDataClient.from_env()

# Async client (same structure, async methods)
async_client = AsyncFMPDataClient.from_env()

# Both clients provide access to these endpoint groups:
client.company.*        # Company data, quotes, and historical prices
client.market.*         # Market movers, hours, and listings/search
client.fundamental.*    # Fundamental analysis
client.technical.*      # Technical analysis
client.intelligence.*   # Market intelligence
client.institutional.*  # Institutional data
client.investment.*     # Investment funds
client.alternative.*    # Alternative markets
client.economics.*      # Economic data
client.batch.*          # Batch data operations
client.transcripts.*    # Earnings call transcripts
client.sec.*            # SEC filings
client.index.*          # Index constituents

Documentation

Examples

Financial Analysis

with FMPDataClient.from_env() as client:
    # Get comprehensive financial data
    symbol = "AAPL"

    # Company overview
    profile = client.company.get_profile(symbol)

    # Financial statements (last 5 years)
    income_statements = client.fundamental.get_income_statement(symbol, limit=5)
    balance_sheets = client.fundamental.get_balance_sheet(symbol, limit=5)
    cash_flows = client.fundamental.get_cash_flow(symbol, limit=5)

    # Key metrics and ratios
    metrics = client.fundamental.get_key_metrics(symbol, limit=5)
    ratios = client.fundamental.get_financial_ratios(symbol, limit=5)

    # Valuation
    dcf = client.fundamental.get_discounted_cash_flow(symbol)

Market Monitoring

with FMPDataClient.from_env() as client:
    # Market overview
    market_hours = client.market.get_market_hours()
    sector_performance = client.market.get_sector_performance()

    # Top movers
    gainers = client.market.get_gainers()
    losers = client.market.get_losers()
    active = client.market.get_most_active()

    # Company search
    results = client.market.search_company("technology")

Async Concurrent Requests

import asyncio
from fmp_data import AsyncFMPDataClient

async def analyze_portfolio(symbols: list[str]):
    async with AsyncFMPDataClient.from_env() as client:
        # Fetch all profiles concurrently
        profiles = await asyncio.gather(
            *[client.company.get_profile(symbol) for symbol in symbols]
        )

        # Fetch all quotes concurrently
        quotes = await asyncio.gather(
            *[client.company.get_quote(symbol) for symbol in symbols]
        )

        for profile, quote in zip(profiles, quotes):
            print(f"{profile.symbol}: ${quote.price:,.2f} ({profile.sector})")

asyncio.run(analyze_portfolio(["AAPL", "MSFT", "GOOGL", "AMZN"]))

Getting Help

License

This project is licensed under the MIT License - see the LICENSE file for details.