Skip to main content

interox

Interactive outcome explanation for process-mining case logs.

interox helps you find out why some cases of a process end the way they do. You hand it a case log and a boolean outcome; it suggests DNF rules (via a fork of RIPPER rule induction) that tell the outcome cases apart from the rest, and gives you notebook widgets to inspect, store, edit and build rules until the outcome is explained.

uv add interox        # or: pip install interox

The widgets ship pre-built inside the package, so using interox needs no Node or JavaScript toolchain.

Use

from interox import InterOX

iox = InterOX(outcome, case_log)   # outcome: bool Series, case_log: DataFrame, same index

iox.get_exp_status()               # how much of the outcome the stored rules explain
iox.get_suggested_ruleset()        # induced suggestions, as a table widget
iox.get_stored_ruleset()           # the rules you kept
iox.get_rule_builder()             # build a rule from scratch

Rendering needs a notebook that speaks anywidget: marimo, Jupyter, VS Code. The API reference is generated from the docstrings:

uv run pdoc interox

A complete walkthrough on a public event log lives in interox-nodebook-sepsis.

Requirements

Python 3.13+ and pandas 3. Case-log enrichment comes from eclear and rule induction from rulelearn-ripper-interactive (imported as rulelearn_ri); both install as dependencies.

Development

Everything Python goes through uv:

uv sync                # creates .venv with interox (editable) + the dev group
./code-check.sh        # pylint + mypy + pytest

The widgets are React 18 + TypeScript in js/, bundled with esbuild into interox/static/*.js:

cd js
npm ci                 # install React, esbuild, TypeScript tooling
npm run build          # minified production bundles → ../interox/static/
npm run dev            # watch mode, unminified, for working on a widget
npm run typecheck      # esbuild does not typecheck; run this separately

See DEVELOPMENT.md for the architecture, DECISIONS.md for why it is shaped this way, and ubiquitous-language.md for the agreed vocabulary.

How the compiled widgets get into the package

Each widget class points _esm at a file next to it, e.g. pathlib.Path(__file__).parent / "static" / "rule_builder.js". anywidget reads that file when the widget is created, so the bundle has to be inside the installed package. Two things make sure it is:

  • interox/static/*.js is committed on purpose (the same choice as eclear). Whatever is in git is what a build from a clean checkout ships, and a notebook user never runs npm.
  • [tool.hatch.build.targets.wheel] packages = ["interox"] puts the whole interox/ directory, static/ included, into the wheel. js/ and tests/ stay out of the wheel; the sdist carries them so it can be rebuilt.

So the rule is: whenever anything under js/src changes, run npm run build and commit the regenerated interox/static/*.js together with the source change. A stale bundle is the one packaging mistake that goes unnoticed until someone opens a notebook.

Releasing to PyPI

Run from the repo root. Nothing here is automated: an upload is irreversible, so each step is yours to run.

1. Rebuild the widgets and re-verify against exactly what you will ship:

(cd js && npm ci && npm run typecheck && npm run build)
git status --short interox/static    # changed bundles? commit them first
./code-check.sh

2. Bump the version in pyproject.toml (version = "0.1.0"). A version number can never be reused on PyPI, even after deleting the release.

3. Build the distributions:

rm -rf dist/
uv build
uvx twine check dist/*
unzip -l dist/interox-*.whl

The wheel listing must contain the four bundles interox/static/{rule_detail,ruleset_table,explanation_status,rule_builder}.js and must not contain js/, node_modules or tests/.

4. Smoke-test the built wheel from a directory that is not this repo, otherwise Python imports the local interox/ folder and you have tested nothing:

cd /tmp
uv run --isolated --no-project --with ~/Developer/interox/dist/interox-0.1.0-py3-none-any.whl \
  python -c "import interox, interox.rule_builder_widget as w; print(interox.__file__); print(len(str(w.RuleBuilderWidget._esm)))"

The path must be inside a site-packages, and the length must be well above zero: that is the bundle anywidget will send to the notebook.

5. Dry run on TestPyPI (separate site, separate account and token: https://test.pypi.org/manage/account/token/):

uv publish --publish-url https://test.pypi.org/legacy/
cd /tmp
uv run --isolated --no-project \
  --index https://test.pypi.org/simple/ --index-strategy unsafe-best-match \
  --with interox python -c "import interox; print(interox.__file__)"

The extra index flags are needed because the dependencies come from real PyPI.

6. Publish for real. Create a token at https://pypi.org/manage/account/token/. For a project that does not exist yet it must be account-scoped; after the first upload, replace it with a project-scoped one.

read -rs UV_PUBLISH_TOKEN && export UV_PUBLISH_TOKEN && uv publish

7. Tag the release:

git tag v0.1.0
git push origin main --tags

Later, PyPI trusted publishing (a GitHub Actions workflow that uploads on a pushed tag, no stored token) removes the token step: https://pypi.org/manage/project/interox/settings/publishing/.

Metadata

Release files for interox 0.1.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 interox 0.1.0
File Size Uploaded Provenance Actions
interox-0.1.0.tar.gz 322.0 kB Without provenance Details for interox-0.1.0.tar.gz

Built distribution (wheel)

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

Total release size: 575.7 kB

Release files / interox-0.1.0.tar.gz

Download URL interox-0.1.0.tar.gz
Size 322.0 kB
Tags Source
SHA-256 checksum
How to use checksums
09b56144697d2db7363f48f0f232ec3b56c0410dcb6ce12d7d3c3a4ddca3090f
BLAKE2b-256 checksum
How to use checksums
1853bb2de0b44accf775185e3559071719e14955420fd211fc8f1085c1feff13
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via uv/0.11.12 {"installer":{"name":"uv","version":"0.11.12","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Fedora Linux","version":"44","id":"","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}

Release files / interox-0.1.0-py3-none-any.whl

Download URL interox-0.1.0-py3-none-any.whl
Size 253.7 kB
Tags Python 3
SHA-256 checksum
How to use checksums
2449fda7114aae011b9e430a4fe1ad3545cae06a48876e98575430faee3c8385
BLAKE2b-256 checksum
How to use checksums
4de6d9de64cdba776bc058c4a72c9421f37745ce8b004eb22e472cd117df0e08
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via uv/0.11.12 {"installer":{"name":"uv","version":"0.11.12","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Fedora Linux","version":"44","id":"","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}

Security for interox 0.1.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.

No provenance found

None of the files in this release were uploaded with provenance metadata.

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.

Release history Release notifications | RSS feed

This release

0.1.0 This release

2 release files No provenance

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