Track runs from outside Clojure using chachaml's HTTP write API.
A non-Clojure team member should be able to log a run, log
params/metrics, and end the run via REST. Useful for: Python training
scripts, Go services, GitHub Actions, anywhere a quick curl is
easier than a Clojure REPL.
clojure -M:ui or the Docker
setup). The write API lives under /api/w/.HOST=http://localhost:8080
# Start a run — returns the run id
RUN_ID=$(curl -s -X POST $HOST/api/w/runs \
-H 'Content-Type: application/json' \
-d '{"experiment":"iris","name":"from-python","tags":{"author":"maria"}}' \
| jq -r .id)
echo "Run id: $RUN_ID"
# Log params
curl -X POST $HOST/api/w/runs/$RUN_ID/params \
-H 'Content-Type: application/json' \
-d '{"lr":0.01,"epochs":100}'
# Log a metric (single)
curl -X POST $HOST/api/w/runs/$RUN_ID/metrics \
-H 'Content-Type: application/json' \
-d '{"accuracy":0.94}'
# Log time-series metrics
for i in 0 1 2 3 4; do
curl -X POST $HOST/api/w/runs/$RUN_ID/metrics \
-H 'Content-Type: application/json' \
-d "{\"loss\":$(echo "scale=3; 1.0 / ($i + 1)" | bc),\"step\":$i}"
done
# Optionally upload an artifact (raw bytes)
curl -X POST "$HOST/api/w/runs/$RUN_ID/artifacts?name=model.pkl" \
-H 'Content-Type: application/octet-stream' \
--data-binary @model.pkl
# End the run
curl -X POST $HOST/api/w/runs/$RUN_ID/end \
-H 'Content-Type: application/json' \
-d '{"status":"completed"}'
Verify in the UI: the run should appear in /runs with the params,
metrics, and artifact.
import requests
HOST = "http://localhost:8080"
session = requests.Session()
# Start
r = session.post(f"{HOST}/api/w/runs",
json={"experiment": "iris",
"name": "from-python",
"tags": {"author": "maria"}})
r.raise_for_status()
run_id = r.json()["id"]
# Params
session.post(f"{HOST}/api/w/runs/{run_id}/params",
json={"lr": 0.01, "epochs": 100})
# Metric per epoch
for epoch in range(100):
session.post(f"{HOST}/api/w/runs/{run_id}/metrics",
json={"loss": 1.0 / (epoch + 1), "step": epoch})
# Final accuracy
session.post(f"{HOST}/api/w/runs/{run_id}/metrics",
json={"accuracy": 0.94})
# End
session.post(f"{HOST}/api/w/runs/{run_id}/end",
json={"status": "completed"})
curl -X POST $HOST/api/w/models \
-H 'Content-Type: application/json' \
-d "{\"name\":\"iris-classifier\",
\"run_id\":\"$RUN_ID\",
\"artifact\":\"model.pkl\",
\"stage\":\"staging\",
\"description\":\"first cut\"}"
The same exclusivity rule applies: promoting another version to
:production demotes the previous one.
All endpoints accept and return JSON.
| Verb + path | Body | Returns |
|---|---|---|
POST /api/w/runs | {experiment, name?, tags?, parent_run_id?} | {id, ...} |
POST /api/w/runs/:id/params | {key: value, ...} | {ok: true} |
POST /api/w/runs/:id/metrics | {key: value, step?: n} or {key1: v1, key2: v2} | {ok: true} |
POST /api/w/runs/:id/artifacts?name=... | raw bytes | {ok, sha256, size} |
POST /api/w/runs/:id/end | {status: "completed"\|"failed", error?: "..."} | {ok: true} |
POST /api/w/models | {name, run_id, artifact, stage?, description?} | {name, version, ...} |
Read endpoints are at /api/... (no w/ prefix); see
Web UI tour: JSON API.
{ "error": "no such run" } from /params or /metrics —
you're posting to a run id that doesn't exist or was already ended.
Track the run id from the /runs response and stop logging after
/end.Content-Type mismatches — params/metrics endpoints expect
JSON; artifact uploads expect application/octet-stream. Mixing
them returns a 400.{"loss": 0.4, "accuracy": 0.9, "step": 12} logs both at the same step.Can you improve this documentation?Edit on GitHub
cljdoc builds & hosts documentation for Clojure/Script libraries
| Ctrl+k | Jump to recent docs |
| ← | Move to previous article |
| → | Move to next article |
| Ctrl+/ | Jump to the search field |