SDKs

Python SDK

fathom-charts handles authentication, the initial snapshot, resuming after a disconnect, duplicates, history pagination, exports and rate-limit retries for you, on asyncio. This page describes every option and method; the behaviour the four SDKs share is in SDKs.

Install

terminal
pip install fathom-charts

Or uv add fathom-charts. Python 3.11 or later, asyncio only: in a notebook (Jupyter), await works at the top level of a cell. Its dependencies are websockets, httpx and zstandard. The package is typed (py.typed): mypy --strict checks your code against it.

Indicator types

terminal
fathom-charts-types https://api.fathomcharts.com/v1/indicators fathom_charts_types.py

The command, installed with the package, takes the catalog’s URL or a file saved from GET /v1/indicators. Each indicator gets <Name>Params and <Name>Data (TypedDict), named after its id (big-trades → BigTradesParams, BigTradesData), with the catalog’s descriptions as docstrings; IndicatorParams, IndicatorData and IndicatorId cover them all. A tuple whose last elements are optional is the union of its allowed lengths (tuple[int, int, int] | tuple[int, int, int, int] for a footprint level); JSON arrays still arrive as lists. Generate the file again when the catalog changes.

Real time: FathomChartsStream

big_trades.py
import asyncio
import os

from fathom_charts import FathomChartsStream, Subscription, Upsert
from fathom_charts_types import BigTradesData


async def main() -> None:
    async with FathomChartsStream(url="wss://stream.fathomcharts.com/v1", api_key=os.environ["FATHOM_CHARTS_API_KEY"]) as stream:
        big_trades: Subscription[BigTradesData]
        async with stream.subscribe(instrument="NQ.front", indicator="big-trades", params={"minimum": 30}, mode="confirmed") as big_trades:
            async for event in big_trades:
                if isinstance(event, Upsert):
                    print(event.cursor, event.data["side"], event.data["volume"])


asyncio.run(main())

Options

Durations are in seconds.

OptionPurpose
urlRequired. The stream address: wss://stream.fathomcharts.com/v1.
api_keyAPI key, sent in the Authorization: Bearer header.
stream_tokenInstead of api_key, in an application distributed to end users, which must not hold the key: an async function returning a fresh single-use token that your backend gets from POST /v1/stream-tokens (FathomChartsRest.stream_token()). It is called on every connection, reconnections included. Give exactly one of api_key and stream_token, otherwise the constructor raises CONFIGURATION.
web_socketOptional: a function that opens the connection, to use another socket; a socket it returns with pausable false takes the max_buffered path below.
reconnectOptional: Reconnect(initial_delay=0.25, max_delay=30.0, quota_retry=120.0, quota_delay=5.0): first reconnection delay, backoff ceiling, how long a 4029 close code is retried, minimum delay between two attempts after a 4029.
heartbeat_timeoutSilence after which the connection is considered lost, then reopened. 15 by default: the server sends an hb every 5 seconds.
high_water_markNumber of events waiting to be read, all subscriptions together, above which the SDK stops reading the socket and keeps only the latest version of each object in progress. While it waits, it sends ping messages so that the server keeps the connection. 10,000 by default.
max_bufferedFor a socket that cannot be paused: number of waiting events above which the SDK closes the connection (close code 4000, reason client buffer full), then reopens it from the last cursor received once half of high_water_mark has been read. Nothing waiting is lost. 4 × high_water_mark by default.
randomOptional, for tests: the source of the reconnection jitter, a function returning a number in [0, 1). random.random by default.
on_state_changeCalled on every change of connection_state.
on_noticeCalled with each notice from the server (kind, id, effective_at, ends_at, message): a restart, a maintenance window announced or cancelled. See Updates and maintenance.

async with FathomChartsStream(…) as stream closes the stream at the end of the block; await stream.close() does the same. stream.connection_state is idle, connecting, open, reconnecting or closed; stream.maintenance lists the maintenance windows announced on the connection and not over, by start.

subscribe()

stream.subscribe(instrument=…, indicator=…, params=None, mode="live", from_="live") opens a subscription and returns a Subscription, to read with async for. Its arguments are those of the subscribe message; from_ (from is a Python keyword) is "live", {"cursor": …, "engine": …} or {"time": …}. The SDK picks the sub name itself. Annotate the result with the indicator’s data type: big_trades: Subscription[BigTradesData].

The events are frozen dataclasses: Subscribed, Snapshot (its items are Item), Upsert, Remove, Status, Reset and Notice, each with its type ("upsert"…), to test with isinstance or match. Their fields are those of Events, in snake case (tick_size_nanos, lag_ms). An error on the subscription ends the loop: async for raises a FathomChartsError carrying the received code.

Subscription

MemberPurpose
cursorThe cursor of the last event handed to you: your resume point. None until a cursor has arrived. It also moves forward with hb messages when no event is waiting to be read.
topicThe topic of the latest subscribed.
engineThe engine of the latest subscribed: the computation your state comes from. Save it with cursor to resume later.
idThe sub name the SDK chose for this subscription (s1, s2…).
requestThe arguments of subscribe(), completed with the default values.
close()Async: stops the subscription; the SDK sends unsubscribe, and a pending loop ends.

Leaving the async with block of a subscription closes it. Leaving an async for loop alone does not, in Python: use async with, or await sub.close(). Reconnection, resuming and close codes: see Connection lifecycle; to resume after your process restarts, see Resume after a restart.

History: FathomChartsRest

PYTHON
from fathom_charts import FathomChartsRest

async with FathomChartsRest(base_url="https://api.fathomcharts.com", api_key=os.environ["FATHOM_CHARTS_API_KEY"]) as rest:
    usage = await rest.usage()
OptionPurpose
base_urlRequired. The API address: https://api.fathomcharts.com.
api_keyRequired. API key, sent in the Authorization: Bearer header.
rate_limit_retriesNumber of retries of a request the server did not process, or of a read that failed (see Rate limit and retries). 3 by default.
http_clientOptional: your own httpx.AsyncClient (proxy, timeouts…).

Methods

Queries are dictionaries with the fields of the API, as on the History page (instrument, indicator, params, from, to, mode, and depending on the method limit, cursor, untilCursor, snapshot): PageQuery and RangeQuery type them. Responses are TypedDicts with the fields of the API.

MethodReturns
await page(query)One page: instrument, tickSizeNanos, snapshot, items, next, computeUnits.
pages(query)The pages one at a time, following next, as you read them (async for).
history(query)The results one at a time, across pages. With "snapshot": True, the first element is the state at from, {"t": "snapshot", "cursor", "items"}, then come the updates (t is upsert or remove, each with its cursor).
await estimate(query)The cost estimate, charging nothing.
await export(query, resume=None)One export response: body (the zstd-compressed file as is), content_type, filename, token (resumes the export with resume).
export_ndjson(query, max_resumes=5, resume_delay=1.0)The decompressed export, in chunks (bytes) of whole lines, with automatic resume. See Exports.
await stream_token()A stream token: token, expiresAt.
await usage()Your usage this month and your limits.
await instruments()instruments: every instrument served.
await status()The state of the computation, of each instrument, and the maintenance windows announced.
await offers()The plans and the limits of each combination.
await indicators()The indicator catalog.

A call is stopped by cancelling its task (asyncio.timeout(), Task.cancel()), a wait for a retry included: the asyncio.CancelledError goes through untouched, as asyncio requires. Close an async generator you leave early (contextlib.aclosing), as with any async generator.

Errors

Every error the SDK raises, or ends a loop with, is a FathomChartsError. Its codes are listed in Errors (ERROR_CODES; the WebSocket close codes, CloseCode).

FieldContent
codeThe stable error code.
messageA human-readable explanation.
statusThe HTTP status, over REST.
close_codeThe WebSocket close code, when the connection was closed.
retry_afterThe value of the Retry-After header, in seconds, when the response has one.
problemThe full problem+json document of the response, with errors when the API lists invalid fields; None otherwise.
__cause__The original error, when there is one (the error of httpx…).

Cursors

PYTHON
from fathom_charts import compare_cursors

compare_cursors("20720.111416.0", "20720.111417.0")  # < 0