Beautiful, local-first experiment tracking. A lightweight alternative to wandb / tensorboard.
Project description
pandm
pandm tracks ML experiments locally. The Python SDK writes metrics and images straight to a .pandm/ directory next to your code — no account, no daemon, no cloud — and pandm ui serves a dashboard to compare runs. Unlike wandb there is nothing to sign up for, and unlike tensorboard the data is plain SQLite + PNG files you can query yourself. The same scripts report to a shared server over HTTP when you set one env var.
Install
pip install pandm
Quick start
import pandm
run = pandm.init(project="mnist", config={"lr": 1e-3, "batch_size": 64})
for step in range(1000):
loss, acc = train_step()
run.log({"train/loss": loss, "train/acc": acc}, step=step)
if step % 100 == 0:
run.log_image("samples", sample_grid, step=step) # PIL / numpy / torch / path
run.finish()
pandm ui # opens http://127.0.0.1:7878
The dashboard overlays selected runs per metric, with smoothing, log scale, step/time axes, an image browser with a step slider, and a config/summary comparison table. It polls while runs are alive, so curves grow during training.
Usage
step is optional (an internal counter is used). Runs end as finished or crashed: uncaught exceptions are detected via sys.excepthook (and the context manager), and hard-killed processes (kill -9, OOM) are presumed crashed once their 15s heartbeat goes quiet for 60s — self-healing if the process was merely suspended.
with pandm.init(project="mnist") as run:
run.log({"loss": 0.5})
List or delete runs from the terminal:
pandm ls
pandm delete <run_id>
Data lives in ./.pandm by default; override with --dir or PANDM_DIR.
Cloud mode
Run a server anywhere, then point training scripts at it — no code changes:
pandm server --api-key my-secret # on the server (default port 7878)
export PANDM_REMOTE=http://my-host:7878
export PANDM_API_KEY=my-secret
python train.py # same script, now reports over HTTP
The API key protects write endpoints only; put the server behind a reverse proxy if reads need auth too. If the server becomes unreachable mid-run, the SDK warns and keeps training: it retries every 30s, replays run creation on recovery, and drops whatever was logged while offline.
API
pandm.init(project, name=None, config=None, *, directory=None, remote=None, api_key=None) |
start a run |
run.log(metrics, step=None) |
log scalar metrics |
run.log_image(key, image, step=None, caption=None) |
log an image |
run.finish(status="finished") |
end the run (also via atexit) |
GET /api/docs |
REST API reference on any running server |
Development
uv sync && uv run pytest # python sdk + server
cd web && pnpm install && pnpm dev # dashboard dev server (proxies to :7878)
pnpm build # bundles the dashboard into src/pandm/static
License
MIT
Project details
Release history Release notifications | RSS feed
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 pandm-0.1.0.tar.gz.
File metadata
- Download URL: pandm-0.1.0.tar.gz
- Upload date:
- Size: 618.8 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
5771e4b27e61d36fb4dddf8841d0b28caac90882bf34b1d36522ae61e7dd8b98
|
|
| MD5 |
e2ea984b21af093e0bf96f8b4352787f
|
|
| BLAKE2b-256 |
b2fb869bdde82dea8088a2b86aeefe7970ef9cb3a6c78cd0730c3f6bc5ded2b6
|
Provenance
The following attestation bundles were made for pandm-0.1.0.tar.gz:
Publisher:
release.yml on Jannchie/pandm
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
pandm-0.1.0.tar.gz -
Subject digest:
5771e4b27e61d36fb4dddf8841d0b28caac90882bf34b1d36522ae61e7dd8b98 - Sigstore transparency entry: 1742670843
- Sigstore integration time:
-
Permalink:
Jannchie/pandm@9b984de027f42fbc868a7b390526d6d9f674541b -
Branch / Tag:
refs/tags/v0.1.0 - Owner: https://github.com/Jannchie
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@9b984de027f42fbc868a7b390526d6d9f674541b -
Trigger Event:
push
-
Statement type:
File details
Details for the file pandm-0.1.0-py3-none-any.whl.
File metadata
- Download URL: pandm-0.1.0-py3-none-any.whl
- Upload date:
- Size: 435.4 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
347b126f82c6829ff66b2710d5b572386103f9ac96a7d52560ee62f78812a2da
|
|
| MD5 |
7a4ae2f3a566b03ec66c8b18e6ade6a0
|
|
| BLAKE2b-256 |
0a9fe7b6238ec91f87844fc9e9d5a21f15ce5475b3f667bab29b6af64bfffcbb
|
Provenance
The following attestation bundles were made for pandm-0.1.0-py3-none-any.whl:
Publisher:
release.yml on Jannchie/pandm
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
pandm-0.1.0-py3-none-any.whl -
Subject digest:
347b126f82c6829ff66b2710d5b572386103f9ac96a7d52560ee62f78812a2da - Sigstore transparency entry: 1742670937
- Sigstore integration time:
-
Permalink:
Jannchie/pandm@9b984de027f42fbc868a7b390526d6d9f674541b -
Branch / Tag:
refs/tags/v0.1.0 - Owner: https://github.com/Jannchie
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@9b984de027f42fbc868a7b390526d6d9f674541b -
Trigger Event:
push
-
Statement type: