Skip to main content

Odin monitor

Experimental release!

Odin provides lightweight progress reporting for long-running computations. Monitor running programs — progress bars, warnings, errors — from a browser or terminal, with almost no extra code. Start a server, add two lines to your code, and watch it from anywhere your laptop can connect.

Odin works with Python, C++, and shell scripts.

Here is a minimalistic example for how to add a progressbar to a Python script:

from odin import track

for item in track(my_list, label="processing"):
    do_work(item)

Features

  • Minimal API — wrapping an existing loop takes one line
  • Live browser dashboard — auto-updating, no page refreshes. See example below!
  • Live terminal dashboard — odin watch for a rich live table in your terminal. Good to have when your jobs are on a remote server. See example below!
  • Multi-language — Python and C++ reporter libraries; shell one-liners via the odin CLI
  • Graceful fallback — if no server is running, output goes to stderr (or your logger); your code keeps working
  • ETA estimation — time-remaining shown once enough data has accumulated
  • Integrates with Python logging — pass a logger= argument and Odin uses it as the fallback
  • Process death detection — reporters that crash or are killed are automatically marked as died

Installation

The odin package that provides server, terminal-based dashboard, and module for progress reporting in Python programs is typically installed like this (from pypi.org):

pip install odin-monitor

The package requires Python 3.10+. The package installs as odin — use from odin import ... in your code.

For progress reporting in C++ code you download cpp/odin.hpp from this repository to your project – this is a header-only dependency and no further installation is required.


Quickstart

1. Start the server

odin serve

Open http://localhost:6271 in a browser. Or run odin watch in a second terminal for a terminal view.

2. Report from Python

Wrap any iterable with track():

from odin import track

for item in track(my_list, label="training"):
    process(item)

Or use Reporter directly for more control:

from odin import Reporter

r = Reporter("simulation", total=1000)
for i in range(1000):
    run_step(i)
    r.progress(i + 1)
    if something_odd:
        r.warning("Step took longer than expected")
r.done()

Use it as a context manager and exceptions are reported automatically:

with Reporter("risky job", total=100) as r:
    for i in range(100):
        r.progress(i + 1)
        do_work(i)          # if this raises, the error is reported before propagating

3. Stop the server

odin stop

C++ usage

Copy cpp/odin.hpp from the repository into your project — no build system changes needed beyond adding the include path.

#include "odin.hpp"
#include <vector>

int main() {
    // Wrap a container — progress reported automatically
    std::vector<double> data = load_data();
    for (auto& item : odin::track(data, "processing")) {
        process(item);
    }

    // Or use Reporter directly
    odin::Reporter r("simulation", 1000);
    for (int i = 0; i < 1000; ++i) {
        run_step(i);
        r.progress(i + 1);
        if (something_odd) r.warning("Step took too long");
    }
    r.done(); // optional — destructor calls it automatically
}

Compile with C++17 and pthreads:

g++ -std=c++17 -pthread -I/path/to/odin/cpp myprogram.cpp -o myprogram

Exceptions thrown inside odin::track() are automatically reported as errors before propagating.


Shell usage

Report progress from shell scripts using the odin CLI:

odin progress "pipeline" 0 5

for step in 1 2 3 4 5; do
    do_work "$step"
    odin progress "pipeline" "$step" 5
done

odin info    "pipeline" "All steps complete"
odin warning "pipeline" "Disk usage above 80%"
odin error   "pipeline" "Input file missing"

Each odin call connects, sends one message, and exits. If no server is running the commands are silent no-ops.


Snakemake integration

Pipe a running Snakemake workflow's output through odin snakemake to report its progress without changing the workflow itself:

snakemake 2>&1 | odin snakemake

odin snakemake echoes every line straight through to the terminal (so the normal Snakemake output is unaffected), while parsing lines like "15 of 30 steps (50%) done" into progress updates and known Snakemake failure markers (Error in rule ...:, WorkflowError:, etc.) into error reports. Use --label to give it a custom session name, e.g. odin snakemake --label my-pipeline. See examples/snakemake/ for a runnable demo workflow.


Integration with Python logging

Pass a standard logging.Logger and Odin uses it as the fallback when no server is running. Users who don't know about Odin get normal log output; users with a server running get the full dashboard.

import logging
from odin import Reporter, track

log = logging.getLogger(__name__)

r = Reporter("job", total=100, logger=log)
# or
for item in track(data, label="job", logger=log):
    process(item)

Message types

Method Meaning
r.progress(value) Update progress (0 … total)
r.info(message) Informational note
r.warning(message) Something unexpected but non-fatal
r.error(message) An error occurred
r.done() Job finished cleanly (optional — the server also detects clean exit)

Server options

odin serve [--retention SECONDS]

--retention controls how long finished or died sessions remain visible before being removed (default: 30 seconds). Use 0 to keep them until the server restarts.

For remote access from another machine, use an SSH tunnel:

# on the viewing machine:
ssh -L 6271:localhost:6271 user@compute-server
# then open http://localhost:6271

How it works

Reporters connect to a Unix socket (~/.odin) on startup and hold the connection open. The server keeps only the latest state for each reporter and pushes updates to connected viewers over WebSocket. When a reporter's connection drops without a done message, the server marks it as died.

Because the server is single-threaded asyncio and each reporter has its own connection, there are no race conditions — multiple reporters writing simultaneously is safe by design.

The wire protocol is documented in PROTOCOL.md. It is simple enough to implement a reporter in any language in an afternoon.


Publishing / distribution

Python — install from PyPI:

pip install odin-monitor

C++ — the library is a single header file. Copy it directly:

wget https://raw.githubusercontent.com/arvestad/odin/main/cpp/odin.hpp

Or add the repo as a git submodule:

git submodule add https://github.com/arvestad/odin deps/odin
# then add -Ideps/odin/cpp to your compiler flags

License

MIT

Dashboard examples

The following dashboards show concurrent execution of Python scripts in the examples folder.

Browser dashboard (http://localhost:6271):

Browser dashboard

Terminal dashboard (odin watch):

Terminal dashboard

Metadata

Release files for odin-monitor 1.2

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

Source distribution (sdist)

Source distribution for odin-monitor 1.2
File Size Uploaded
odin_monitor-1.2.tar.gz 709.4 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for odin-monitor 1.2
File Interpreter ABI Platform
odin_monitor-1.2-py3-none-any.whl Python 3 none any Details

Total release size: 729.9 kB

Release files / odin_monitor-1.2.tar.gz

Download URL odin_monitor-1.2.tar.gz
Size 709.4 kB
Tags Source
SHA-256 checksum
How to use checksums
f1cc6d9aa268f920737940603b4ed155462f8d0cbd630c685e5efe8121763a9c
BLAKE2b-256 checksum
How to use checksums
b7c75be68a57afd7830ec199eef559b1a1da7ff039bf040fe484773228aad6e6
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 Aug 13, 2026.

Transparency log

Release files / odin_monitor-1.2-py3-none-any.whl

Download URL odin_monitor-1.2-py3-none-any.whl
Size 20.5 kB
Tags Python 3
SHA-256 checksum
How to use checksums
ca0a85608a174d70b1806a9c18f2a3fce1e1582a04fa34ef00193659eccb11d6
BLAKE2b-256 checksum
How to use checksums
0e5d4b64752ab0bc40fed71f0444b00e6e055cc0a849a63608a202f540c57e8a
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 Aug 13, 2026.

Transparency log

Release history Release notifications | RSS feed

This release

1.2 This release

2 release files

1.1

2 release files

0.5.0

2 release files

0.4.0

2 release files

0.3.0

2 release files

0.2.0

2 release files

0.1.0

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