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 2025.12.99-1b4706d3)

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. The port is auto-selected from the 8080-8099 range unless specified.

[ ]:
# Uncomment and adjust the path for your system:
wb_new = mw.launch("D:\\Dev\\MITK\\installers\\MITK-v2026.06-rc1-windows-x86_64\\MitkWorkbench.bat", port=8085)

# Or use the MITK_WORKBENCH environment variable:
import mitk_workbench_remote as mw
import os
os.environ["MITK_WORKBENCH"] = "D:\\Dev\\MITK\\installers\\MITK-v2026.06-rc1-windows-x86_64\\MitkWorkbench.bat"
# wb_new = mw.launch(port=8085)

# For this example, we attempt launch and handle the error gracefully
try:
    wb_new = mw.launch(timeout=15)
    print(f"Launched at {wb_new.url}")
    print(f"  MITK version: {wb_new.info.mitk_version}")
    print(f"  Managed process: {wb_new.is_launched_remotely}")
except (mw.errors.MitkError, FileNotFoundError) as e:
    wb_new = None
    print(f"Could not launch: {e}")
    print("Set MITK_WORKBENCH env var or pass the executable path.")
pydev debugger: Unable to find real location for: <frozen runpy>

6. Multi-Workbench workflow

Each Workbench handle is independent — no global state is shared. You can show the same data in all running instances.

[ ]:
all_instances = mw.discover()
data = np.random.default_rng(7).random((32, 32, 32), dtype=np.float32)

nodes = []
for wb in all_instances:
    n = wb.show(data, name="Shared Data")
    nodes.append((wb, n))
    print(f"Showed in {wb.url}")

# Clean up
for wb, n in nodes:
    n.remove()

print(f"\nShowed data in {len(all_instances)} instance(s)")

7. 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.

[ ]:
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.")