Skip to main content

Artitrack

Artitrack is a local-first experiment tracker and launcher built on xmanager, task-spooler, and ML Metadata. It provides a Python API for defining experiments and a CLI for querying and managing runs, executions, artifacts, and metrics. CLI output is plain text and fzf-friendly.

Core Concepts

  • Experiment: A top-level grouping of related pipeline runs.
  • Run: A tracked execution of a pipeline within an experiment.
  • Execution (job): A single step submitted to task-spooler.
  • Artifact: Inputs/outputs tied to executions (datasets, models, reports).
  • Metric: Values extracted from job logs or registered manually.

Requirements

  • Python 3.10 or 3.11
  • task-spooler q command on PATH
  • ml-metadata for local tracking (Linux only)

Data Directory

Artitrack stores metadata in ~/.at by default. Override with ARTITRACK_DATA_DIR.

Python API (xmanager style)

Artitrack's launcher subclasses xm.Experiment/xm.WorkUnit — it is genuinely xmanager-compatible, not just vocabulary-compatible. Two surfaces are available, trading portability for artitrack's DAG/dedup features:

Portable subset — xm.Job/JobGroup, args, role, identity, exp.add(), wait_until_complete() follow real xmanager's own contract, so a script written to this shape ports to real xmanager by swapping the import for xmanager's own xm_local (or another real backend) and its executor — no other code changes. xm_local.TaskSpooler() itself, and the experiment_title= kwarg spelling, are artitrack-specific and have no real-xmanager equivalent to swap in verbatim:

from xmanager import xm

from artitrack.launcher import xm_local


def main() -> None:
    with xm_local.create_experiment(experiment_title="quick_test") as exp:
        exp.add(
            xm.Job(
                name="train",
                executable=xm.Binary(path="python train.py"),
                executor=xm_local.TaskSpooler(),
                args={"learning_rate": 0.001},
            )
        )

Artitrack-native surface — adds dependency ordering and artifact-based dedup, at the cost of portability to real xmanager:

from xmanager import xm

from artitrack.launcher import xm_local


def main() -> None:
    with xm_local.experiment(name="quick_test") as exp:
        with exp.run(title="train_then_eval") as run:
            train_handle = run.add(
                xm.Job(
                    name="train",
                    executable=xm.Binary(path="python train.py"),
                    executor=xm_local.TaskSpooler(),
                    args={"learning_rate": 0.001},
                ),
                output_artifacts={"model": {"path": "/data/model.pt", "type": "Model"}},
            )
            run.add(
                xm.Job(
                    name="eval",
                    executable=xm.Binary(path="python eval.py"),
                    executor=xm_local.TaskSpooler(),
                ),
                depends_on=train_handle,
                input_artifacts={"model": {"path": "/data/model.pt", "type": "Model"}},
            )

depends_on/input_artifacts/output_artifacts/force/at_resume/est_time are keyword-only extras on run.add() — they are not part of exp.add()'s inherited xmanager signature, so mixing surfaces per-job is a TypeError, not a silent no-op.

Examples live in examples/.

Quick start:

python examples/quick_pipeline.py

A sync-sentinel job is submitted automatically after all pipeline jobs to record terminal state in MLMD when the experiment context exits.

CLI

The CLI reads from the local metadata store and provides management tools.

Quick Commands

# What's running right now?
at status

# Show recent runs
at runs
at runs --failed
at runs -e my-experiment -n 5

# Show a specific run
at run <run-id>

# Most recent run
at run last

# Why did it fail?  Grab the job log
at runs --failed
at log <job-id>

# Jobs and artifacts
at jobs
at job <job-id>
at query --entity artifact

Management

  • at info shows database stats.
  • at sync refreshes run/job status from task-spooler.
  • at cancel <run-id>... cancels one or more runs.
  • at delete cleans runs from the store.
  • at update edits runs or executions.
  • at metrics --run <run-id> shows metrics for a run.

Artifact Provenance

Find all runs that produced or consumed a given artifact:

# Which runs produced this model?
at query --entity run --output "models/model.pt"

# Which runs used this dataset as input?
at query --entity run --input "data/train.csv"

# Combine input and output filters
at query --entity run --input "data/train.csv" --output "models/model.pt"

Run Commands and Git Info

Inspect the exact commands, repository, and commit for each job in a run:

# Show full run detail (jobs, commands, artifacts, metrics)
at query --entity run <run-id>

# Show a single job's command, git repo, and commit
at query --entity execution <ts-job-id>

The job detail view includes:

  • command: the full shell command used to launch the job
  • git_repo: the remote URL of the repository (for python/uv scripts)
  • git_commit: the exact commit SHA at submission time
  • git_dirty: whether the repo had uncommitted changes

Dirty Repo Guard

When submitting from a git repository with uncommitted changes, artitrack prompts for confirmation. You can either auto-commit (recommended) or skip the check:

# Default: prompts to auto-commit if dirty
at submit -n train -- python train.py

# Skip the check entirely
at submit -n train --allow-dirty -- python train.py

The auto-commit creates a chore: artitrack auto-commit <timestamp> commit with all modified tracked files, so the recorded git_commit always points to reproducible code. The same guard applies to the Python launcher API — it is controlled by the same --at_allow_dirty CLI flag (not a Python kwarg), off by default, read once when experiment()/create_experiment() runs.

Advanced Queries

The query command supports full filtering, ordering, and lineage queries:

# Filter by status
at query --entity run --status failed

# Filter by artifact lineage
at query --entity run --input "data/train.csv"
at query --entity run --output "models/model.pt"

# List jobs or artifacts
at query --entity execution
at query --entity artifact

# fzf-friendly output
at query --entity run --format fzf

Run at query --help for the full filter syntax.

Update Cheatsheet

# Change run status or tags
at update run <run-id> --status cancelled
at update run <run-id> --tag baseline --tag sweep
at update run <run-id> --remove-tag baseline

# Add artifacts or metrics to a job
at update execution <ts-job-id> --artifact /data/model.pt:model
at update execution <ts-job-id> --metric accuracy=0.95

Shell Completion

The completion command prints a shell snippet you can source:

# Print the snippet for the current shell
at completion

Use --shell fish to target a specific shell.

To print the fzf alias snippet:

at completion fzf-aliases --shell fish

fzf Workflow

Artitrack provides tab-delimited output that works well with fzf. Use the --format fzf flag on query to get one-line rows without headers.

# Pick a run and preview details
at query --entity run --format fzf \
  | fzf --delimiter='\t' --with-nth=2,3,4 \
    --preview 'at query --entity run {1}'

# Pick a job and preview details
at query --entity execution --format fzf \
  | fzf --delimiter='\t' --with-nth=1,3,4 \
    --preview 'at query --entity execution {1}'

The fzf alias snippet (fish only) defines these functions:

  • at-runs — browse runs, sorted finished-first
  • at-jobs RUN_ID — browse jobs/steps for a run; Enter opens the log, ctrl-i shows job detail
  • at-tb — pick metrics logdirs and print a tensorboard --logdir_spec string
  • at-trace PATH — trace a file path to the run that produced or consumed it
  • at-watch [RUN_ID | QUERY] — live-monitor a running pipeline, refreshing every 5s

MCP Server

Use the MCP server to expose Artitrack data to LLM clients:

at-mcp

The server uses the same local metadata store as the CLI. CLI output is plain text (or fzf tab-delimited), while MCP tools return JSON. For MCP list calls, some large fields are omitted (for example config and resolved_pipeline_path), so use get_run for full details.

Remote Access via SSH Tunnel

ml-metadata only runs on Linux. To query experiments on obelix from a Mac, tunnel the MCP server over SSH:

at mcp-tunnel obelix

This starts at-mcp on obelix (if not already running), opens an SSH port forward on localhost:8000, and prints the config snippet for ~/.claude/mcp_servers.json:

{
  "artitrack-remote": {
    "type": "streamable-http",
    "url": "http://localhost:8000/mcp"
  }
}

Custom ports and remote working directory:

at mcp-tunnel obelix --port 9000 --remote-port 8001
at mcp-tunnel obelix:/home/hicham/project

Press Ctrl+C to stop the tunnel.

Metadata

Release files for artitrack 2026.9.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 artitrack 2026.9.1
File Size Uploaded
artitrack-2026.9.1.tar.gz 514.5 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for artitrack 2026.9.1
File Interpreter ABI Platform
artitrack-2026.9.1-py3-none-any.whl Python 3 none any Details

Total release size: 974.2 kB

Release files / artitrack-2026.9.1.tar.gz

Download URL artitrack-2026.9.1.tar.gz
Size 514.5 kB
Tags Source
SHA-256 checksum
How to use checksums
86761931446e3806734c6f51d3721da7c635db795ca982db4a702ef5ee648ddf
BLAKE2b-256 checksum
How to use checksums
e75e400a3589f0188357235fa2ba83ec98015434db7a796363c26c711585873c
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 Sep 23, 2026.

Transparency log

Release files / artitrack-2026.9.1-py3-none-any.whl

Download URL artitrack-2026.9.1-py3-none-any.whl
Size 459.7 kB
Tags Python 3
SHA-256 checksum
How to use checksums
a7ae1f34c652bf95676c274952d2d2d460549cd6e9b07659b2c4ef50e209a0ba
BLAKE2b-256 checksum
How to use checksums
44c637251ef1f1f937bc01d701c9317b4f6f17f194bfb08f2fd60ef8cdf5d273
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 Sep 23, 2026.

Transparency log

Release history Release notifications | RSS feed

This release

2026.9.1 This release

2 release files

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