Skip to content

Python client

rtseg_client.py is a single-file client for the automation API. It uses only the Python standard library (Python 3.10 or newer), so it can be copied into other projects; RTpipeline ships the same file.

Command line

export RTSEG_URL=https://rtseg.example.org

python rtseg_client.py health
python rtseg_client.py models --enabled
python rtseg_client.py submit ./patient01 --model total --model lung_nodules \
    --modality CT --out ./results
python rtseg_client.py status JOB_ID
python rtseg_client.py download JOB_ID --out ./results --extract
python rtseg_client.py verify ./results/JOB_ID.zip

submit uploads every file below the given paths through a resumable upload session, waits for the portal's series assessment and creates one job per selected series. Select series with --modality (CT, MR or PT) or --series-uid; series the portal marks unavailable are never selected. With --out, the client waits for each job, downloads its ZIP and verifies it against the packaged manifest. The output is a JSON summary with each job's models, outcomes and ROI counts.

Prompted models take --prompt-json, multi-sequence MRI models take --roles, and the prostate SBRT crop takes --postprocess prostate_sbrt_crop; the formats are the ones described in the API reference.

Authentication and TLS

RTsegmentator has no built-in user authentication. When the portal sits behind an authenticating reverse proxy, pass the required headers with --header "Name: value" or in the RTSEG_CLIENT_HEADERS environment variable (one Name: value per line). Use --ca-bundle for a private certificate authority. Certificate verification cannot be switched off.

Verification

verify and download fail when the ZIP has no rtsegmentator_manifest.json, when a listed file is missing or its size or SHA-256 differs, when the ZIP contains a file the manifest does not list, or when a member name could escape the extraction directory. submit --out and download also compare the packaged manifest with the one the portal serves for the job. The manifest is not signed: these checks detect corruption, incomplete transfers and a package that does not belong to the job, not deliberate tampering by someone who can rewrite both the files and the manifest.

Python use

from pathlib import Path
import rtseg_client as rc

client = rc.RTsegClient("https://rtseg.example.org", headers={"Authorization": "Bearer ..."})
session = client.upload_files(rc.collect_files([Path("patient01")]))
upload = client.assess(session)
series = rc.select_series(upload["series"], modalities=["CT"])
batch = client.submit(upload["upload_id"], [s["key"] for s in series], ["total"])
for job in batch["jobs"]:
    client.wait(job["id"], poll=10)
    package = client.download(job["id"], Path("results") / f"{job['id']}.zip")
    manifest = rc.verify_result_zip(package)
    for model in manifest["models"]:
        print(model["name"], model["outcome"], (model.get("rtstruct") or {}).get("roi_names"))

Transient failures (HTTP 429, 502, 503, 504 and connection errors) are retried with exponential back-off. A failed job raises JobFailed with the portal's error text.