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.
Metadata
Release files for juniper-cascor 0.9.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-0.9.0.tar.gz | 1.2 MB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| juniper_cascor-0.9.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 3.1 MB
Release files / juniper_cascor-0.9.0.tar.gz
| Download URL | juniper_cascor-0.9.0.tar.gz |
|---|---|
| Size | 1.2 MB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
88dae2ac811fc9865937faf3b9c0a13d71944c329eb5c3b01c797319920883ea
|
|
BLAKE2b-256 checksum How to use checksums |
24565244771f1963e5d4f6d988c19ff06f39cce337c1d7029faf14500b755e28
|
| 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 14, 2026.
Transparency logRelease files / juniper_cascor-0.9.0-py3-none-any.whl
| Download URL | juniper_cascor-0.9.0-py3-none-any.whl |
|---|---|
| Size | 1.9 MB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
edcc369e6bbe964070f404427904d80bfa1ba97bc6230526f38aa7b0c3dd7a3c
|
|
BLAKE2b-256 checksum How to use checksums |
58358c1521a75cfb6a2bbe87e89aa317989cad80fdd9c1f6c1bb16ad49b5fa5f
|
| 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 14, 2026.
Transparency log