Skip to main content

FMP Data Client

CI Release codecov Python Poetry License: MIT

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:

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: Open In Colab

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

  1. Clone the repository:
git clone https://github.com/MehdiZare/fmp-data.git
cd fmp-data
  1. Install dependencies using Poetry:
poetry install
  1. 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

  1. Fork the repository
  2. Create a feature branch: git checkout -b feature-name
  3. Make your changes
  4. Run tests: poetry run pytest
  5. 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

Examples

Interactive Notebooks

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.

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

fmp_data-0.3.3.post10.tar.gz (139.7 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

fmp_data-0.3.3.post10-py3-none-any.whl (169.1 kB view details)

Uploaded Python 3

File details

Details for the file fmp_data-0.3.3.post10.tar.gz.

File metadata

  • Download URL: fmp_data-0.3.3.post10.tar.gz
  • Upload date:
  • Size: 139.7 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.1.0 CPython/3.12.11

File hashes

Hashes for fmp_data-0.3.3.post10.tar.gz
Algorithm Hash digest
SHA256 67be6f7b0a7efb010b7acc5f798770b04ab66241e3b4760727eb30afd5424bda
MD5 f872d714a3aa37d92d1315ddb844de9b
BLAKE2b-256 d340eb1769fbf77e236230474f0816c7708d80bd50605ed061018dca6495ba1a

See more details on using hashes here.

File details

Details for the file fmp_data-0.3.3.post10-py3-none-any.whl.

File metadata

  • Download URL: fmp_data-0.3.3.post10-py3-none-any.whl
  • Upload date:
  • Size: 169.1 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.1.0 CPython/3.12.11

File hashes

Hashes for fmp_data-0.3.3.post10-py3-none-any.whl
Algorithm Hash digest
SHA256 25e866c642d28c197ece2a3ca9160593e436451ae637a0b7ff3c3bef629c34ef
MD5 4840e38715083538c9678f401705c762
BLAKE2b-256 3ab4e0c887ff7c3076f125462d828f0a39797ba8222dcc1933ffeb01b6648527

See more details on using hashes here.

Release history Release notifications | RSS feed

2.7.1

2 files

2.7.0

2 files

2.6.0

2 files

2.5.0

2 files

2.4.0

2 files

2.3.1

2 files

2.3.0

2 files

2.2.1

2 files

2.2.0

2 files

2.1.8

2 files

2.1.7

2 files

2.1.6

2 files

2.1.5

2 files

2.1.4

2 files

2.1.3

2 files

2.1.2

2 files

2.1.1

2 files

2.1.0

2 files

2.0.0

2 files

1.0.2

2 files

1.0.1

2 files

0.5.2

2 files

0.3.4.post8

2 files

This release

0.3.3.post10 This release

2 files

0.3.1

2 files

0.3.0

2 files

0.2.0

2 files

0.1.2

2 files

0.1.0

2 files

0.0.0.post1

2 files

0.0.0

2 files

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page