Files
poly-maker/tests/test_live_marketdata.py
T
Daniel Sapkota c7b686116e Getting there
2026-07-05 17:50:04 -04:00

75 lines
2.6 KiB
Python

"""Live integration test for the market WS (network-gated).
Run explicitly with: POLYMAKER_LIVE=1 uv run pytest tests/test_live_marketdata.py
Skipped by default so the unit suite stays offline and fast.
"""
from __future__ import annotations
import asyncio
import json
import os
import httpx
import pytest
import websockets
pytestmark = pytest.mark.skipif(
os.environ.get("POLYMAKER_LIVE") != "1", reason="live test; set POLYMAKER_LIVE=1"
)
async def _top_political_tokens() -> tuple[str, list[str]]:
async with httpx.AsyncClient(timeout=20) as c:
r = await c.get(
"https://gamma-api.polymarket.com/markets",
params={"limit": 1, "closed": "false", "tag_id": 2,
"order": "volume24hr", "ascending": "false"},
)
m = r.json()[0]
return m["conditionId"], json.loads(m["clobTokenIds"])
async def test_market_service_builds_a_live_book():
from polymaker.marketdata.service import MarketDataService
cond, tokens = await _top_political_tokens()
woken: list[tuple[str, str]] = []
svc = MarketDataService(on_dirty=lambda c, t: woken.append((c, t)))
svc.set_markets([(cond, tokens)])
task = asyncio.create_task(svc.run())
try:
# wait until at least one token has a two-sided book
for _ in range(60):
await asyncio.sleep(0.5)
if any(not svc.book(t).is_empty for t in tokens):
break
finally:
svc.stop()
task.cancel()
assert woken, "quoter was never woken by a book event"
live = [t for t in tokens if not svc.book(t).is_empty]
assert live, "no book was populated from the live feed"
book = svc.book(live[0])
assert book.best_bid() is not None and book.best_ask() is not None
assert book.best_bid().price < book.best_ask().price
async def test_live_market_ws_raw_frames():
"""Sanity check the wire format our parser targets hasn't drifted."""
_, tokens = await _top_political_tokens()
uri = "wss://ws-subscriptions-clob.polymarket.com/ws/market"
async with websockets.connect(uri, ping_interval=5, ping_timeout=None) as ws:
await ws.send(json.dumps({"assets_ids": tokens, "type": "market"}))
got_book = False
for _ in range(10):
raw = await asyncio.wait_for(ws.recv(), timeout=10)
data = json.loads(raw)
for msg in data if isinstance(data, list) else [data]:
if msg.get("event_type") == "book":
assert {"asset_id", "bids", "asks", "hash"} <= set(msg)
got_book = True
assert got_book