Skip to main content

yfin-client

Compact Python 3.14 Yahoo Finance client returning pyarrow.Table, built on fastreq's curl_cffi backend with browser TLS impersonation (the same trick that makes yahooquery reliable).

Published on PyPI as yfin-client; imported as yfin.

What it does

  • Batch quotes via query1.finance.yahoo.com/v7/finance/quote
  • Chart history (OHLCV + dividends + splits) via query1.finance.yahoo.com/v8/finance/chart/{symbol}
  • Deterministic pyarrow.Table output with explicit schemas
  • Optional Polars conversion via the polars extra
  • Async and sync APIs; sync wrappers fail clearly inside a running event loop
  • Two-strategy Yahoo cookie/crumb authentication (basic + CSRF fallback)
  • Per-proxy-route cookie/crumb isolation (no state leakage between proxies)

What it does NOT do

  • No pandas, numpy, yfinance, yahooquery, requests, pendulum, or lxml
  • No quote summaries, company fundamentals, symbol search, or options
  • No free proxies or bypass/aggressive behavior
  • No compatibility layer for the legacy yfin API

Installation

pip install yfin-client            # core (pyarrow output)
pip install 'yfin-client[polars]'  # with Polars conversion

Requires fastreq>=3.0.0, which is resolved automatically from PyPI.

Usage

import yfin

# Batch quotes
quotes = yfin.quotes(
    ["AAPL", "MSFT"],
    fields=["regularMarketPrice", "regularMarketVolume", "currency"],
)
# pyarrow.Table: symbol, regular_market_price, regular_market_volume, currency

# Historical OHLCV
from datetime import date

history = yfin.history(
    ["AAPL", "MSFT"],
    start=date(2024, 1, 1),
    end=date(2024, 6, 1),
    interval="1d",
)
# pyarrow.Table: symbol, timestamp, open, high, low, close, adjusted_close,
#                volume, dividend, split_ratio, currency, exchange_timezone

# Or use a range instead of dates
history = yfin.history(["AAPL"], period="1y")

# Async equivalents
quotes = await yfin.quotes_async(["AAPL", "MSFT"])
history = await yfin.history_async(["AAPL"], period="1y")

# Optional Polars conversion (requires 'yfin[polars]')
df = yfin.to_polars(history)

Arrow schemas

History

Column Type
symbol string
timestamp timestamp(s, UTC)
open float64
high float64
low float64
close float64
adjusted_close float64
volume int64
dividend float64
split_ratio float64
currency string
exchange_timezone string

Quotes

Column symbol (string) followed by each requested Yahoo field converted from camelCase to snake_case, in caller order. Missing symbols get a null row; missing field values are null. When fields=None, all Yahoo-returned keys are included as snake_case columns.

yfin adopts yahooquery's proven session flow, built on fastreq's curl_cffi backend (no yahooquery or curl_cffi dependency at the API level):

  1. Browser impersonation — every request carries a real browser's TLS fingerprint (JA3/JA4), HTTP/2 settings, and headers via curl_cffi's impersonate feature (a random recent Chrome/Safari/Firefox target per client). This is what keeps Yahoo's bot detection from rate-limiting you.
  2. Warmup — GET https://finance.yahoo.com (redirects followed) seeds the session cookie jar; most consent walls resolve through the redirect chain automatically.
  3. Crumb — one GET to query2.finance.yahoo.com/v1/test/getcrumb per route, cached for the session. If it fails, requests proceed crumb-less: the v8 chart API works without a crumb.
  4. CSRF fallback — if the warmup itself fails, an explicit consent flow (guce consent form parse, collectConsent POST, copyConsent) runs once.

Every API request carries yahooquery's default query parameters (lang=en-US&region=US&corsDomain=finance.yahoo.com) plus the crumb when available. Both quotes (v7) and history (v8/chart) use the query2 host.

Each network route (direct or a specific proxy URL) maintains independent cookie/crumb state. A crumb obtained through one proxy is never sent through another.

Proxy policy

yfin uses fastreq's explicit proxy transport support. It chooses configured proxies round-robin as explicit Yahoo routes so that cookie/crumb state remains bound to the proxy that obtained it. No free proxies are used or offered. Configure proxies explicitly:

client = yfin.YahooClient(proxies=["http://proxy1:8080", "http://proxy2:8080"])
quotes = await yfin.quotes_async(["AAPL"], client=client)

Unofficial endpoints

yfin uses unofficial Yahoo Finance endpoints. These endpoints are not documented, not guaranteed stable, and may change without notice. yfin implements conservative pacing and retry behaviour to minimise the risk of rate-limiting, but cannot guarantee availability.

Testing

All tests are hermetic (no network access required):

uv run pytest -q

A live Yahoo smoke test is available but opt-in only (never required for test success):

YFIN_LIVE_SMOKE=1 uv run pytest tests/test_live_smoke.py -q

Migration from legacy yfin (pre-1.0)

This is a clean rewrite. The legacy API (QuoteSummary, Search, Lookup, validate, pandas DataFrames) has been removed. Key changes:

  • Output is pyarrow.Table, not pandas.DataFrame
  • history() uses interval= (not freq=) and events= (not splits=/dividends=)
  • No QuoteSummary, symbol search, or lookup endpoints
  • No free proxy scraping
  • No pendulum, lxml, numpy, pandas, yfinance, or parallel-requests

Metadata

Release files for yfin-client 1.1.0

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

Source distribution (sdist)

Source distribution for yfin-client 1.1.0
File Size Uploaded Provenance Actions
yfin_client-1.1.0.tar.gz 19.3 kB Without provenance Details for yfin_client-1.1.0.tar.gz

Built distribution (wheel)

Table of built distributions (wheels) for yfin-client 1.1.0
File Interpreter ABI Platform Actions
yfin_client-1.1.0-py3-none-any.whl Python 3 none any Details for yfin_client-1.1.0-py3-none-any.whl

Total release size: 43.2 kB

Release files / yfin_client-1.1.0.tar.gz

Download URL yfin_client-1.1.0.tar.gz
Size 19.3 kB
Tags Source
SHA-256 checksum
How to use checksums
642e82a91b5b2a86bcb557b7cf8db56d6166163998c33f6e33fcdfab26cb41f3
BLAKE2b-256 checksum
How to use checksums
20be852512d705c1df036b344f6c739be49d51fa2bd760077967e6b9fd975ba1
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.14.0

Release files / yfin_client-1.1.0-py3-none-any.whl

Download URL yfin_client-1.1.0-py3-none-any.whl
Size 23.9 kB
Tags Python 3
SHA-256 checksum
How to use checksums
91f59e96dbcdf4400c87226fe71f9adf022b069a805a40fcdcb27b344f627d78
BLAKE2b-256 checksum
How to use checksums
50137ebec760555bdd1635fac0557c7ecf66c342a2a3e04e3cf24de8d81c4187
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.14.0

Security for yfin-client 1.1.0

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.

Release history Release notifications | RSS feed

This release

1.1.0 This release

2 release files No provenance

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