Skip to main content

Real-time Polymarket CLOB WebSocket streaming for Python

Project description

polyws

Real-time Polymarket data streaming for Python. Built for trading bots, data pipelines, and AI agents.

pip install polyws
polyws stream --markets 10
from polyws import WSSubscriptionManager, WebSocketHandlers

stream = WSSubscriptionManager(WebSocketHandlers(
    on_polymarket_price_update=lambda events: [
        print(f"{e.asset_id[:16]}{float(e.price)*100:.1f}%") for e in events
    ]
))
await stream.add_subscriptions(["<asset-id>"])

Why polyws?

Polymarket has two APIs, no official Python streaming library, and a multi-step lookup just to get real-time prices. polyws solves all of that.

The problem

To stream live Polymarket data in Python today, you need to:

  1. Query the Gamma API to discover markets and extract clobTokenIds
  2. Connect to the CLOB WebSocket with a handshake protocol
  3. Manage subscriptions, reconnections, and ping/pong keepalive
  4. Maintain an order book cache to compute display prices
  5. Implement Polymarket's price calculation logic (midpoint when spread ≤ $0.10, last trade price otherwise)

That's ~500 lines of async boilerplate before you write a single line of business logic.

What polyws gives you

stream = WSSubscriptionManager(handlers)
await stream.add_subscriptions(asset_ids)
# Done. Events flow to your handlers.
  • Automatic WebSocket connection, reconnection, and keepalive
  • Subscription batching with event-driven flush (no polling)
  • Order book cache with sorted bid/ask levels
  • Derived display prices matching the Polymarket UI
  • CLI for discovery and streaming without writing code
  • JSON Lines output for piping into other tools and agents

How it compares

polyws poly-websockets (TS) py-clob-client (official) polymarket-cli (Rust)
Language Python TypeScript Python Rust
Real-time streaming WebSocket WebSocket REST only REST only
Auto-reconnect Event-driven Polling (5s interval) N/A N/A
Subscription flush Instant (asyncio.Event) Polling (100ms interval) N/A N/A
Display price logic Built-in Built-in Manual Manual
Order book cache bisect.insort Full re-sort None None
CLI polyws markets/stream None None Full trading CLI
Agent-friendly output JSON Lines (auto-detect) None None --output json
Trading / orders No No Yes Yes
Runtime deps 2 5 8+ N/A (binary)
Install pip install npm install pip install brew install

polyws is not a trading client. It does one thing — real-time data streaming — and does it well. Use it alongside py-clob-client for a complete Python trading stack.


CLI

Browse markets

# Top 20 markets by volume
polyws markets

# Search
polyws markets --search "bitcoin" --limit 5

# Sort options: volume (default), liquidity, newest
polyws markets --sort liquidity --limit 10

Stream real-time data

# Stream top 10 markets
polyws stream --markets 10

# Stream specific assets
polyws stream --asset-id 4655345557056451798919...

# Search and stream
polyws stream --search "election"

Output format

polyws auto-detects the output context:

  • Terminal (TTY): Human-readable, formatted, colored
  • Piped / redirected: JSON Lines — one JSON object per line
# Human output
polyws markets --limit 3

#  99.7%  $58.7M  Will there be no change in Fed rates...  [10255981...]
#   0.2%  $53.5M  Will the Fed decrease rates by 25...     [62938043...]
#   0.1%  $48.3M  Will the Fed decrease rates by 50+...    [46553455...]

# Machine output (piped)
polyws markets --limit 1 | jq .
# {"asset_id": "102559...", "question": "Will there be...", "volume": 58739675, "price": "0.9965"}

This makes polyws natively usable by AI agents — pipe the output, parse the JSON, act on it.


Library API

WSSubscriptionManager

from polyws import WSSubscriptionManager, WebSocketHandlers

handlers = WebSocketHandlers(
    on_book=my_book_handler,
    on_price_change=my_change_handler,
    on_last_trade_price=my_trade_handler,
    on_tick_size_change=my_tick_handler,
    on_polymarket_price_update=my_price_handler,  # Derived display price
    on_error=my_error_handler,
    on_ws_open=my_open_handler,
    on_ws_close=my_close_handler,
)

manager = WSSubscriptionManager(handlers, reconnect_interval_s=5.0)

All handlers are async, optional, and receive a list of typed events.

Method Description
await add_subscriptions(ids) Subscribe to assets. Connects automatically.
await remove_subscriptions(ids) Unsubscribe from assets.
get_asset_ids() List all monitored assets.
get_statistics() Connection stats (open_websockets, asset_ids, pending_subscribe, pending_unsubscribe).
await clear_state() Full teardown. Manager is reusable after.

Market Discovery

from polyws import fetch_markets, extract_asset_ids

markets = fetch_markets(limit=10, sort="volume", search="crypto")
assets = extract_asset_ids(markets)  # {asset_id: question, ...}

Event Types

Event When Key Fields
BookEvent Full order book snapshot on subscribe bids, asks, asset_id
PriceChangeEvent Order book level added/removed/updated price_changes[].side, price, size
LastTradePriceEvent A trade executes price, side, size
TickSizeChangeEvent Tick size changes old_tick_size, new_tick_size
PolymarketPriceUpdateEvent Derived display price changes price, midpoint, spread, triggering_event

How display prices work

Polymarket doesn't show raw bid/ask prices. It shows a derived price:

  • If bid-ask spread ≤ $0.10 → display the midpoint
  • If bid-ask spread > $0.10 → display the last trade price

on_polymarket_price_update fires whenever this derived price changes. This matches what you see on polymarket.com.


For AI Agents

polyws is designed as a tool for AI agents that need real-time market intelligence.

As a CLI tool:

# Agent discovers markets about a topic
polyws markets --search "AI" --limit 5 | jq -r '.question'

# Agent monitors prices and acts on thresholds
polyws stream --search "bitcoin" | while read line; do
  price=$(echo "$line" | jq -r 'select(.event=="price_update") | .price')
  # ... agent logic ...
done

As a Python library:

# Agent builds a real-time market monitor
from polyws import WSSubscriptionManager, WebSocketHandlers, fetch_markets, extract_asset_ids

markets = fetch_markets(search="election", limit=20)
assets = extract_asset_ids(markets)

async def on_update(events):
    for e in events:
        if float(e.price) > 0.9:
            await alert(f"High confidence: {assets[e.asset_id]} at {e.price}")

mgr = WSSubscriptionManager(WebSocketHandlers(on_polymarket_price_update=on_update))
await mgr.add_subscriptions(list(assets.keys()))

Why agents prefer polyws over alternatives:

  • JSON Lines output — no parsing HTML or tables
  • Zero config — no API keys needed for read-only streaming
  • Predictable schema — every event is typed and documented
  • Instant — WebSocket, not polling REST endpoints
  • Composable — pipe into jq, grep, other tools, or import as a library

Architecture

polyws/
├── src/polyws/
│   ├── types.py        # Typed dataclasses for all events
│   ├── order_book.py   # Sorted order book cache (bisect.insort)
│   ├── manager.py      # WebSocket lifecycle, reconnect, flush
│   ├── gamma.py        # Gamma API market discovery
│   ├── cli.py          # CLI entry point (argparse)
│   └── logger.py       # stdlib logging
├── tests/              # 53 unit + integration tests
└── examples/           # Ready-to-run scripts

Runtime dependencies: websockets, orjson. That's it.

Python: >= 3.11


Development

git clone https://github.com/<org>/polyws.git
cd polyws
python -m venv .venv && source .venv/bin/activate
pip install -e ".[dev]"

# Run tests
pytest

# Run live integration test (requires network)
pytest -m live

Inspired by

poly-websockets by Nevua Markets — the TypeScript library that pioneered this approach. polyws is a Python rewrite with performance improvements (event-driven flush, bisect-based order book) and a CLI layer for agents and humans.

License

MIT

Disclaimer

This software is provided "as is", without warranty of any kind. The authors are not responsible for any financial losses, trading decisions, or system failures. Polymarket data is provided by Polymarket's public APIs. Use at your own risk.

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

polyws-0.2.0.tar.gz (21.2 kB view details)

Uploaded Source

Built Distribution

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

polyws-0.2.0-py3-none-any.whl (16.9 kB view details)

Uploaded Python 3

File details

Details for the file polyws-0.2.0.tar.gz.

File metadata

  • Download URL: polyws-0.2.0.tar.gz
  • Upload date:
  • Size: 21.2 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for polyws-0.2.0.tar.gz
Algorithm Hash digest
SHA256 e281bbe661175872e5d93d2998919a775d22755957701707797bfe57bd984a2a
MD5 50750ac4041d86ab2902fe4c05594cbc
BLAKE2b-256 cb8c65d11f9d4a9c99241e01587242f435aa8106adbe2f957568ca90ef4cd8cc

See more details on using hashes here.

Provenance

The following attestation bundles were made for polyws-0.2.0.tar.gz:

Publisher: ci.yml on davidamom/polyws

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

File details

Details for the file polyws-0.2.0-py3-none-any.whl.

File metadata

  • Download URL: polyws-0.2.0-py3-none-any.whl
  • Upload date:
  • Size: 16.9 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for polyws-0.2.0-py3-none-any.whl
Algorithm Hash digest
SHA256 de15535476af4f8739292dd933274b7c22e695005464f1a21f6f23c1e09afa05
MD5 cc4bead41797fc8716b265f5c5033337
BLAKE2b-256 a8e953037f7d5864210d2c119b6f6290fcf92b11b8f2a88b97edb1a09868c861

See more details on using hashes here.

Provenance

The following attestation bundles were made for polyws-0.2.0-py3-none-any.whl:

Publisher: ci.yml on davidamom/polyws

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