juniper-data
A FastAPI service that generates, versions, and serves ML datasets as NPZ artifacts.
juniper-data turns a catalogue of dataset generators into a REST service: you ask it for a dataset
by name and parameters, and it returns a versioned, NPZ-formatted train/test/full split. The
catalogue spans synthetic classification problems (two-spiral, concentric circles, XOR, Gaussian
mixtures, moons, checkerboard), image sets (MNIST), the ARC-AGI visual-reasoning families, a CSV/JSON
import path, and a family of time-series and irregularly-sampled sequence generators
(autoregressive, Mackey-Glass, multi-sine, delay-product, equities, and the irregular-Δt equities_seq
contract). A named-version registry, tag filtering, batch creation, and per-dataset preview round out
the surface. Call GET /v1/generators for the live catalogue.
It is the foundational data layer of the platform: the dataset identifiers it returns are the
substrate juniper-cascor trains on and juniper-canopy visualises.
Part of the Juniper platform. juniper-data is the dataset-generation service of Juniper — a multi-package ML research platform built around constructive (Cascade-Correlation) and recurrent neural networks. It runs standalone; the rest of the platform consumes it over HTTP (see
juniper-data-client).
Install
pip install juniper-data # from PyPI
For development from a clone (the optional extras are api, arc-agi, equities, mnist,
observability, test, dev, all):
git clone https://github.com/pcalnon/juniper-data.git && cd juniper-data
pip install -e ".[all]"
MNIST / Fashion-MNIST (optional extra)
The mnist generator loads the real MNIST / Fashion-MNIST datasets from the Hugging Face Hub and
needs the (heavy) datasets chain, shipped behind an explicit extra — it is never part of the base
install:
pip install "juniper-data[mnist]"
- First call downloads from the Hub into the Hugging Face cache (
HF_HOME, default~/.cache/huggingface; the Docker image pins it to/app/data/hf-cacheso a mounted data volume persists it). Later calls are served from the cache. - Offline deployments must seed that cache ahead of time (run one generation for each dataset
while online, or copy a populated
HF_HOMEin); withHF_HUB_OFFLINE=1the generator then works entirely from the cache. - Without the extra installed, the generator is unavailable: the registry reports
available: falseandPOST /v1/datasetsreturns501with the install hint instead of a masked 500. - The service Docker image ships the extra (it is compiled into
requirements.lock), so MNIST generation works in containers out of the box.
Run
uvicorn --factory juniper_data.api.app:get_app --reload # binds 127.0.0.1:8100
curl http://localhost:8100/v1/health/ready
curl http://localhost:8100/v1/generators # the live generator catalogue
Create a dataset over the REST API:
curl -sX POST localhost:8100/v1/datasets \
-H 'Content-Type: application/json' \
-d '{"generator": "spiral", "name": "demo", "params": {"n_spirals": 2, "noise": 0.1}}'
Or generate one in-process, without the service:
from juniper_data.generators import SpiralGenerator, SpiralParams
dataset = SpiralGenerator.generate(SpiralParams(n_spirals=2, n_points_per_spiral=100, noise=0.1))
# dataset: dict of float32 arrays — X_train, y_train, X_test, y_test, X_full, y_full
Data contract
Datasets are NPZ archives with the keys X_train, y_train, X_test, y_test, X_full, y_full,
all float32. This is the contract every Juniper consumer reads.
Configuration
Settings load from the JUNIPER_DATA_ environment namespace (juniper_data/api/settings.py) and honor
the Docker _FILE secret convention. The most common knobs (full surface in
docs/REFERENCE.md):
| Variable | Default | Purpose |
|---|---|---|
JUNIPER_DATA_HOST / JUNIPER_DATA_PORT |
127.0.0.1 / 8100 |
Bind address / port (0.0.0.0 under Docker). |
JUNIPER_DATA_STORAGE_PATH |
./data/datasets |
Where persisted dataset artifacts live. |
JUNIPER_DATA_API_KEYS |
(unset) | CSV / JSON-array of X-API-Key values; auth is disabled when unset. |
JUNIPER_DATA_LOG_LEVEL / _LOG_FORMAT |
INFO / text |
Verbosity / text or json. |
JUNIPER_DATA_METRICS_ENABLED |
false |
Expose /metrics for Prometheus (IP-gated). |
Docker
docker build -t juniper-data:latest .
docker run --rm -p 8100:8100 -e JUNIPER_DATA_HOST=0.0.0.0 juniper-data:latest
Multi-stage build (Python 3.14-slim); 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.
Consumed by juniper-cascor and juniper-canopy via JUNIPER_DATA_URL, and by
juniper-data-client programmatically.
Documentation
docs/QUICK_START.md— get running in five minutesdocs/USER_MANUAL.md— comprehensive usage guidedocs/api/JUNIPER_DATA_API.md— full REST reference (filtering, batch, tagging, versioning)docs/REFERENCE.md— configuration and environment-variable referencedocs/DOCUMENTATION_OVERVIEW.md— index of all juniper-data docs
License
MIT — see LICENSE.
Release files for juniper-data 0.12.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_data-0.12.0.tar.gz | 330.0 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| juniper_data-0.12.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 739.7 kB
Release files / juniper_data-0.12.0.tar.gz
| Download URL | juniper_data-0.12.0.tar.gz |
|---|---|
| Size | 330.0 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
f5238e9f57b9c25b308fef25dc75b29cb4781272e99a8a3d5bc57897a065b16c
|
|
BLAKE2b-256 checksum How to use checksums |
1819a4ac1703a48188939e8c7443059bdb953ed918090ccb92cc966197349444
|
| 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 31, 2026.
Transparency logRelease files / juniper_data-0.12.0-py3-none-any.whl
| Download URL | juniper_data-0.12.0-py3-none-any.whl |
|---|---|
| Size | 409.7 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
7357225d1016cac40d9806ae92aa5f0b76780af96366c4f61750577e05d58347
|
|
BLAKE2b-256 checksum How to use checksums |
881b3815312e30807840726b5767c1eb9a61d042a5f83bac29cdd9dccd3206f8
|
| 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 31, 2026.
Transparency log