Discovery and Launch

This notebook demonstrates how to find running MITK Workbench instances and start new ones programmatically.

You will learn how to:

  • Discover running Workbench instances with mw.discover()

  • Connect to a discovered instance

  • Launch a new Workbench with mw.launch()

  • Work with multiple Workbench instances

  • Shut down a launched Workbench

Prerequisites:

  • For discovery: at least one running MITK Workbench with the REST API enabled

  • For launch: the MITK_WORKBENCH environment variable pointing to the Workbench executable, or pass the path explicitly

1. Discover running instances

mw.discover() probes localhost ports 8080-8099 (by default) for running MITK Workbench REST servers. Probes run concurrently, so scanning 20 ports takes about as long as a single probe.

Each found instance is returned as a ready-to-use Workbench handle.

[1]:
import mitk_workbench_remote as mw

instances = mw.discover()
print(f"Found {len(instances)} running Workbench instance(s):\n")

for wb in instances:
    info = wb.info
    print(f"  {wb.url}{info.name} (MITK {info.mitk_version})")
Found 1 running Workbench instance(s):

  http://localhost:8080  —  MITK Workbench REST API (MITK 2026.06.00)

2. Use a discovered instance

The returned Workbench handles work exactly like those from mw.connect(). Pick one and use it.

[2]:
import numpy as np

if instances:
    wb = instances[0]
    node = wb.show(
        np.random.default_rng(42).random((32, 32, 32), dtype=np.float32),
        name="Discovery Demo",
    )
    print(f"Showed data in {wb.url}")
    node.remove()
else:
    print("No instances found — start a Workbench and re-run this cell.")
Showed data in http://localhost:8080

3. Connecting to an auth-enabled instance

A Workbench can be configured to require authentication: in the REST API preferences, set requireAuth=true and a non-empty apiToken. Every request then needs an Authorization: Bearer <token> header, which connect() adds when you pass token:

secured = mw.connect("http://localhost:8080", token="your-api-token")
print(secured.info.name)

launch() (section 5) does this automatically: it generates a random token and wires it into the returned handle. You only need to pass a token yourself when connecting to an already-running instance that was secured manually.

Caveat for ``discover()``: discovery probes /health, which is exempt from authentication, so auth-enabled instances are still found. But the returned handles carry no token, and discovery cannot tell whether an instance requires auth (the server does not advertise it). The first non-exempt call against a secured instance therefore raises AuthenticationError. If you know an instance is secured, reconnect with the token:

secured = mw.connect(wb.url, token="your-api-token")

4. Custom port range

Pass a custom port range if your Workbench is on a non-default port.

[3]:
# Scan a wider range
found = mw.discover(ports=range(8080, 8200), timeout=1.0)
print(f"Found {len(found)} instance(s) in port range 8080-8199")
Found 1 instance(s) in port range 8080-8199

5. Launch a new Workbench

mw.launch() starts a new MITK Workbench process with the REST API enabled. It waits for the server to become healthy, then returns a connected Workbench handle.

The executable is resolved from:

  1. The executable argument (if given)

  2. The MITK_WORKBENCH environment variable

A secure random API token is generated automatically and passed to the process through the MITK_REST_API_TOKEN environment variable, so it is never written to disk while requireAuth still enforces it. The port is auto-selected from the 8080-8099 range unless specified.

MITK Workbench is single-instance. If a Workbench is already running, starting the executable again hands off to that instance and exits without bringing up a REST server on the new port. launch() detects this and raises a clear error telling you to connect to the running instance instead (sections 1-2). Pass new_instance=True to force a separate, isolated instance anyway (next cell).

[4]:
import os

import mitk_workbench_remote as mw

# Point MITK_WORKBENCH at a Workbench build whose REST API is available.
# Adjust this path to your own installation.
os.environ["MITK_WORKBENCH"] = (
    r"YOUR_MITK_INSTALL_PATHD/MitkWorkbench.bat"
)

try:
    wb_new = mw.launch(timeout=30)
    print(f"Launched at {wb_new.url}  (MITK {wb_new.info.mitk_version})")
    print(f"  Managed process: {wb_new.is_launched_remotely}")
except mw.errors.MitkError as e:
    # Most common cause: a Workbench is already running (single-instance), or
    # MITK_WORKBENCH is unset / points at a build without the REST API.
    wb_new = None
    print(f"Could not launch: {e}")
    print("Tip: connect to a running instance with mw.discover() / mw.connect(),")
    print("or pass new_instance=True to force a separate instance.")
except FileNotFoundError as e:
    wb_new = None
    print(f"Executable not found: {e}")
Launched at http://localhost:8080  (MITK 2026.06.00)
  Managed process: True

Forcing a second, isolated instance

When a Workbench is already open and you want a separate one under REST control, pass new_instance=True:

wb_extra = mw.launch(new_instance=True)

The forced instance runs from a throwaway storage directory (MITK does not remove it afterwards) and, like every launched instance, receives its API token through the environment rather than on disk. When nothing is running, new_instance has no effect — an ordinary launch() already gives you a fresh instance.

6. Shutdown

wb.shutdown() terminates a Workbench that was started with mw.launch(). It also closes the underlying transport session.

Only instances started by launch() can be shut down — calling shutdown() on a connect()-ed handle raises MitkError. Use wb.is_launched_remotely to check.

[5]:
if wb_new is not None:
    print(f"Shutting down {wb_new.url} ...")
    wb_new.shutdown()
    print("Done.")
else:
    print("No launched instance to shut down.")
Shutting down http://localhost:8080 ...
Done.