Skip to main content

Experiment Tracker

PyPI Python License Docs

A local-first experiment tracker. Metrics land in a JSONL file you own, stay queryable while the run is live, and can trigger alerts from an expression language. wandb and trackio are optional mirrors, not requirements.

📖 Documentation: https://hspk.github.io/expr_tracker/

import expr_tracker as et

et.init(project="demo", name="run-1", alert_rules=["zscore(loss[50]) > 3 => error: spike"])
for step in range(1000):
    et.log({"loss": loss, "lr": lr})
et.finish()

et.history(50)                    # the last 50 steps, as dicts
et.history(-1, output_type="pd")  # everything, as a DataFrame

Why

  • The file is the source of truth. One JSON object per step, appended to metrics.jsonl, automatically split into retained segments at 100 MiB. History queries read all segments transparently. No server, no database, no vendor.

  • History is queryable during the run. et.history(n) answers from an in-memory cache and reads older records from the local files.

  • Alerts are expressions, not callbacks. zscore(loss[50]) > 3 or isnan(loss) is parsed, validated, and evaluated against a rolling window. Rules can be replayed over a finished run to tune thresholds before you trust them.

  • It stays out of the way. A failed disk, a dead webhook or an unserialisable value degrades with a warning; none can stop training.

Local Web workspace

The native development build includes a local, read-only Web workspace:

et serve --root ./tracker/jsonl

Open http://127.0.0.1:9110 to inspect metrics, compare runs, follow new records, and view config, summary, and spans across rotation segments. Enter the random key printed at startup in the viewer's login form. The default listener is 0.0.0.0; use a trusted network or HTTPS/SSH for remote access. Use Add run to select each run's directory on the server. Added runs are saved on the server and shared across browsers; subdirectories are not scanned for runs. See the viewer guide and native build instructions.

Install

uv add expr_tracker                 # local-first; no remote backend required
uv add "expr_tracker[wandb]"        # mirror to Weights & Biases
uv add "expr_tracker[trackio]"      # mirror to trackio
uv add "expr_tracker[pandas]"       # history(output_type="pandas")
uv add "expr_tracker[all]"          # everything

Only the JSONL history is built in. A missing extra is reported with the exact install command; it never crashes a run.

Features

Logging One line per step. Several log() calls for one step merge into one row, wandb-compatible step/commit semantics, numpy and pydantic values handled.
History et.history(n) during or after the run, offline reads of any run directory, dict/pandas/polars output, bounded in-memory cache with observable hit rate.
Alerts An expression DSL with rolling windows, three-valued logic (no false alarms during warm-up), a rule state machine, and a watchdog that catches a hung run.
Channels Lark, Slack, DingTalk, WeCom, generic webhook, email — with rate limiting, dedup, retries and per-channel routing.
Artifacts Versioned file sets, deduplicated by content, shared across a project's runs, with lineage.
Spans Time the parts of a step, and their parts. Each duration becomes a metric, so alerts and queries work on it unchanged; et trace exports the timeline for Perfetto. print_fn prints the tree live, and plugins attach CPU and GPU cost to each region.
Streams Independent producers — a data worker and a training loop — each with their own step cursor and file inside one run.
Distributed Per-rank shards so concurrent appends cannot corrupt step order; only rank 0 alerts by default.
CLI et history, et trace, et rules explain, et rules test, et alert.

Examples

Every one runs offline, with no account and no network.

quickstart.py The sixty-second tour: log a run, merge eval into the training step, read the history back while it is open and again afterwards.
alert_rules.py Four rules against four faults — a loss spike, a non-finite loss, a stalled curve and a regression that must persist. --fault none fires nothing, which is the point.
profile_step.py Where a step goes. Nested spans become metrics, a plugin adds CPU cost, and the tree exports to Perfetto.
early_stopping.py Querying your own history mid-run to decay the learning rate on a plateau and stop when it stops paying.
checkpoints.py Checkpoints as versioned artifacts, deduplicated by content and fetched later by alias.
multiprocess_pipeline.py Four data producers and four trainers as eight processes in one run, with bounded staleness. Each worker gets its own stream and its own lane in the trace, and the blocking spans show which side is the bottleneck.
uv run python examples/quickstart.py
uv run python examples/alert_rules.py --fault spike
uv run python examples/multiprocess_pipeline.py --produce-ms 10 --train-ms 40

wandb compatibility

Migrating an existing script is usually one line:

# import wandb as et
import expr_tracker as et

init, log, finish, alert, log_artifact, use_artifact, Artifact, define_metric, run.summary, run.step, run.dir and run.url keep their wandb names and signatures. See the compatibility table.

Development

uv sync --all-extras
uv run pytest                                   # everything
uv run pytest -m "not slow and not benchmark"   # the fast suite
uv run pytest -m benchmark -s                   # timing and memory report
uv run pytest --cov=expr_tracker                # coverage
uv run ruff check src tests
uv run ruff format src tests

Test layout

File Covers
test_history, test_expr_*, test_alert_*, test_writer_durability, … per-module unit tests
test_correctness.py value and type round trips, randomised commit sequences, ordering invariants
test_cache.py that the cache really serves reads: zero-IO assertions, eviction boundaries, warm/cold parity
test_failure_modes.py degradation: write failures, read-only dirs, encoder blow-ups, dead alert backends
test_e2e.py full runs, resume, crash recovery, offline reads, CLI
test_scenarios.py live cross-process reads, alerts during eviction, out-of-order resume
test_hot_paths.py contracts and defaults of et.log / et.history / summary / alerts
test_value_encoding.py numpy, pydantic, datetime, Path, Enum round trips; output types; query bounds
test_expr_properties.py DSL properties: render round-trip stability, precedence, the whole M builder
test_trace.py Chrome Trace export: lane layout, stream and step selection, the CLI
test_spans.py nesting, aggregation, decorator and async forms, errors, thread and task isolation
test_examples.py the shipped examples run, and their backpressure claims hold
test_span_plugins.py print_fn output and indentation, the plugin protocol, failure isolation, CPU/GPU built-ins
test_streams.py stream naming and validation, isolation, resolution order, backend grouping, two-process runs
test_distributed.py rank shards, alert_on_rank, real multi-process runs
test_wandb.py real wandb in offline mode: parameter mapping, step alignment, artifacts
test_trackio.py trackio contract, resume mapping, real end-to-end
test_lark.py Lark card construction; real delivery when ET_LARK_TEST_WEBHOOK is set
test_stress.py (slow) 100k-row writes, concurrency, cache thrash, write-failure recovery
test_benchmark.py (benchmark) throughput, tail latency, query cost, memory stability

Docs

uv run --group docs mkdocs serve    # preview at localhost:8000
uv run --group docs mkdocs build    # build into site/

Published to GitHub Pages by .github/workflows/docs.yaml on every push to main. Internals: docs/design.md (data model and key invariants) and docs/architecture.md (module map, read/write paths, concurrency model).

License

MIT

Metadata

Release files for expr-tracker 0.6.1

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for expr-tracker 0.6.1
File Size Uploaded Provenance Actions
expr_tracker-0.6.1.tar.gz 1.3 MB With provenance Details for expr_tracker-0.6.1.tar.gz

Built distributions (wheels)

Table of built distributions (wheels) for expr-tracker 0.6.1
File Actions
expr_tracker-0.6.1-cp310-abi3-win_amd64.whl CPython 3.10 abi3 Windows x86-64 Details for expr_tracker-0.6.1-cp310-abi3-win_amd64.whl
expr_tracker-0.6.1-cp310-abi3-manylinux_2_28_x86_64.whl CPython 3.10 abi3 Linux glibc 2.28+ x86-64 Details for expr_tracker-0.6.1-cp310-abi3-manylinux_2_28_x86_64.whl
expr_tracker-0.6.1-cp310-abi3-manylinux_2_28_aarch64.whl CPython 3.10 abi3 Linux glibc 2.28+ ARM64 Details for expr_tracker-0.6.1-cp310-abi3-manylinux_2_28_aarch64.whl
expr_tracker-0.6.1-cp310-abi3-macosx_11_0_arm64.whl CPython 3.10 abi3 macOS 11.0+ ARM64 Details for expr_tracker-0.6.1-cp310-abi3-macosx_11_0_arm64.whl
expr_tracker-0.6.1-cp310-abi3-macosx_10_12_x86_64.whl CPython 3.10 abi3 macOS 10.12+ x86-64 Details for expr_tracker-0.6.1-cp310-abi3-macosx_10_12_x86_64.whl

Total release size: 17.2 MB

Release files / expr_tracker-0.6.1.tar.gz

Download URL expr_tracker-0.6.1.tar.gz
Size 1.3 MB
Tags Source
SHA-256 checksum
How to use checksums
223dcd600bb12ba59f0d190130d2faf100d5d6349aab8c53cdef516ba935c1f1
BLAKE2b-256 checksum
How to use checksums
a05b2032d6203a42a390b2c12518bd1bd617e879373e67042e1f36fef8103f83
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.16

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 Nov 6, 2026.

Transparency log

Release files / expr_tracker-0.6.1-cp310-abi3-win_amd64.whl

Download URL expr_tracker-0.6.1-cp310-abi3-win_amd64.whl
Size 3.1 MB
Tags CPython 3.10 Windows x86-64 abi3
SHA-256 checksum
How to use checksums
6fbf3c22ac588d09e7bfe2a3b29fdacad288d39c786675956aaab3896549c806
BLAKE2b-256 checksum
How to use checksums
3d6dd7bb0ea9c03a303c06fdc5befaa72047b43910ca500c47fda18eb3d7d33a
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.16

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 Nov 6, 2026.

Transparency log

Release files / expr_tracker-0.6.1-cp310-abi3-manylinux_2_28_x86_64.whl

Download URL expr_tracker-0.6.1-cp310-abi3-manylinux_2_28_x86_64.whl
Size 3.3 MB
Tags CPython 3.10 Linux glibc 2.28+ x86-64 abi3
SHA-256 checksum
How to use checksums
574ea4e427e5f503af2818f753a260e7ff8ddd88544c74226611e7d44b878bfb
BLAKE2b-256 checksum
How to use checksums
7074d64d1554648e42efe086db44b88f2216272b404744b2f9c112d38a66fadb
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.16

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 Nov 6, 2026.

Transparency log

Release files / expr_tracker-0.6.1-cp310-abi3-manylinux_2_28_aarch64.whl

Download URL expr_tracker-0.6.1-cp310-abi3-manylinux_2_28_aarch64.whl
Size 3.3 MB
Tags CPython 3.10 Linux glibc 2.28+ ARM64 abi3
SHA-256 checksum
How to use checksums
2706e5e1380e0f3363714f8999deeea17da762b667440f42423177a150773d8a
BLAKE2b-256 checksum
How to use checksums
d4fd825d37d388391d8ef06f3d33b57d1ff4a59412448a71c2d9acb4cdadcf20
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.16

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 Nov 6, 2026.

Transparency log

Release files / expr_tracker-0.6.1-cp310-abi3-macosx_11_0_arm64.whl

Download URL expr_tracker-0.6.1-cp310-abi3-macosx_11_0_arm64.whl
Size 3.0 MB
Tags CPython 3.10 abi3 macOS 11.0+ ARM64
SHA-256 checksum
How to use checksums
74c4ef23439769b19ed972182006d470396af7f03d86d63cc44a2d71c6122d01
BLAKE2b-256 checksum
How to use checksums
8eb7400ccd30276b8cee13e7bffc25127aadc2857ceb8da577ef2c1e293a41f7
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.16

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 Nov 6, 2026.

Transparency log

Release files / expr_tracker-0.6.1-cp310-abi3-macosx_10_12_x86_64.whl

Download URL expr_tracker-0.6.1-cp310-abi3-macosx_10_12_x86_64.whl
Size 3.1 MB
Tags CPython 3.10 abi3 macOS 10.12+ x86-64
SHA-256 checksum
How to use checksums
2e52d5d040f22cf9c30103ba6a0bd34dcfbce02f2ac953c2129783280f2c8bb3
BLAKE2b-256 checksum
How to use checksums
230691db1650c52351a736eccbd334a2130f4dd1bdad257bfcce25f2efec410c
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.16

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 Nov 6, 2026.

Transparency log

Security for expr-tracker 0.6.1

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.

Full provenance

All 6 files in this release have been uploaded with provenance metadata.

Select from 6 files

Attestation for expr_tracker-0.6.1.tar.gz

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 Nov 6, 2026.

Transparency log

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page