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.3.tar.gz (21.9 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.3-py3-none-any.whl (17.7 kB view details)

Uploaded Python 3

File details

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

File metadata

  • Download URL: polyws-0.2.3.tar.gz
  • Upload date:
  • Size: 21.9 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.3.tar.gz
Algorithm Hash digest
SHA256 c93117f44b2310c2981bd31eaf19b941331c37210d6f57661653e2212fa0e8d3
MD5 4bdc75678ba0eca95503e992cde30b58
BLAKE2b-256 10495f3455e565db15ebe7eb90e423e36d699afc1f2047c66d84fe8f2da66e4e

See more details on using hashes here.

Provenance

The following attestation bundles were made for polyws-0.2.3.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.3-py3-none-any.whl.

File metadata

  • Download URL: polyws-0.2.3-py3-none-any.whl
  • Upload date:
  • Size: 17.7 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.3-py3-none-any.whl
Algorithm Hash digest
SHA256 3d9f47a2f4a88ffc244aa53392b0ed67bc08cd336350090abd94c9a2034ccac0
MD5 e1772ab92b01f6f4f9273338727c2771
BLAKE2b-256 3ddf05d387f3cad00449a27b5922c0574661731fbb6d6b4ac2879316463150a1

See more details on using hashes here.

Provenance

The following attestation bundles were made for polyws-0.2.3-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