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 watchfor 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
odinCLI - 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.
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):
Terminal dashboard (odin watch):
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 odin_monitor-0.5.0.tar.gz.
File metadata
- Download URL: odin_monitor-0.5.0.tar.gz
- Upload date:
- Size: 706.8 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via:
twine/6.1.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
e691791f29db5d89f3f3fc8a952258616bb3754e3af6cf18e3b24900067b6689
|
|
| MD5 |
efae3d9cd680bbdec5bd146306348c48
|
|
| BLAKE2b-256 |
43e9bd416a5396ee81269d5fcf3a1b57999dc82c7fd3c022b9cb2ef5804cba69
|
Provenance
The following attestation bundles were made for odin_monitor-0.5.0.tar.gz:
Publisher:
publish.yml on arvestad/odin
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
odin_monitor-0.5.0.tar.gz -
Subject digest:
e691791f29db5d89f3f3fc8a952258616bb3754e3af6cf18e3b24900067b6689 - Sigstore transparency entry: 2257179304
- Sigstore integration time:
-
Permalink:
arvestad/odin@b096d2b1ef28aef408730371df825830630938c3 -
Branch / Tag:
refs/tags/v0.5.0 - Owner: https://github.com/arvestad
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@b096d2b1ef28aef408730371df825830630938c3 -
Trigger Event:
push
-
Statement type:
File details
Details for the file odin_monitor-0.5.0-py3-none-any.whl.
File metadata
- Download URL: odin_monitor-0.5.0-py3-none-any.whl
- Upload date:
- Size: 19.0 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via:
twine/6.1.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
48e5366eaccfea682210e77027293a14bd42eee0e7bd11541d5023d3b17d4531
|
|
| MD5 |
eabc5fef8d15d9dfa574320384cb5870
|
|
| BLAKE2b-256 |
67534635a8346f7f92258d0dd830c4e676bc17e648ddf1d20901988e373b2dd2
|
Provenance
The following attestation bundles were made for odin_monitor-0.5.0-py3-none-any.whl:
Publisher:
publish.yml on arvestad/odin
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
odin_monitor-0.5.0-py3-none-any.whl -
Subject digest:
48e5366eaccfea682210e77027293a14bd42eee0e7bd11541d5023d3b17d4531 - Sigstore transparency entry: 2257179312
- Sigstore integration time:
-
Permalink:
arvestad/odin@b096d2b1ef28aef408730371df825830630938c3 -
Branch / Tag:
refs/tags/v0.5.0 - Owner: https://github.com/arvestad
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@b096d2b1ef28aef408730371df825830630938c3 -
Trigger Event:
push
-
Statement type: