Python reference
dcmview-py is a subprocess wrapper and binary distribution path for the same Rust viewer. It is not a DICOM parsing library.
Signature
Section titled “Signature”view( files, *, port=0, host="127.0.0.1", browser=True, block=True, recursive=True, timeout=None, annotations=None, filters=None, mask=False, vscode_bridge=True,)files accepts one str or path-like value, or an iterable of path-like values.
v0.3.0 removed the tunnel, tunnel_host, and tunnel_port keywords. Passing them raises TypeError. Use SSH forwarding from your local machine instead.
view() has no parameter for --unix-socket, --no-token, or --cache-budget. Socket mode is not available from view(). The module command forwards every CLI option.
Parameters
Section titled “Parameters”| Parameter | Default | Behavior |
|---|---|---|
files |
required | File or directory path, or an iterable of paths. |
port |
0 |
Forwards --port; zero selects an available port. |
host |
"127.0.0.1" |
Forwards --host. |
browser |
True |
False forwards --no-browser. |
block |
True |
Wait for exit, or return a session handle. |
recursive |
True |
False forwards --no-recursive. |
timeout |
None |
Idle timeout in seconds, counted once the scan has finished. |
annotations |
None |
Optional EMBED-style ROI CSV path. |
filters |
None |
Iterable of FIELD=VALUE filters combined with AND semantics. Fields accept snake_case names or DICOM keywords. |
mask |
False |
True forwards --mask: replace patient identifiers in everything the viewer displays, for screen sharing. Display only: files are not modified and this is not de-identification. |
vscode_bridge |
True |
Open in VS Code from a VS Code terminal or inside an open workspace folder. False always launches locally. |
The filter fields are those of the CLI reference. mask starts the masked session described in the CLI reference; it is fixed for that viewer and cannot be turned off through the handle.
Return values
Section titled “Return values”With block=True, a successful call returns None after the session exits. Interrupting the call, for example with a notebook interrupt, stops the viewer before the KeyboardInterrupt is re-raised.
With block=False, it returns a ShutdownHandle for both a local viewer and a VS Code-managed viewer. The handle exposes:
| Attribute or method | Behavior |
|---|---|
.url -> str | None |
Read-only launch URL, verbatim from startup, including the #token=… fragment when the token is enabled. |
.token -> str | None |
Read-only bearer token reported at startup. None when absent or under --no-token. |
.base_url -> str | None |
Read-only HTTP origin reported at startup, without the token fragment. None when absent. |
.stop(timeout=5.0) -> int |
Ask the viewer to stop, wait for exit, and return the exit code. |
| Context manager | Calls stop() on exit. |
.token and .base_url are new in v0.4.0. Binaries older than v0.4.0 report only url and leave both as None. A viewer routed into VS Code through the bridge also leaves both as None, while .url still carries the token fragment.
Call the API from a handle
Section titled “Call the API from a handle”The viewer’s HTTP routes are an unsupported internal protocol, and every request needs the access token. For a local launch, append the API path to base_url and send the bearer header:
import jsonfrom urllib.request import Request, urlopen
from dcmview_py import view
with view("./study", browser=False, block=False, vscode_bridge=False) as handle: request = Request( handle.base_url + "/api/files", headers={"Authorization": f"Bearer {handle.token}"}, ) with urlopen(request) as response: catalog = json.load(response)Do not build a request from handle.url: an API path appended after its #token=… fragment never reaches the server. Treat handle.url and handle.token as credentials and keep them out of logs and notebook output that you share.
A non-blocking call waits for the viewer’s URL, then up to five more seconds for its scan to finish or for VS Code to take the launch. If the scan finds no files, the call raises subprocess.CalledProcessError instead of returning a handle. If no URL is reported within 30 seconds, the call warns with RuntimeWarning and .url stays None until the viewer reports it.
.stop() asks the viewer to stop and returns its exit code. For a local viewer it sends the platform’s graceful interrupt, then terminate and kill fallbacks if the process does not exit within the timeout; for a VS Code-managed viewer it closes that viewer. Viewers started with block=False are stopped when the Python interpreter exits, so a finished script or restarted notebook kernel does not leave a server running.
Exceptions
Section titled “Exceptions”| Exception | Cause |
|---|---|
ValueError |
No file paths were supplied. |
TypeError |
Invalid file, annotation, or filter argument types, or an unknown keyword. |
RuntimeError |
No usable binary could be resolved. |
subprocess.CalledProcessError |
The viewer returned a non-zero exit status or found no files. |
CalledProcessError carries the viewer’s last output. The wrapper reads startup events only from the binary’s standard output; standard error is still echoed and included in that output.
Binary resolution
Section titled “Binary resolution”The wrapper resolves the executable in this order:
DCMVIEW_BINARY, which may include~but must resolve to an existing file.- The platform binary bundled inside the installed wheel.
dcmviewordcmview.exeonPATH.
The wrapper adds the hidden --startup-json option so it can parse the server URL, origin, and token reliably, which requires a v0.2.0 or newer binary. It no longer retries older binaries without that option.
VS Code routing
Section titled “VS Code routing”Every launch goes through the dcmview binary, so view(), the module command, and terminal commands share one routing rule. With the dcmview extension active, the viewer opens in a VS Code webview when Python runs in a VS Code integrated terminal, or when its working directory is inside an open workspace folder. The second case covers notebooks started from the workspace. Anywhere else the local viewer starts.
vscode_bridge=False sets DCMVIEW_VSCODE_BYPASS=1 for the child process, and setting that variable yourself has the same effect.
The bridge reports a launch URL with its token fragment, so handle.url keeps working for a VS Code-managed viewer. Its session event has no separate token or origin, so handle.token and handle.base_url stay None. A DCMVIEW_TOKEN set only in the launching terminal or notebook is not forwarded through the bridge: the viewer inherits the extension host’s environment and otherwise generates its own token.
Runtime environment variables
Section titled “Runtime environment variables”| Variable | Behavior |
|---|---|
DCMVIEW_TOKEN |
Fix the session’s access token. The binary reads it; non-empty A-Z a-z 0-9 - . _ ~ only. Not forwarded through the VS Code bridge. |
DCMVIEW_BINARY |
Override executable path. |
DCMVIEW_VSCODE_BYPASS=1 |
Disable VS Code routing and launch a local viewer. |
DCMVIEW_VSCODE_BRIDGE_URL |
Explicit extension-managed bridge URL. |
DCMVIEW_VSCODE_BRIDGE_TOKEN |
Bearer token for the explicit bridge. |
DCMVIEW_VSCODE_BRIDGE_REGISTRY_DIR |
Override the bridge registry location. |
DCMVIEW_VSCODE_BRIDGE_DEBUG=1 |
Print bridge discovery diagnostics to stderr. |
XDG_STATE_HOME |
Preferred Unix base for bridge registry state when absolute. |
Bridge entries expire after three hours. On Unix, registry directories must be owned by the current user and must not be group- or world-writable. The pre-0.2.5 locations under XDG_RUNTIME_DIR and /tmp are no longer searched.
Module command
Section titled “Module command”python -m dcmview_py and the dcmview and dcmview-py console scripts forward their arguments unchanged to the resolved binary. Options, --help, and --version are the binary’s own. They follow the same VS Code routing rule, wait for the viewer to exit, and return its exit code; Ctrl+C stops the viewer. Use view() when a script needs a non-blocking handle.
See Launch dcmview from Python for complete examples.