Skip to main content

WebSocket transport (recommended)

BranchKey needs a way to tell your client "an aggregation is ready to download". It supports two mechanisms for that notification: a WebSocket tunnel (recommended) and RabbitMQ/AMQP (legacy). This page covers the WebSocket tunnel.

Why WebSocket

The WebSocket tunnel runs over the same host and port as the REST API (https / port 443). That means:

  • No extra firewall rules. If your client can reach https://app.branchkey.com to upload and download files, it can already receive notifications. Contrast with RabbitMQ, which needs an additional outbound port (5671) opened.
  • Simpler networking. One host, one port, standard HTTPS/WSS — friendly to corporate proxies and locked-down hospital or lab networks.

The WebSocket transport was introduced in BranchKey client v2.8.0.

Enabling it

Set use_websocket=True when you create the client:

from branchkey import Client, Credentials, APIConfig

client = Client(
credentials=credentials,
api_config=APIConfig(host="https://app.branchkey.com"),
use_websocket=True,
)

That's it. You then receive aggregation notifications exactly as you would with RabbitMQ — from client.queue:

aggregation_id = client.queue.get(block=True, timeout=300)
file_path = client.file_download(aggregation_id)
One consumption pattern, either transport

client.queue.get() works whether you chose WebSocket or RabbitMQ, so your training loop does not change when you switch. (In WebSocket mode you can alternatively poll client.get_latest_aggregation_id(), but the queue is simpler and is what the Docker template uses.)

What happens under the hood

You don't have to manage any of this — the client library does it for you — but for those who need to reason about network behaviour or debug a proxy:

  1. The client requests a short-lived ticket over HTTPS: POST /api/v1/ws/ticket, authenticated with your leaf's Authorization: Bearer <leaf_id>:<session_token> and LEAF: true headers.
  2. The server returns a single-use ticket_id (valid for 60 seconds).
  3. The client opens the WebSocket: wss://app.branchkey.com/api/v1/ws?ticket=…&request_id=…. The ticket is validated and burned on connection.
  4. The server pushes small JSON messages as events occur:
    • aggregation_status → an aggregation is ready (carries the aggregation_id).
    • run_status → the run was started, paused, or stopped.
  5. If the connection drops, the client automatically reconnects with exponential backoff (fetching a fresh ticket each time).

Configuring reconnection

Reconnection behaviour is configurable via WebSocketConfig (all optional):

from branchkey import Client, WebSocketConfig

client = Client(
credentials=credentials,
websocket_config=WebSocketConfig(
max_reconnect_attempts=0, # 0 = retry forever (default)
reconnect_backoff_factor=2.0, # exponential backoff multiplier
reconnect_max_delay=60, # cap on delay between attempts (seconds)
),
use_websocket=True,
)

Firewall requirements

DirectionDestinationPortProtocol
Outboundapp.branchkey.com443HTTPS / WSS

No other outbound ports are required for the WebSocket transport. The WebSocket upgrade happens on the same 443 connection as your REST API traffic.

Security

Transport security comes from TLS (wss://), terminated at the BranchKey gateway — the same certificate chain as the HTTPS API. The client derives the wss:// URL from your https:// host and validates the server certificate against your system's CA store. Do not disable SSL verification in production.

Troubleshooting

  • WebSocket connection failed / connection errors — confirm the client can reach the API host over HTTPS at all (try curl -I https://app.branchkey.com). If 443 is open for the REST API, the WebSocket uses the same path. If a strict proxy blocks WebSocket upgrades, fall back to RabbitMQ with use_websocket=False.
  • Notifications never arrive — check client.run_status is "start"; the platform only emits aggregation notifications for active runs. See the FAQ.

See also