Skip to main content

one-finance-data

Unified financial data client for Python. Abstracts FMP, Finnhub, Twelve Data, Yahoo Finance, Alpha Vantage, and Massive (formerly Polygon.io) behind a single interface with transparent disk-based caching and a CLI designed for agents and automation.

PyPI Python 3.12+

Installation

pip install onefinance

The ofclient CLI is included. If you're on a system with an externally-managed Python (e.g. Homebrew), install as a tool instead:

uv tool install onefinance   # installs ofclient on your PATH
uv tool upgrade onefinance   # upgrade later

Development install

git clone https://github.com/yishanhe/one-finance-data
cd one-finance-data
uv sync --all-extras

Setup

API keys

Each provider requires its own API key. Set the relevant variables in your environment before running the client or CLI. Providers whose key is absent are skipped automatically — YFinanceProvider (no key needed) is always available as a fallback.

export FMP_API_KEY="your_key"           # https://financialmodelingprep.com/developer
export FINNHUB_API_KEY="your_key"       # https://finnhub.io
export TWELVE_DATA_API_KEY="your_key"   # https://twelvedata.com
export ALPHAVANTAGE_API_KEY="your_key"  # https://www.alphavantage.co
export MASSIVE_API_KEY="your_key"       # https://massive.com (formerly Polygon.io)

Persist them in your shell profile (~/.zshrc, ~/.bashrc) or use a .env file with a tool like direnv.

Variable Provider Free tier
FMP_API_KEY Financial Modeling Prep 250 req/day
FINNHUB_API_KEY Finnhub 60 req/min
TWELVE_DATA_API_KEY Twelve Data 800 req/day
ALPHAVANTAGE_API_KEY Alpha Vantage 25 req/day
MASSIVE_API_KEY Massive (formerly Polygon.io) Unlimited calls; 15-min delayed data. Legacy POLYGON_API_KEY still honored
(none) SEC EDGAR No key; free. Optional EDGAR_USER_AGENT contact string; 10 req/s

CLI environment overrides

Variable Effect
OFCLIENT_OUTPUT Default output format (json, table, csv)
OFCLIENT_NO_CACHE Set 1 to bypass cache on all calls
OFCLIENT_DRY_RUN Set 1 to dry-run all calls
OFCLIENT_CONFIG Path to a custom config YAML file

Python usage

from onefinance.core.client import OneFinanceClient
from datetime import date

# Reads API keys from environment; builds all available providers automatically
with OneFinanceClient() as client:
    # Price history — cached 30 days (historical) or 6 h (after market close)
    bars = client.get_price_history("AAPL", date(2024, 1, 1), date(2024, 12, 31))

    # Live quote — cached 30 seconds
    quote = client.get_quote("AAPL")

    # Batch quotes for multiple symbols — uses native batch endpoints where available
    quotes = client.get_quotes(["AAPL", "MSFT", "GOOG"])

    # Company info — cached 30 days
    info = client.get_info("AAPL")

    # Financial statements
    income = client.get_financials("AAPL", statement="income", period="annual")

    # Ratios — cached once per trading day (date-keyed); use fresh=True for intraday refresh
    ratios = client.get_ratios("AAPL", period="annual", fresh=True)

    # Earnings history
    earnings = client.get_earnings("AAPL")

    # Insider trades
    trades = client.get_insider_trades("AAPL")

    # News
    articles = client.get_news("AAPL")

    # Options chain
    expirations = client.get_options_expirations("AAPL")
    chain = client.get_option_chain("AAPL", expiration=expirations[0])

    # Analyst data
    analyst = client.get_analyst_data("AAPL")

    # Earnings calendar
    calendar = client.get_earnings_calendar(start=date(2026, 7, 1), end=date(2026, 7, 31))

    # DCF valuation
    dcf = client.get_dcf("AAPL")

    # Options analytics (put/call ratio, open interest aggregates)
    analytics = client.get_options_analytics("AAPL")

    # Short interest and days-to-cover
    short = client.get_short_interest("AAPL")

    # Market-wide sentiment (put/call ratio)
    market_sentiment = client.get_market_sentiment()

Per-call overrides

bars = client.get_price_history(
    "AAPL",
    date(2024, 1, 1),
    date(2024, 12, 31),
    no_cache=True,  # bypass cache for this call
    provider="finnhub",  # force a specific provider
    ttl=3600,  # custom TTL in seconds
)

CLI usage

# Discovery
ofclient capabilities --availability  # local routes, plan gates, cooldowns
ofclient capabilities         # machine-readable command manifest (JSON)
ofclient version              # package + schema version

# Market data
ofclient price AAPL --range 1y
ofclient price AAPL --start 2024-01-01 --end 2024-12-31
ofclient quote AAPL
ofclient quotes AAPL MSFT GOOG              # batch quotes for multiple symbols
ofclient quotes AAPL,MSFT,GOOG              # comma-separated symbols also accepted
ofclient quotes AAPL MSFT --enrich          # fill missing fields via single-quote routes

# Fundamentals
ofclient financials AAPL --statement income --period annual
ofclient info AAPL
ofclient insiders AAPL --since 2024-01-01
ofclient ratios AAPL --period annual --fresh
ofclient earnings AAPL
ofclient estimates AAPL                     # forward-looking analyst estimates

# Technical analysis
ofclient indicators AAPL                    # MA, MACD, RSI, ATR, bias, trend
ofclient indicators AAPL --range 1y

# Alternative data
ofclient news AAPL
ofclient actions AAPL                       # dividends and splits
ofclient holders AAPL                       # institutional holders
ofclient analyst AAPL                       # price targets and ratings
ofclient options-analytics AAPL            # put/call ratio, open interest aggregates
ofclient short-interest AAPL               # short interest and days-to-cover
ofclient sentiment                          # market-wide put/call ratio

# Options
ofclient options AAPL                       # list available expiration dates
ofclient options AAPL --expiration 2026-06-20   # full options chain

# Market-wide
ofclient screen "sector=Technology"
ofclient sector technology
ofclient calendar                           # upcoming earnings releases
ofclient calendar --start 2026-07-01 --end 2026-07-31

# Output formats
ofclient price AAPL --range 1m --format table
ofclient price AAPL --range 1m --format csv

# Dry-run: see cache key and whether a fetch would happen, without fetching
ofclient price AAPL --range 1y --dry-run

# Force a provider or bypass cache
ofclient quote AAPL --provider finnhub --no-cache

# Introspection
ofclient cache stats
ofclient providers status
ofclient providers check                    # validate API keys, instantiation, tier refs
ofclient providers check --ping             # also ping each provider and report latency
ofclient config show
ofclient config init --output ./config.yaml

# Audit log
ofclient audit stats
ofclient audit recent --limit 20 --format table
ofclient audit recent --request-id REQUEST_ID --format table
ofclient audit recent --symbol AAPL --format table
ofclient audit path
ofclient audit follow                       # tail live entries (Ctrl-C to stop)
ofclient audit follow --status error        # stream errors only
ofclient audit truncate --confirm           # permanently clear all entries

Exit codes

Code Meaning
0 Success
1 Invalid argument (bad range, unknown statement, etc.)
2 Provider error or rate limit
3 Endpoint not supported by any configured provider
4 Configuration error (missing API key, bad config file)

Provider coverage

Endpoint FMP Finnhub Twelve Data YFinance Alpha Vantage Massive EDGAR Cboe
get_price_history ✓ ✓* ✓ ✓ ✓ ✓ — —
get_quote ✓ ✓ ✓ ✓ ✓ ✓ — ✓
get_quotes (native batch) — — ✓ — — — — —
get_info ✓ ✓ — ✓ ✓ ✓ — —
get_financials ✓ ✓ — ✓ ✓ — ✓ —
get_ratios ✓ ✓ — ✓ ✓ — — —
get_earnings ✓ ✓ — ✓ ✓ — — —
get_insider_trades ✓ ✓ — ✓ — — — —
get_dcf ✓ — — — — — — —
get_news — ✓ — ✓ ✓ ✓ — —
get_corporate_actions ✓ ✓ — ✓ — ✓ — —
get_institutional_holders ✓ — — ✓ — — — —
get_analyst_data ✓ ✓ — ✓ — — — —
get_options_expirations — — — ✓ — ✓ — —
get_option_chain — — — ✓ — ✓ — —
screen_stocks ✓ — — ✓ — ✓ — —
get_sector_overview — — — ✓ — — — —
get_earnings_calendar ✓ ✓ — ✓ ✓ — — —
get_forward_estimates ✓ ✓ — ✓ — — — —
get_options_analytics — — — ✓ (derived) — — — —
get_short_interest ✓ — — ✓ — — — —
get_market_sentiment — — — — — — — ✓

Note on batch quotes: get_quotes uses Twelve Data's native multi-symbol endpoint when available. For other providers, it fans out concurrent single get_quote calls automatically.

Batch quotes return provider fields without null-fill enrichment. They share the cache used by get_quote(..., enrich=False). Both can reuse enriched single-quote entries without overwriting them. Enriched requests can also reuse lightweight entries when every configured enrichment trigger field is populated. Reuse preserves the original expiry; no_cache=True bypasses it. Use get_quotes(symbols, enrich=True) or ofclient quotes AAPL MSFT --enrich to fill missing fields through concurrent single-quote routes. Each unique symbol has its own audit request ID. Single quotes remain enriched by default. Client symbol inputs are trimmed, uppercased, and validated before routing; pass separate list elements to the Python batch API.

Enrichment records unsupported provider calls in the same negative cache as primary routing. A recent successful filler call prevents a later symbol-specific 402/403 from disabling that provider for every symbol. Providers that declare they cannot populate any missing trigger field are skipped. Invalidating quotes also clears their cached enrichment data.

* Finnhub free-tier returns HTTP 403 for price history; treated as plan restriction (NotSupportedError). Paid plans may work.

Running tests

# Unit tests only (no network)
uv run pytest tests/ -m "not integration"

# All tests including live API calls (requires API keys in env)
uv run pytest tests/ -m integration

# Single test file
uv run pytest tests/unit/test_client.py -v

Audit accounting and availability

audit stats separates logical_requests (unique dispatch request IDs) from provider_attempts. Provider methods may make several HTTP requests internally, so http_calls is unknown (null); total_api_calls remains an alias for provider attempts. HTTP-backed unsupported responses and failed or unused enrichment calls count as attempts. Timed-out enrichment workers record their attempt when they end.

cache_hits counts cached items; cache_hit_rate counts requests served entirely from cache. A batch mixing cached items and provider calls is not fully cached. Stale fallback shares the request ID of its failed provider attempts. request_complete records dispatch latency and success, partial, or error; completed_requests shows coverage because older logs lack completion records. Composite operations can dispatch multiple requests.

For price, quote, and indicators, response metadata.cache_hit reports actual full cache reuse, including covering-range reuse. A miss, bypass, or price-range extension is not a full hit. cache_status summarizes the outcome; cache_requests lists each calculation request's endpoint and outcome (including both history and quote requests for indicators). These fields work with audit-file logging disabled.

Price-history date ranges are inclusive. Daily cache lifetimes are shortened when the latest completed session is missing, and cannot cross the next relevant session boundary. Extensions refresh unfinished boundary bars; indicators use completed daily bars under the existing conservative US/Eastern 16:00 close convention. The cache-key/index version change bypasses older price entries automatically.

Cache diagnostics record bypass, absent_or_expired, range_reuse, range_extension, and compatible_quote, plus cache writes with their TTL. Diskcache removes expired values, so a miss alone cannot distinguish expiry from absence or eviction. Use audit recent --request-id ... to correlate decisions with provider attempts.

capabilities --availability and providers check report configured endpoint routes as unverified, plan_gated, cooldown, or no_provider. They use local configuration and cached failures; an eligible route is not proof of live access. This makes macro-calendar subscription blocks explicit without adding a new feed. providers check --ping checks provider liveness, not every endpoint.

Metadata

Release files for onefinance 0.3.1

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for onefinance 0.3.1
File Size Uploaded Provenance Actions
onefinance-0.3.1.tar.gz 409.0 kB Without provenance Details for onefinance-0.3.1.tar.gz

Built distribution (wheel)

Table of built distributions (wheels) for onefinance 0.3.1
File Interpreter ABI Platform Actions
onefinance-0.3.1-py3-none-any.whl Python 3 none any Details for onefinance-0.3.1-py3-none-any.whl

Total release size: 600.3 kB

Release files / onefinance-0.3.1.tar.gz

Download URL onefinance-0.3.1.tar.gz
Size 409.0 kB
Tags Source
SHA-256 checksum
How to use checksums
734ae85f1c604a5da05a3b7709b265b631fe8366206c9171d968ef3d46f3ec26
BLAKE2b-256 checksum
How to use checksums
5508c7bb225cd80c9030c5ebc0544696d4c38e36574b5c47a892b554839fd288
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via uv/0.11.14 {"installer":{"name":"uv","version":"0.11.14","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

Release files / onefinance-0.3.1-py3-none-any.whl

Download URL onefinance-0.3.1-py3-none-any.whl
Size 191.3 kB
Tags Python 3
SHA-256 checksum
How to use checksums
ef1279beea8e3563d6c0f6b78980ae674f789cde052ccab28682ca1ee6fc19e2
BLAKE2b-256 checksum
How to use checksums
afef53c206a9a26b9dd6f19e25ae7d2dc6cb2dbaffce322b9b113a60cea3adaa
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via uv/0.11.14 {"installer":{"name":"uv","version":"0.11.14","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

Security for onefinance 0.3.1

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

No provenance found

None of the files in this release were uploaded with provenance metadata.

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page