A minimal Python client for the REST API of The Cancer Imaging Archive (TCIA): query collection/series/patient metadata as JSON, and download image series as zip archives.
With uv:
uv syncOr with pip:
pip install .The client's only runtime dependency is requests.
from tcia_client import TCIAClient
base_url = 'https://nbia.cancerimagingarchive.net/nbia-api/services/v4/'
client = TCIAClient(base_url)get_json calls a TCIA API endpoint and returns the parsed JSON response. Any endpoint-specific parameters are passed as a dict.
collections = client.get_json('getCollectionValues') # lists all available collections
# [{'Collection': '4D-Lung'}, ..., {'Collection': 'LIDC-IDRI'}, ...]
series = client.get_json('getSeries', {'Collection': 'Lung-PET-CT-Dx'}) # returns all series information of a collection
# [{'SeriesInstanceUID': '1.3.6.1...', 'Modality': 'CT', ...}, ...]
patients = client.get_json('getPatientStudy', {'Collection': 'Lung-PET-CT-Dx'}) # returns all patient information of a collection
# [{'PatientID': 'Lung_Dx-A0001', 'PatientSex': 'M', ...}, ...]The results are plain lists of dicts, so they drop straight into a pandas.DataFrame if you want to work with them as tables:
import pandas as pd
series_df = pd.DataFrame(client.get_json('getSeries', {'Collection': 'Lung-PET-CT-Dx'}))See here for the full list of available endpoints and their parameters.
get_image downloads a series by its SeriesInstanceUID, optionally unzipping the result and/or removing the archive afterwards.
series_uid = series_df.iloc[0]['SeriesInstanceUID']
client.get_image(
series_instance_uid=series_uid,
local_path='downloads/series.zip',
unzip=True,
remove_zip=True,
)- API responses are consumed as-is, the client does no schema validation, so unexpected fields from the API pass straight through.
get_imagecreates the parent directory oflocal_pathfor you. It does not currently overwrite an existing directory (see tests/test_tcia_client.py for the documented behavior).