Skip to main content

Python client for the Pyth Network Hermes price-oracle API (sync + async, SSE streaming).

Project description

pyth-hermes

CI PyPI version Python versions License: MIT

A typed Python client for the Pyth Network Hermes price-oracle API. Sync and async clients, Pydantic v2 models, Server-Sent-Events price streaming with auto-reconnect, and a Decimal price helper.

  • Sync (HermesClient) and async (AsyncHermesClient) APIs over httpx
  • SSE streaming with reconnect + backoff
  • Graceful 429 rate-limit handling (retries that respect the 60s window)
  • Configurable base_url (production, beta, or paid providers) and optional API key from day one
  • mypy --strict clean, fully type-hinted, ships py.typed

Install

pip install pyth-hermes
# with the optional pandas helper:
pip install "pyth-hermes[pandas]"

Quickstart — BTC/USD price in under 5 lines

from pyth_hermes import HermesClient

client = HermesClient()
feed_id = client.get_feed_id("Crypto.BTC/USD")   # exact-symbol lookup
print(client.get_price_decimal(feed_id))         # -> Decimal("63952.82...")

Async + streaming

import asyncio
from pyth_hermes import AsyncHermesClient

BTC = "e62df6c8b4a85fe1a67db44dc12de5db330f7ac66b72dc658afedf0f4a415b43"

async def main():
    async with AsyncHermesClient() as client:
        async for update in client.stream_prices([BTC]):
            print(update.parsed[0].to_decimal())

asyncio.run(main())

Historical price

resp = client.get_price_at(1718900000, [BTC])   # unix timestamp
print(resp.parsed[0].to_decimal())

pandas

from pyth_hermes.pandas import updates_to_dataframe
df = updates_to_dataframe([client.get_latest_price([BTC])])

Prices and exponents

Pyth returns integer prices plus an exponent. The real value is price * 10**expo, computed exactly as a Decimal:

from pyth_hermes import price_to_decimal
price_to_decimal(6395282153102, -8)   # Decimal("63952.82153102")

RpcPrice.to_decimal() and ParsedPriceUpdate.to_decimal() are convenience wrappers.

Finding feed ids — use the EXACT symbol

/v2/price_feeds?query=btc returns deprecated / variant feeds (e.g. MBTC, XBTC) before the canonical one and matches substrings. get_feed_id() therefore matches on exact attributes.symbol:

client.get_feed_id("Crypto.BTC/USD")
# -> "e62df6c8b4a85fe1a67db44dc12de5db330f7ac66b72dc658afedf0f4a415b43"

🔴 Authentication (changes 2026-07-31)

Today the public endpoint needs no API key. From 2026-07-31 an API key becomes mandatory. This client accepts one from day one — pass it now to be ready:

client = HermesClient(api_key="YOUR_KEY")  # default: Authorization: Bearer YOUR_KEY

The exact header is not finalized publicly, so both the header name and scheme are configurable:

HermesClient(api_key="KEY", api_key_header="X-Api-Key", api_key_scheme="")  # -> X-Api-Key: KEY

Endpoints / base URLs

from pyth_hermes import HermesClient

HermesClient()                                           # production: https://hermes.pyth.network
HermesClient(base_url="https://hermes-beta.pyth.network")  # beta
HermesClient(base_url="https://your-paid-provider.example")  # Triton / P2P / extrnode / Liquify

You may also inject your own preconfigured httpx.Client / httpx.AsyncClient via client=... (e.g. for custom transports, proxies, or connection pools). In that case the request host is taken from your client, so set base_url on the client itself — passing both base_url= and client= raises a UserWarning because the constructor's base_url would be a no-op. The api_key is still applied per-request, so it works with an injected client.

import httpx
from pyth_hermes import HermesClient

http = httpx.Client(base_url="https://your-paid-provider.example", proxy="http://localhost:8080")
client = HermesClient(api_key="KEY", client=http)  # base_url comes from `http`

Rate limits

The public endpoint allows 10 requests / 10 seconds per IP. Exceeding it returns HTTP 429 for the next 60 seconds. The client retries 429 and 5xx responses with exponential backoff + jitter, honoring any Retry-After header and never exceeding the 60s rate-limit window per delay. Tune via max_retries, backoff_base, backoff_cap.

Not implemented

The TWAP endpoints (/v2/updates/twap/...) are intentionally omitted — the API returns HTTP 400 "deprecated and no longer available".

Development

pip install -e ".[dev]"
pytest                 # unit tests (no network)
pytest -m integration  # live smoke tests against production
mypy
ruff check .

License

MIT

Project details


Download files

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

Source Distribution

pyth_hermes-0.1.1.tar.gz (21.7 kB view details)

Uploaded Source

Built Distribution

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

pyth_hermes-0.1.1-py3-none-any.whl (18.4 kB view details)

Uploaded Python 3

File details

Details for the file pyth_hermes-0.1.1.tar.gz.

File metadata

  • Download URL: pyth_hermes-0.1.1.tar.gz
  • Upload date:
  • Size: 21.7 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.13.9

File hashes

Hashes for pyth_hermes-0.1.1.tar.gz
Algorithm Hash digest
SHA256 db022f6d588e4ef593c4e89db34056a8c242d443fa4d42157a35968d8fe18a9f
MD5 86831e769134cbdc137a3296304a64c7
BLAKE2b-256 76922255f959c9b196ffd9cb696fac018e38c6d3f10ef9cc37061b28557ed6e6

See more details on using hashes here.

File details

Details for the file pyth_hermes-0.1.1-py3-none-any.whl.

File metadata

  • Download URL: pyth_hermes-0.1.1-py3-none-any.whl
  • Upload date:
  • Size: 18.4 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.13.9

File hashes

Hashes for pyth_hermes-0.1.1-py3-none-any.whl
Algorithm Hash digest
SHA256 327381b82262ba59a26d88b641ba348ec9faea129f4125bc017fcb5534b92441
MD5 46d245688327c057543ec963cad70eb4
BLAKE2b-256 b13ac49feb6fa1b8b25f5a8ff040e318d9d83ca66bff75e07c023794a63c6a40

See more details on using hashes here.

Supported by

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