juniper-cascor
A Cascade-Correlation neural-network training service with live REST + WebSocket streaming.
juniper-cascor is a FastAPI service that implements the Fahlman & Lebiere (1990) Cascade-Correlation
algorithm — a constructive network that grows itself by recruiting hidden units one at a time, each
chosen to maximise correlation with the network's remaining error. Instead of fixing the architecture
up front, CasCor builds it as training proceeds.
The service exposes a REST API for network and training control and live WebSocket streams for real-time introspection of the growing network. It trains on datasets from juniper-data, is driven over HTTP by juniper-cascor-client, monitored live by juniper-canopy, and can offload candidate-unit training to distributed juniper-cascor-worker instances.
Part of the Juniper platform. juniper-cascor is the Cascade-Correlation training backend of Juniper — a multi-package ML research platform built around constructive and recurrent neural networks.
Install
pip install juniper-cascor
For development from a clone:
git clone https://github.com/pcalnon/juniper-cascor.git && cd juniper-cascor
pip install -e ".[ml,api,observability]"
Run
python src/server.py # binds 127.0.0.1:8200
curl http://localhost:8200/v1/health/ready
A minimal train loop over the REST API — create a network, stage a dataset, start training:
curl -sX POST localhost:8200/v1/network \
-H 'Content-Type: application/json' -d '{"config": {"input_size": 2, "output_size": 2}}'
curl -sX POST localhost:8200/v1/training/dataset \
-H 'Content-Type: application/json' -d '{"dataset": {"generator": "spiral"}}'
curl -sX POST localhost:8200/v1/training/start \
-H 'Content-Type: application/json' -d '{"params": {"max_epochs": 100}}'
curl -s localhost:8200/v1/training/status
API
REST routes (prefix /v1; responses wrapped in a {status, data, meta} envelope):
| Route | Methods | Purpose |
|---|---|---|
/health, /health/live, /health/ready |
GET | Liveness / readiness probes |
/network |
POST / GET / DELETE | Create, inspect, delete the network |
/network/topology, /network/stats |
GET | Topology + statistics |
/training/start, /stop, /pause, /resume, /reset |
POST | Training control |
/training/status, /training/params |
GET | Training state + parameters |
/training/dataset |
POST / GET / DELETE | Stage / inspect / clear the training dataset |
WebSocket streams: /ws/training (live metrics + topology, resumable), /ws/control (control +
heartbeat), /ws/v1/workers (the distributed worker pool). WebSocket admission is capped globally
across all three sockets, with an additional per-identity cap on /ws/control; over-cap clients are
closed with code 1013.
Configuration
Settings load from the JUNIPER_CASCOR_ environment namespace. Common knobs (full surface in
docs/install/REFERENCE.md):
| Variable | Default | Purpose |
|---|---|---|
JUNIPER_CASCOR_HOST / JUNIPER_CASCOR_PORT |
127.0.0.1 / 8200 |
Bind address / port (0.0.0.0 under Docker). |
JUNIPER_CASCOR_LOOPBACK_PUBLISH_ATTESTED |
false |
Bind attestation for a non-loopback interface: the port is reachable only via a loopback-only host publish. |
JUNIPER_CASCOR_AUTH_PROXY_ATTESTED |
false |
Bind attestation for a non-loopback interface: a fronting authenticating reverse proxy terminates access. |
JUNIPER_DATA_URL |
http://localhost:8100 |
Upstream juniper-data service. |
JUNIPER_CASCOR_API_KEYS |
(unset) | CSV X-API-Key values; auth disabled when unset. |
JUNIPER_CASCOR_WS_MAX_CONNECTIONS_GLOBAL |
200 |
Stack-wide WebSocket cap across training, control, and worker sockets. |
JUNIPER_CASCOR_WS_MAX_CONNECTIONS_PER_IDENTITY |
5 |
/ws/control cap per API-key identity. |
JUNIPER_CASCOR_LOG_LEVEL / _LOG_FORMAT |
INFO / text |
Verbosity / text or json. |
JUNIPER_CASCOR_METRICS_ENABLED |
false |
Expose /v1/metrics for Prometheus. |
Docker
docker build -t juniper-cascor:latest .
docker run --rm -p 127.0.0.1:8200:8200 \
-e JUNIPER_CASCOR_HOST=0.0.0.0 \
-e JUNIPER_CASCOR_LOOPBACK_PUBLISH_ATTESTED=true \
-e JUNIPER_CASCOR_API_KEYS=replace-with-a-strong-key \
-e JUNIPER_DATA_URL=http://host.docker.internal:8100 \
juniper-cascor:latest
The host-side publish is loopback-only; JUNIPER_CASCOR_LOOPBACK_PUBLISH_ATTESTED=true
attests that boundary so the startup bind guard allows the container's internal
0.0.0.0 bind. (Behind a fronting authenticating reverse proxy instead, attest
JUNIPER_CASCOR_AUTH_PROXY_ATTESTED=true.) Health is probed at /v1/health/ready. For the full stack, see
juniper-deploy.
Status
Live on PyPI. The current version is shown by the badge above; see CHANGELOG.md.
It trains on datasets from juniper-data (JUNIPER_DATA_URL) and is driven by
juniper-cascor-client.
Documentation
docs/install/QUICK_START.md— installation and setupdocs/install/USER_MANUAL.md— comprehensive usage guidedocs/api/API_REFERENCE.md— REST + WebSocket API referencedocs/install/REFERENCE.md— configuration reference
License
MIT — see LICENSE.
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-0.8.0.tar.gz.
File metadata
- Download URL: juniper_cascor-0.8.0.tar.gz
- Upload date:
- Size: 1.2 MB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/7.0.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
f86c8e2c7b0574e9380f2ccac91bcfd0ed7920478c74ff9bfb38d2bd6fc761d4
|
|
| MD5 |
761a464fde8756f9400ef4e375e5b350
|
|
| BLAKE2b-256 |
411664ea703edb7b41430c5d8523aa0a33b6f91f1271223d0cf44ad5af86666b
|
Provenance
The following attestation bundles were made for juniper_cascor-0.8.0.tar.gz:
Publisher:
publish.yml on pcalnon/juniper-cascor
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
juniper_cascor-0.8.0.tar.gz -
Subject digest:
f86c8e2c7b0574e9380f2ccac91bcfd0ed7920478c74ff9bfb38d2bd6fc761d4 - Sigstore transparency entry: 2405483253
- Sigstore integration time:
-
Permalink:
pcalnon/juniper-cascor@d8ae2f97419760cb00b0c9fb75dce4a88f27ac5f -
Branch / Tag:
refs/tags/v0.8.0 - Owner: https://github.com/pcalnon
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@d8ae2f97419760cb00b0c9fb75dce4a88f27ac5f -
Trigger Event:
release
-
Statement type:
File details
Details for the file juniper_cascor-0.8.0-py3-none-any.whl.
File metadata
- Download URL: juniper_cascor-0.8.0-py3-none-any.whl
- Upload date:
- Size: 1.9 MB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/7.0.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
957bd28a18ad3df8634ff331c72eb6ddb6f2bb7682925d5f39a262db6bb25774
|
|
| MD5 |
dc3e8152d00840a36741df1f70e24e0c
|
|
| BLAKE2b-256 |
a957e608c8576c7005344ad6417fe39fee2731bcf59b53084dd9add4282c7dca
|
Provenance
The following attestation bundles were made for juniper_cascor-0.8.0-py3-none-any.whl:
Publisher:
publish.yml on pcalnon/juniper-cascor
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
juniper_cascor-0.8.0-py3-none-any.whl -
Subject digest:
957bd28a18ad3df8634ff331c72eb6ddb6f2bb7682925d5f39a262db6bb25774 - Sigstore transparency entry: 2405483270
- Sigstore integration time:
-
Permalink:
pcalnon/juniper-cascor@d8ae2f97419760cb00b0c9fb75dce4a88f27ac5f -
Branch / Tag:
refs/tags/v0.8.0 - Owner: https://github.com/pcalnon
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@d8ae2f97419760cb00b0c9fb75dce4a88f27ac5f -
Trigger Event:
release
-
Statement type: