Skip to content

WS: structured subscribe helpers (generic param builder) - #179

Merged
martinkersner merged 2 commits into
mainfrom
issue-170-structured-subscribe-helpers
Jul 6, 2026
Merged

WS: structured subscribe helpers (generic param builder)#179
martinkersner merged 2 commits into
mainfrom
issue-170-structured-subscribe-helpers

Conversation

@martinkersner

Copy link
Copy Markdown
Member

Closes #170

What

Adds structured WS subscribe helpers driven by the generated registry, keeping the raw-string path fully backward-compatible.

  • New pure build_param(param_format, **tokens) -> str in datamaxi/aio/ws.py: assembles a wire subscribe param from keyword tokens whose names ARE the raw tokens in WS_CHANNELS[path]["param"].
  • Generic / registry-driven — no per-channel name table. New generated channels get structured helpers for free.
  • Token -> kwarg rule: a token that is entirely upper-case is lower-cased (SYMBOL -> symbol); every other token is verbatim (exchange, tokenId, srcQuote, ...). Documented in the docstring.
  • Grammar handled: None (no params -> reject kwargs), single SYMBOL (no separator), @/: separated tokens (separator inferred), and a trailing [@...] optional both-or-neither group.
  • Wired into Subscription.subscribe/unsubscribe and MarketSubscription.subscribe/unsubscribe via a small _resolve_params guard. market= on ticker stays a control kwarg (not a param token).

Usage

ws.ticker.subscribe(symbol="BTC-USDT", exchange="binance", market="spot")
ws.premium.subscribe(src="binance", tgt="upbit", tokenId="bitcoin",
                     srcQuote="USDT", tgtQuote="KRW", srcMkt="spot", tgtMkt="spot")
ws.forex.subscribe("USD-KRW")  # raw path unchanged

Why

Ergonomic named-arg subscribe without hand-writing per-channel mappings (issue's Option 1). Raw wire-string path preserved.

Decisions / notes

  • Chose raw-token kwargs (not friendly source_exchange/token_id) per the maintainer's Option 1 — zero per-channel code.
  • Mixing raw positional params + keyword tokens raises ValueError.
  • Structured kwargs on a param: None channel raise ValueError.
  • Async-only (no sync WS client exists).

Test plan

  • python -m pytest tests/test_ws.py -q -> 27 passed (13 pre-existing + 14 new).
  • flake8 clean; black clean.
  • New tests: build_param per format; SYMBOL->symbol rule; errors (missing required, unknown token, partial optional group, None channel, mixing raw+tokens); round-trip structured == raw wire string; integration structured ws.ticker.subscribe(...) sends BTC-USDT@binance over a fake conn.

Known failures

None.

Add build_param() that assembles a wire subscribe param from keyword
tokens named after the generated WS_CHANNELS[path]['param'] format
string. Generic (registry-driven), zero per-channel code: new channels
get structured helpers for free. Token->kwarg rule: all-upper tokens
lower-cased (SYMBOL->symbol), others verbatim (exchange, tokenId,
srcQuote). Handles @/: separators and the optional [@...] both-or-neither
group. Wire into Subscription/MarketSubscription subscribe+unsubscribe;
raw positional path unchanged, mixing raw+tokens rejected.
Unit-test build_param for every format (forex SYMBOL, SYMBOL@exchange,
ticker with/without optional currency@conversionBase, premium 7 tokens),
the SYMBOL->symbol lowercase rule, and error cases (missing required,
unknown token, partial optional group, None channel, mixing raw+tokens).
Round-trip: structured == raw wire string. Integration: structured
ws.ticker.subscribe(...) sends BTC-USDT@binance over a fake conn.
@martinkersner martinkersner self-assigned this Jul 5, 2026
@martinkersner
martinkersner merged commit b605400 into main Jul 6, 2026
5 checks passed
@martinkersner
martinkersner deleted the issue-170-structured-subscribe-helpers branch July 6, 2026 01:33
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

WIP WS: structured subscribe helpers (build param from named args, not raw strings)

1 participant