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 remembered locally across reloads; 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.5.0

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.5.0
File Size Uploaded Provenance Actions
expr_tracker-0.5.0.tar.gz 1.3 MB With provenance Details for expr_tracker-0.5.0.tar.gz

Built distributions (wheels)

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

Total release size: 16.7 MB

Release files / expr_tracker-0.5.0.tar.gz

Download URL expr_tracker-0.5.0.tar.gz
Size 1.3 MB
Tags Source
SHA-256 checksum
How to use checksums
87015065531d553ce0b8b15375c1d4eb29eddb6bdf0e0a7f590951006eadd23c
BLAKE2b-256 checksum
How to use checksums
4a29d3d681847be9c326a759306be9ac309fa9e294dd936fd7047fc729e2a094
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 Oct 30, 2026.

Transparency log

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

Download URL expr_tracker-0.5.0-cp310-abi3-win_amd64.whl
Size 3.0 MB
Tags CPython 3.10 Windows x86-64 abi3
SHA-256 checksum
How to use checksums
483d4dbc180f8612c92414045e70dd815a18c9a16026d541d075d496dd109b03
BLAKE2b-256 checksum
How to use checksums
3c924f6ea88ad057d259c50c9099f46d55384c68198d387d262e35a2aec69110
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 Oct 30, 2026.

Transparency log

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

Download URL expr_tracker-0.5.0-cp310-abi3-manylinux_2_28_x86_64.whl
Size 3.2 MB
Tags CPython 3.10 Linux glibc 2.28+ x86-64 abi3
SHA-256 checksum
How to use checksums
116200a807d849213a9046881f1582b8c8a71dcda7533e27137dc64790ae790f
BLAKE2b-256 checksum
How to use checksums
720b8921e3b2358a6ee5dd9dfbd6ae37243ddaa4e73d6d210b05837e082d8f75
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 Oct 30, 2026.

Transparency log

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

Download URL expr_tracker-0.5.0-cp310-abi3-manylinux_2_28_aarch64.whl
Size 3.2 MB
Tags CPython 3.10 Linux glibc 2.28+ ARM64 abi3
SHA-256 checksum
How to use checksums
d447743d2facc637a250f22644b57b4b5287818e0259ccb5da6210044c089a01
BLAKE2b-256 checksum
How to use checksums
3351beccae65242b8f8857fc82d05682efbf5e88ecc29c83421e728d26f2b24c
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 Oct 30, 2026.

Transparency log

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

Download URL expr_tracker-0.5.0-cp310-abi3-macosx_11_0_arm64.whl
Size 2.9 MB
Tags CPython 3.10 abi3 macOS 11.0+ ARM64
SHA-256 checksum
How to use checksums
98f537142b181a0396a931b4427b34993f650eff9d371c0c8616621e01ad9828
BLAKE2b-256 checksum
How to use checksums
9e4f8e34d85d43c4eb5b83b79e8ac6a57c1f778b5f2bf2237c7ba3169cf0d950
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 Oct 30, 2026.

Transparency log

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

Download URL expr_tracker-0.5.0-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
311eaffb82abf4f3e999acbc5f755f711f951fe2f5c0f4d9050d99275c8b7a7d
BLAKE2b-256 checksum
How to use checksums
74e0d50e5538fb055eb8c5cdd445fb040d6a50452af4293dc46252a29a708990
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 Oct 30, 2026.

Transparency log

Security for expr-tracker 0.5.0

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.5.0.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 Oct 30, 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