bitbang-python implements only the listener/device role today -- the connecting peer has to be a browser or the Go CLI. So two Python programs can't talk to each other without running the CLI as a port-forwarding sidecar.
This adds a Python connector role plus a blocking API over it, deliberately mirroring the stdlib's multiprocessing.connection:
# machine A
from bitbang import Listener
with Listener() as l: # prints its address
conn = l.accept()
conn.send({'temp': 22.5})
# machine B, anywhere
from bitbang import Client
conn = Client('g4x-WQfW…#7jIyMYY…')
print(conn.recv())
Three substitutions from the stdlib version: (ip, port) becomes the identity address, authkey disappears (identity verification is already stronger than the stdlib's HMAC handshake), and plaintext TCP becomes DTLS over P2P WebRTC. The pitch is one sentence — the stdlib API you already know, minus the same-network requirement.
Scope. Generic TCP/HTTP forwarding stays the CLI's job; it's faster and more general. This is for in-code messaging: a model, a sensor loop, or a job queue on one machine made callable from Python on another, with no web framework, no serialization boilerplate, and no deployment step.
Work involved:
connector.py -- the connecting side. A third implementation of an already-specced protocol (code_exchange.md), not new protocol. ~300 lines.
connection.py -- sync Connection facade: queues, backpressure, format tags. ~300 lines.
listener.py -- thin wrapper over the device-role core. ~150 lines.
- One new SWSP stream type,
conn, reusing the existing websocket MORE chunking verbatim. Requires 'conn' in the device's ready.caps. No signaling-server changes.
- The main surgery on existing code: extract the device-role signaling/PC/stream-0 core out of
BitBangBase, which currently assumes a WSGI/ASGI app, so Listener and BitBangWSGI/BitBangASGI share it. Behavior-preserving for existing apps.
v1 scope decisions: direct + STUN only, no TURN or ice_restart (matches the current Python listener's capability); no reconnect — a drop surfaces as BrokenPipeError/EOFError and the caller constructs a new Client; JSON serialization by default, with pickle as an explicit opt-in required on both sides.
Full design, including wire format, threading model, and two worked examples (remote system monitor, remote Whisper transcription): python2python.md.
Open:
accept() queue -- unbounded, or a stdlib-style backlog cap? (leaning unbounded, revisit if abused)
- Should
Client retry transient signaling failures internally, or fail fast? (leaning fail fast, with a retry loop shown in the examples)
bitbang-pythonimplements only the listener/device role today -- the connecting peer has to be a browser or the Go CLI. So two Python programs can't talk to each other without running the CLI as a port-forwarding sidecar.This adds a Python connector role plus a blocking API over it, deliberately mirroring the stdlib's
multiprocessing.connection:Three substitutions from the stdlib version:
(ip, port)becomes the identity address,authkeydisappears (identity verification is already stronger than the stdlib's HMAC handshake), and plaintext TCP becomes DTLS over P2P WebRTC. The pitch is one sentence — the stdlib API you already know, minus the same-network requirement.Scope. Generic TCP/HTTP forwarding stays the CLI's job; it's faster and more general. This is for in-code messaging: a model, a sensor loop, or a job queue on one machine made callable from Python on another, with no web framework, no serialization boilerplate, and no deployment step.
Work involved:
connector.py-- the connecting side. A third implementation of an already-specced protocol (code_exchange.md), not new protocol. ~300 lines.connection.py-- syncConnectionfacade: queues, backpressure, format tags. ~300 lines.listener.py-- thin wrapper over the device-role core. ~150 lines.conn, reusing the existing websocketMOREchunking verbatim. Requires'conn'in the device'sready.caps. No signaling-server changes.BitBangBase, which currently assumes a WSGI/ASGI app, soListenerandBitBangWSGI/BitBangASGIshare it. Behavior-preserving for existing apps.v1 scope decisions: direct + STUN only, no TURN or
ice_restart(matches the current Python listener's capability); no reconnect — a drop surfaces asBrokenPipeError/EOFErrorand the caller constructs a newClient; JSON serialization by default, with pickle as an explicit opt-in required on both sides.Full design, including wire format, threading model, and two worked examples (remote system monitor, remote Whisper transcription):
python2python.md.Open:
accept()queue -- unbounded, or a stdlib-stylebacklogcap? (leaning unbounded, revisit if abused)Clientretry transient signaling failures internally, or fail fast? (leaning fail fast, with a retry loop shown in the examples)