Skip to main content

Real-time pulse of Polymarket — an order book feed that never freezes.

Project description

polypulse

PyPI CI License: MIT

Real-time pulse of Polymarket — an order book feed that never freezes.

polypulse keeps a live, in-memory Polymarket order book over WebSocket, so reading the best bid/ask is instant — with no per-read network round-trip. REST /book polling pays its latency on every read (≈185 ms from a typical host, ≈19 ms warm when colocated); polypulse pays a one-time subscribe, then updates are pushed. It adds the production reliability the official tooling lacks: heartbeat, a PONG-aware watchdog that detects the silent WS freeze (issue #292), exponential-backoff reconnect, and an optional REST fallback.

Install

pip install polypulse

Quickstart

import asyncio
from polypulse import BookFeed

async def main():
    feed = BookFeed(["<token_id>"])
    asyncio.create_task(feed.run())   # connects, reconnects, self-heals
    await asyncio.sleep(2)
    print(feed.best_bid("<token_id>"), feed.mid("<token_id>"))  # 0 ms, in-memory
    feed.stop()

asyncio.run(main())

Discover markets

No token_id yet? Find active markets and their tokens via the Gamma API:

from polypulse import list_markets, tokens_for_slug, BookFeed

markets = list_markets(tag="weather")              # active markets (tag is optional)
tokens = tokens_for_slug(markets, markets[0].slug) # the token ids for one market
feed = BookFeed(tokens)                             # ...now stream them

Or from the terminal:

polypulse markets --tag weather

Why

REST /book polling pays per-read latency and serves a book that is ~1 s stale. Polymarket's WebSocket can also silently freeze — the connection stays open but events stop. polypulse pushes updates as the book changes (no per-read latency) and guarantees liveness with a watchdog that reconnects the moment the socket goes quiet.

API

BookFeed(token_ids, on_update=None, *, ping_interval=10, watchdog_timeout=30, rest_fallback=True, max_backoff=30, rest_poll_interval=1.0, logger=None)

  • best_bid / best_ask / mid / spread (token_id) — sync, no network
  • book(token_id) — full-depth OrderBook snapshot
  • staleness(token_id), source(token_id) — freshness introspection
  • await run() / stop()

Behavior notes

  • Reads are synchronous and never hit the network — they return whatever the background run() task has most recently applied.
  • source(token_id) is "ws" when the latest update came from the live socket, or "rest" when it came from the REST fallback (used only while the WS is down). staleness(token_id) is seconds since that token last updated.
  • on_update fires on WebSocket events only. While the socket is down, the REST fallback keeps the book fresh for readers (best_bid etc.) but does not invoke the callback; on reconnect you get a fresh book snapshot (which does fire it).
  • stop() signals shutdown and closes the active connection so run() returns promptly.

Benchmark

python -m polypulse benchmark

It picks a live market and compares REST /book time-to-first-byte against the WebSocket feed. Example run (from a non-colocated host — your absolute numbers depend on where you run it):

market: highest-temperature-in-karachi-on-june-29-2026  (11 tokens)
REST /book TTFB: median 184.5ms  min 124.4  max 238.3  (n=8)
WS subscribe → first book: 220.6ms
WS updates in 30s: 130 (4.3/s)

=== verdict ===
REST pays ~185ms EVERY read; WS pays 221ms ONCE, then updates are PUSHED (no per-read latency).

Absolute latency drops sharply when colocated (a eu-west-2 host measured ~19 ms warm REST GETs), but the structural win holds everywhere: REST pays its round-trip on every read; the WS feed pays once.

Watch a live book

polypulse watch <token_id>

Prints top-of-book once a second — a quick sanity check that the feed is live:

3414098972...  bid=0.012  ask=0.024  mid=0.018  src=ws
3414098972...  bid=0.012  ask=0.024  mid=0.018  src=ws

Values tick as the market moves; src shows ws or rest (REST fallback). An animated GIF reads even better here — record one to drop in.

Honest note

polypulse was extracted from a live Polymarket trading bot. The trading edge didn't pan out, but the low-latency feed is solid and battle-tested — so here it is. Out of scope (for now): generic multi-CLOB support, book integrity hashing, indicators.

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

polypulse-0.1.0.tar.gz (17.7 kB view details)

Uploaded Source

Built Distribution

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

polypulse-0.1.0-py3-none-any.whl (14.1 kB view details)

Uploaded Python 3

File details

Details for the file polypulse-0.1.0.tar.gz.

File metadata

  • Download URL: polypulse-0.1.0.tar.gz
  • Upload date:
  • Size: 17.7 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for polypulse-0.1.0.tar.gz
Algorithm Hash digest
SHA256 22d6c9066af91b69e73edf3cadcbcfefcd9ef9a3a1cbd3b7839c2a3e501af028
MD5 3256de0f25bca64f904b467c17c06a72
BLAKE2b-256 22cc29730080ec70bca1637110a99ff6d181f463b307bb7df1edd02838fc2012

See more details on using hashes here.

Provenance

The following attestation bundles were made for polypulse-0.1.0.tar.gz:

Publisher: publish.yml on Gavr625/polypulse

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file polypulse-0.1.0-py3-none-any.whl.

File metadata

  • Download URL: polypulse-0.1.0-py3-none-any.whl
  • Upload date:
  • Size: 14.1 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for polypulse-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 b98588f1f2b4cbe625671319b91a5841d2db52e65171d2fcc9807c583c02f335
MD5 d8f0f6db6a87ff4fe03fe67e448c4724
BLAKE2b-256 2c5de0617d2bc3673f0c53daee6a9d6975c66997c7a905fb0cbf1c00c29cad45

See more details on using hashes here.

Provenance

The following attestation bundles were made for polypulse-0.1.0-py3-none-any.whl:

Publisher: publish.yml on Gavr625/polypulse

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

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