HTTP/WebSocket client for the JuniperCascor neural network training service
Project description
Juniper: Dynamic Neural Network Research Platform
Juniper is an AI/ML research platform for investigating dynamic neural network architectures and novel learning paradigms. The project emphasizes ground-up implementations from primary literature, enabling a more transparent exploration of fundamental algorithms.
Juniper Cascor Client
juniper-cascor-client is the Python HTTP and WebSocket client library for the juniper-cascor training service. The package exposes a synchronous JuniperCascorClient for the REST surface (network lifecycle, training control, snapshots, metrics, distributed-worker monitoring) and two async WebSocket clients — CascorTrainingStream over /ws/training for inbound training events and CascorControlStream over /ws/control for outbound runtime commands. Inbound WebSocket frames are validated against the Pydantic envelope models of juniper-cascor-protocol, with unrecognised frame types and malformed payloads logged and counted rather than crashing the stream. The two WebSocket streams do not auto-reconnect; callers are responsible for wrapping a stream in a retry loop with backoff if a long-running connection is expected to survive network interruptions.
Distribution
juniper-cascor-client is published on PyPI as juniper-cascor-client.
The package is also surfaced through the platform meta-distribution
juniper-ml, which installs
the full client stack via pip install juniper-ml[all].
pip install juniper-cascor-client
Ecosystem Compatibility
This client library is part of the Juniper ecosystem. Verified compatible versions:
| juniper-data | juniper-cascor | juniper-canopy | data-client | cascor-client | cascor-worker |
|---|---|---|---|---|---|
| 0.6.x | 0.5.x | 0.5.x | >=0.4.1 | >=0.4.0 | >=0.4.0 |
For full-stack Docker deployment and integration tests, see juniper-deploy.
Architecture
juniper-cascor-client is a thin client surface over the juniper-cascor REST and WebSocket protocols. The REST client (JuniperCascorClient) is synchronous and built on requests + urllib3 retry semantics; the two WebSocket clients (CascorTrainingStream, CascorControlStream) are async and built on websockets.
┌─────────────────────────┐ ┌──────────────────────┐
│ Caller (e.g. juniper- │ HTTP REST │ juniper-cascor │
│ canopy / research │ ◄────────────► │ Training Svc │
│ notebook / operator │ WS / WSS │ Port 8200 │
│ script) │ ◄────────────► │ /v1/... │
└──────────┬──────────────┘ │ /ws/training │
│ uses │ /ws/control │
▼ └──────────────────────┘
┌─────────────────────────┐
│ juniper-cascor-client │
│ JuniperCascorClient │
│ CascorTrainingStream │
│ CascorControlStream │
│ (this package) │
└─────────────────────────┘
Inbound WebSocket frames are observed against juniper_cascor_protocol.envelope.validate_envelope() (METRICS-MON R2.2.4). Unknown frame types and malformed payloads are logged at WARNING level and — when prometheus-client is installed via the [observability] extra — counted via juniper_cascor_client_unrecognized_ws_frames_total. Cardinality is bounded: beyond the first sixteen distinct unrecognised types, observations collapse to "_unmatched".
Related Services
| Service | Relationship | Notes |
|---|---|---|
| juniper-cascor | The service this client targets | Set base_url (default http://localhost:8200) and the WebSocket origin |
| juniper-canopy | Primary consumer; uses this client to monitor and control CasCor training | Reads JUNIPER_CANOPY_CASCOR_SERVICE_URL |
| juniper-cascor-protocol | Wire-protocol envelope schemas validated against inbound WS frames | juniper-cascor-protocol>=0.1.0 is a runtime dependency |
Active Research Components
juniper-cascor-client is the reference client implementation of two research artifacts of the Juniper platform: the WebSocket training-stream protocol (/ws/training), which carries cascade-add events, per-epoch metrics, network-topology updates, and state transitions as a Cascade-Correlation network grows; and the WebSocket control-stream protocol (/ws/control), which carries the operator-facing command surface (start, stop, pause, resume, reset, parameter updates) that an experimentation interface uses to steer a running training run. Both protocols are non-trivial enough to be worth naming as platform artifacts; the envelope schemas are defined in juniper-cascor-protocol and validated observationally on every inbound frame.
Quick Start Guide
Prerequisites
- Python ≥ 3.12
- A running
juniper-cascorinstance reachable at thebase_url(typicallyhttp://localhost:8200) - An API key configured on the cascor service (
JUNIPER_CASCOR_API_KEYS); the client readsJUNIPER_CASCOR_API_KEYas a fallback
Installation
pip install juniper-cascor-client
Optional extras: [observability] enables Prometheus counters for WebSocket-frame validation; [test] installs the testing dependencies; [dev] adds linting and type-checking tools.
Verification — REST client
from juniper_cascor_client import JuniperCascorClient
with JuniperCascorClient("http://localhost:8200") as client:
client.create_network(input_size=2, output_size=2, learning_rate=0.01)
client.start_training(
dataset={"source": "inline"},
inline_data={
"train_x": [[0, 0], [1, 0], [0, 1], [1, 1]],
"train_y": [[1, 0], [0, 1], [0, 1], [1, 0]],
},
epochs=100,
)
status = client.get_training_status()
print(status["data"]["training_active"])
metrics = client.get_metrics()
print(f"Loss: {metrics['data']['train_loss']}")
Verification — WebSocket training stream
import asyncio
from juniper_cascor_client import CascorTrainingStream
async def monitor():
async with CascorTrainingStream("ws://localhost:8200") as stream:
async for message in stream:
if message["type"] == "metrics":
print(f"Epoch {message['data']['epoch']}: loss={message['data']['train_loss']}")
elif message["type"] == "cascade_add":
print("New hidden unit added")
asyncio.run(monitor())
Verification — WebSocket control stream
import asyncio
from juniper_cascor_client import CascorControlStream
async def control():
async with CascorControlStream("ws://localhost:8200") as ctrl:
result = await ctrl.command("start", {"epochs": 200})
print(result)
asyncio.run(control())
Reconnection contract
WebSocket streams do not auto-reconnect. If a connection is lost (network interruption, server restart, timeout), the stream silently terminates and the async iterator stops. Long-running consumers must wrap the stream in their own retry loop with backoff. The canonical pattern:
import asyncio
from juniper_cascor_client import CascorTrainingStream
async def resilient_stream(url, api_key):
while True:
try:
async with CascorTrainingStream(url, api_key=api_key) as stream:
async for message in stream.stream():
process(message)
except Exception:
await asyncio.sleep(5) # backoff before reconnect
Next Steps
docs/QUICK_START.md— complete installation and verification guidedocs/REFERENCE.md— full API reference, error model, and WebSocket frame cataloguedocs/DEVELOPER_CHEATSHEET.md— quick-reference card for development tasksjuniper-cascor— the upstream training servicejuniper-ml— platform meta-package on PyPI
Research Philosophy
The Juniper platform exists to study learning algorithms whose network architecture is not fixed in advance. Its initial anchor is the Cascade-Correlation algorithm of Fahlman and Lebiere (1990), implemented from the primary literature without recourse to higher-level abstractions that elide the algorithm's operational detail. The organising commitment is that algorithm implementations remain inspectable at the level at which they were originally specified: candidate units, correlation objectives, weight-freezing semantics, and the structural events that grow the network are first-class artifacts of the codebase rather than internal details of a library wrapper. This permits comparative work — across algorithms, datasets, and hyperparameter regimes — to be conducted on a known and reproducible substrate.
The current platform comprises a Cascade-Correlation training service exposing a REST and WebSocket interface, a dataset-generation service with a named-version registry that includes the ARC-AGI families, a real-time monitoring dashboard for inspecting training dynamics as they occur, and a distributed worker that parallelises candidate-unit training across hosts. Near-term work extends the architectural-growth catalogue beyond Cascade-Correlation, introduces multi-network orchestration for comparative experiments at the level of network populations rather than individual runs, and tightens the dataset–training–monitoring loop into a reproducible research workbench. The longer-term direction is the systematic empirical study of constructive and architecture-growing learning algorithms, with first-class infrastructure for the ablation, comparison, and replication that such a study requires.
Documentation
API Reference
JuniperCascorClient — REST client
| Method | Description |
|---|---|
health_check() |
Service health check |
is_alive() |
Liveness probe |
is_ready() |
Readiness probe |
wait_for_ready(timeout, poll_interval) |
Wait for service readiness |
create_network(**kwargs) |
Create a CasCor network |
get_network() / delete_network() |
Network lifecycle |
get_topology() / get_statistics() |
Network introspection |
start_training(...) / stop_training() |
Training start / stop |
pause_training() / resume_training() / reset_training() |
Training control |
get_training_status() / get_training_params() |
Training state |
get_metrics() / get_metrics_history(count) |
Metrics retrieval |
update_params(params) |
Runtime training parameter updates |
get_dataset() / get_dataset_data() |
Dataset retrieval |
get_decision_boundary(resolution) |
Decision boundary for visualisation |
list_snapshots() / get_snapshot(id) |
Snapshot listing and inspection |
save_snapshot(description) / load_snapshot(id) |
Snapshot save / restore |
list_workers() / get_worker(id) / get_worker_stats() |
Distributed-worker monitoring |
close() |
Close the underlying HTTP session |
CascorTrainingStream — async WebSocket training stream
Connects to /ws/training. Yields inbound JSON frames as Python dicts. Supports both raw iteration (async for message in stream) and callback-based dispatch (on_metrics, on_state, on_topology, on_cascade_add, on_event). Context-manager API.
CascorControlStream — async WebSocket control stream
Connects to /ws/control. Sends outbound command frames and awaits their responses. Convenience: set_params(params) is sugar for command("set_params", {...}). Context-manager API.
Reference documents
| Document | Purpose |
|---|---|
docs/DOCUMENTATION_OVERVIEW.md |
Navigation index for all juniper-cascor-client documentation |
docs/QUICK_START.md |
Complete installation and verification guide |
docs/REFERENCE.md |
Full API reference, error model, and WebSocket frame catalogue |
docs/DEVELOPER_CHEATSHEET.md |
Quick-reference card for development tasks |
CHANGELOG.md |
Version history |
License
MIT License — see LICENSE for details.
Project details
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file juniper_cascor_client-0.5.0.tar.gz.
File metadata
- Download URL: juniper_cascor_client-0.5.0.tar.gz
- Upload date:
- Size: 74.5 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.13
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
05d3d8d125fddde2ade67049993df848cca7c3dc7629e2d0cc5dc9fcd644d9a2
|
|
| MD5 |
3604251817a192e7fc90185d3e0aeba7
|
|
| BLAKE2b-256 |
7c21744a2a3f0cae016b511d3ad587593f8a3043a44d0919fb0565bf77cd2717
|
Provenance
The following attestation bundles were made for juniper_cascor_client-0.5.0.tar.gz:
Publisher:
publish.yml on pcalnon/juniper-cascor-client
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
juniper_cascor_client-0.5.0.tar.gz -
Subject digest:
05d3d8d125fddde2ade67049993df848cca7c3dc7629e2d0cc5dc9fcd644d9a2 - Sigstore transparency entry: 1673087378
- Sigstore integration time:
-
Permalink:
pcalnon/juniper-cascor-client@8a6da9f31e57c7fa73d948e919c4af63706ad54e -
Branch / Tag:
refs/tags/v0.5.0 - Owner: https://github.com/pcalnon
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@8a6da9f31e57c7fa73d948e919c4af63706ad54e -
Trigger Event:
release
-
Statement type:
File details
Details for the file juniper_cascor_client-0.5.0-py3-none-any.whl.
File metadata
- Download URL: juniper_cascor_client-0.5.0-py3-none-any.whl
- Upload date:
- Size: 47.2 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.13
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
d1a95c674d717fe15f92b4e654cb96db21a0213c7146846b7b8583e10a99bcbb
|
|
| MD5 |
149f5ccabeb61dfa2f259f70822524ec
|
|
| BLAKE2b-256 |
ea423df2f0b8d47d6965fa80a0b20560b61a98cf33d408d267e306ad06ea213e
|
Provenance
The following attestation bundles were made for juniper_cascor_client-0.5.0-py3-none-any.whl:
Publisher:
publish.yml on pcalnon/juniper-cascor-client
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
juniper_cascor_client-0.5.0-py3-none-any.whl -
Subject digest:
d1a95c674d717fe15f92b4e654cb96db21a0213c7146846b7b8583e10a99bcbb - Sigstore transparency entry: 1673087458
- Sigstore integration time:
-
Permalink:
pcalnon/juniper-cascor-client@8a6da9f31e57c7fa73d948e919c4af63706ad54e -
Branch / Tag:
refs/tags/v0.5.0 - Owner: https://github.com/pcalnon
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@8a6da9f31e57c7fa73d948e919c4af63706ad54e -
Trigger Event:
release
-
Statement type: