juniper-cascor-protocol
Cross-process WebSocket frame schemas for the juniper-cascor ecosystem.
This package is the canonical, single-sourced wire-protocol surface for the three Juniper WebSocket endpoints:
| Endpoint | Schema source |
|---|---|
/ws/training (server → client broadcast) |
juniper_cascor_protocol.envelope (Pydantic v2) |
/ws/control (bidirectional command/response) |
juniper_cascor_protocol.envelope (Pydantic v2) |
/ws/v1/workers (cascor ↔ worker JSON + binary side-channel) |
juniper_cascor_protocol.worker (StrEnum + numpy BinaryFrame) |
Why two subpackages?
The envelope subpackage uses Pydantic v2 for declarative validation of JSON-only frames.
The worker subpackage stays Pydantic-free so juniper-cascor-worker
can adopt the canonical type enum and binary codec without pulling Pydantic into its slim image —
preserving the METRICS-MON R2 exit-gate decision.
Importing juniper_cascor_protocol.worker does not load Pydantic (verified by the test suite).
Install
pip install juniper-cascor-protocol
Pinned by the cascor server, juniper-cascor-client, juniper-canopy, and juniper-cascor-worker — each consumer imports only the subpackage it needs.
Quick start
Validating an inbound /ws/training frame
import json
from juniper_cascor_protocol.envelope import (
UnknownEnvelope,
MetricsEnvelope,
validate_envelope,
)
raw = ws.recv() # ``websockets`` text frame
frame = json.loads(raw)
envelope = validate_envelope(frame) # never raises on bad input
if isinstance(envelope, MetricsEnvelope):
handle_metrics(envelope.data)
elif isinstance(envelope, UnknownEnvelope):
# ``envelope.type`` is the cardinality-bounded label
# (collapses to ``"_unmatched"`` after N distinct unknowns).
log_unrecognized_frame(envelope.type)
validate_envelope never raises on schema mismatch — chaos-testing of malformed frames is part of the package's contract so a misbehaving server cannot crash a consumer.
Worker-side BinaryFrame codec
import numpy as np
from juniper_cascor_protocol.worker import BinaryFrame, WorkerMessageType
# Send tensor as a binary side-channel frame
weights = np.zeros((128, 128), dtype="float32")
ws.send(BinaryFrame.encode(weights))
# Receive and decode
raw = await ws.recv() # bytes
arr = BinaryFrame.decode(raw) # owned numpy array
# Dispatch JSON envelope by canonical message type
msg = json.loads(text_frame)
if msg.get("type") == WorkerMessageType.TASK_ASSIGN:
...
Cardinality-bound details
The validate_envelope helper tracks distinct unknown type strings up to UNKNOWN_TYPE_BUDGET = 16 per process; subsequent unknowns return as UNMATCHED_TYPE_LABEL = "_unmatched". This mirrors the juniper_observability.UNMATCHED_ENDPOINT_LABEL strategy used for HTTP cardinality bounds. Tests reset state via reset_unknown_label_state() in juniper_cascor_protocol.envelope.
Versioning
Follows PEP 440 + Keep a Changelog. Consumers should pin juniper-cascor-protocol>=A.B,<A+1. Additive envelope fields are minor bumps; field removals/renames are major bumps.
See CHANGELOG.md for the per-version contract.
License
MIT — see LICENSE.
Metadata
Release files for juniper-cascor-protocol 0.2.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| juniper_cascor_protocol-0.2.0.tar.gz | 20.6 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| juniper_cascor_protocol-0.2.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 35.8 kB
Release files / juniper_cascor_protocol-0.2.0.tar.gz
| Download URL | juniper_cascor_protocol-0.2.0.tar.gz |
|---|---|
| Size | 20.6 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
477ad23eaf86f2d976c97b0e7770874d214b842a9aade272c9b627cba7875ebe
|
|
BLAKE2b-256 checksum How to use checksums |
e65ac04f0f035030fb44763b56cf3d1cd60c1875f0eb47ca5d24d8b3b6ddebc1
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Aug 10, 2026.
Transparency logRelease files / juniper_cascor_protocol-0.2.0-py3-none-any.whl
| Download URL | juniper_cascor_protocol-0.2.0-py3-none-any.whl |
|---|---|
| Size | 15.3 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
9bcb31db84c2a23e01829ceca13cc924af88c813d6c8bd4c1a73cf79bac8b1de
|
|
BLAKE2b-256 checksum How to use checksums |
5b468cfdecbb68a1bddd5671dfd826e69e1d68505c7eb5487fd86a52df436faf
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Aug 10, 2026.
Transparency log