2.2. API v2
2.2.1. General information
This document contains information on how to use the Delft AI API v2 for either communicating with the cloud, or communicating with a local CAD4TBbox.
2.2.1.1. Prerequisites
2.2.1.1.1. Cloud
For the API calls, the following parameters are required. These parameters will be provided by Delft AI or your distributor.
Base_url: |
Base URL of the Delft AI server |
Token: |
Token used for authentication to use the API |
Project: |
Client project on the Delft AI server |
Archive: |
Client archive on the Delft AI server |
Archive_pk: |
Unique id of the client archive on the Delft AI server. “Project” and “Archive” will be replaced by this in the future. |
2.2.1.1.2. CAD4TBbox (local)
To query a local CAD4TBbox, default parameters can be used as described below. By default, a token is not generated and therefore should be setup by Delft AI/Delft Imaging.
Base_url: |
|
Token: |
(to be enabled and provided by Delft Imaging) |
Project: |
project |
Archive: |
archive |
Archive_pk: |
1 |
2.2.1.2. Data flow
The following section describes the data flow for generating CAD4TB results based on an input frontal chest x-ray dicom.
Get archive_pk via “Archive API”.
Upload Series via “Upload API”.
Each Serie can be uploaded in parallel (e.g. separate threads).
Check status of Series via “Series status API”.
Download Series results via “Series API – Results endpoint”.
2.2.1.2.1. Get archive_pk via “Archive API”
To upload files, the archive_pk is required. This archive_pk is a unique archive on the Delft AI cloud to which only the user with the specified token has access to. This archive_pk has to be queried only once as the archive_pk is fixed for the client. In the future, the archive_pk will be available to the client directly, but for backward compatibility, we are working with ‘project’ and ‘archive’ still. This step thus does not have to be implemented within the software, but can be done manually on account setup.
2.2.1.2.2. Upload Series via “Upload API”
Each Series can be uploaded via the “Upload API”. All Series can be uploaded sequentially or in parallel. Doing the upload in parallel will reduce the overall turnaround time as Series get processed once they are uploaded to the cloud / box.
2.2.1.2.3. Check status of Series via “Series status API”
After a Series has been uploaded, the status of the Series can be requested using the “Series status API”. In the response, the status is available in the “status” field. When the status of a Series is “processing_ok”, it means that the Series has been processed and results are available.
If the status is “New”, “in_processing_queue” or “Processing”, the results are not yet available and it is advised to redo the Series status check in X seconds (e.g. 5 seconds).
2.2.1.2.4. Download Series results via “Series API – Results endpoint”
When the status of a Series is “processing_ok”, the Series results can be requested using the “Series API – results endpoint”.
2.2.1.3. Troubleshooting
2.2.1.3.1. Delete Serie/Study/Patient
A Series/Study/Patient can be deleted from the cloud/box using the ‘Delete API’ commands. The Delete commands should NOT be used in general usage setting (and are also not always available on each account), but the option is available might this be necessary.
2.2.1.4. Appendix A: Archive API
2.2.1.4.1. General endpoint
The generic series endpoint can be used to acquire series for an archive, or to apply filtering such as by PatientID, project, and archive.
Command type: GET url = “<base_url>/api/v2/series/” headers = {“Authorization”: “Token <token>”} payload (optional) = {“project”: “<project>”, “archive”: “<archive>”, “PatientID”: “<PatientID>”}.
Example call:
response = requests.get(url, headers=headers, payload=payload)
Result .. code-block:: python
- {
‘count’: 1, ‘next’: None, ‘previous’: None, ‘results’: [{‘id’: <results_pk>, ‘url’: ‘<base_url>/api/v2/series/<series_pk>/’, ‘SeriesInstanceUID’: ‘1.2.826.0.1.3680043.2.876.8236.1.3.0.20161213 115738.1.210’, ‘study’: ‘<base_url>/api/v2/studies/<study_pk>/’, ‘patient’: ‘<base_url>/api/v2/patients/<patient_pk>/’}]
}
2.2.1.4.2. Individual series information endpoint
Command type: GET url = “<base_url>/api/v2/series/<series_pk>/” headers = {“Authorization”: “Token <token>”}
Example call:
response = requests.get(url, headers=headers)
Result .. code-block:: python
response.content {
“id”: 651214, “status”: “processing_ok”, “status_message”: “Processing OK”, “extra_information”: {}, “SeriesInstanceUID”: “<SeriesInstanceUID>”, “ImageType”: null, “SOPClassUID”: “<SOPClassUID>”, “SeriesDate”: null, “SeriesTime”: null, “Modality”: “DX”, “Manufacturer”: “Anonymized”, “ManufacturerModelName”: “Anonymized”, “SeriesDescription”: null, “BodyPartExamined”: null, “SliceThickness”: null, “KVP”: null, “SpacingBetweenSlices”: null, “PatientPosition”: null, “SeriesNumber”: 2, “PatientOrientation”: null, “NumberOfFrames”: null, “ImagePositionPatient”: null, “ImageOrientationPatient”: null, “ImageComments”: null, “PhotometricInterpretation”: “MONOCHROME1”, “Rows”: 2160, “Columns”: 2688, “StationName”: null, “TransferSyntaxUID”: null, “Laterality”: null, “patient”: “<base_url>/api/v2/patients/<patient_pk>/”, “study”: “<base_url>/api/v2/studies/<study_pk>/”, “url”: “<base_url>/api/v2/series/<series_pk>/”, “instances”: [“<base_url>/api/v2/instances/<instance>/”]
}
Possible “status”:
New: This is the status right after uploading
in_processing_queue: The image is in the processing queue for processing.
Processing: The image is being processed.
processing_ok: The image is processed and results are ready
processing_failed: Processing of the image failed. Either retry uploading the case (first delete the image using the Delete API call and then reupload the image using the Upload API call). You are advised to contact Delft Imaging support when this happens.
processing_disallowed: The client has run out of runs. Either generate a new license via the license server or contact Delft Imaging support.
2.2.1.4.3. Result endpoint
Based on the series_pk, we can obtain results via the results endpoint on the series endpoint. Command type: GET url = “<base_url>/api/v2/series/<series_pk>/results headers = {“Authorization”: “Token <token>”}
Example call:
response = requests.get(url, headers=headers)
Result .. code-block:: python
json.loads(response.content) [ {‘id’: <results_pk_1>,
‘url’: ‘<base_url>/api/v2/results/<results_pk_1>/’, ‘value’: ‘<base_url>/api/v2/results/<results_pk_1>/download/’, ‘name’: ‘Texture Overlay’, ‘algorithm’: {‘name’: ‘CAD4TB’, ‘version’: ‘7.0.0’}
}, {
‘id’: <results_pk_2>, ‘url’: ‘<base_url>/api/v2/results/<results_pk_2>/’, ‘value’: ‘<base_url>/api/v2/results/<results_pk_2>/download/’, ‘name’: ‘Original’, ‘algorithm’: {‘name’: ‘CAD4TB’, ‘version’: ‘7.0.0’}
}, {
‘id’: <results_pk_3>, ‘url’: ‘<base_url>/api/v2/results/<results_pk_3>/’, ‘value’: {
‘cxrNonCxrScore’: 1.0, ‘is_pa_cxr’: ‘Yes’, ‘lungHeight’: 1879, ‘lungHeightFraction’: 0.8703, ‘lungWidth’: 1719, ‘lungWidthFraction’: 0.64, ‘narrowScore’: 0.9993, ‘rotation’: 0
},
‘name’: ‘quality_check’, ‘algorithm’: {‘name’: ‘CAD4TB’, ‘version’: ‘7.0.0’}
}, {
‘id’: <results_pk_4>, ‘url’: ‘<base_url>/api/v2/results/<results_pk_4>/’, ‘value’: ‘<base_url>/api/v2/results/<results_pk_4>/download/’, ‘name’: ‘algorithm_manifest’, ‘algorithm’: {‘name’: ‘CAD4TB’, ‘version’: ‘7.0.0’}
}, {
‘id’: <results_pk_5>, ‘url’: ‘<base_url>/api/v2/results/<results_pk_5>/’, ‘value’: 1.301, ‘name’: ‘CAD4TB 7’, ‘algorithm’: {‘name’: ‘CAD4TB’, ‘version’: ‘7.0.0’}
}]
Output types
There are five result types per SeriesInstanceUID: Texture Overlay, Original, quality_check, algorithm_manifest, and CAD4TB 7. Texture Overlay: png (or dicom) file containing the normalized image + heatmap overlay of the score. Original: dicom file containing the originally uploaded image. quality_check: outputs of the quality checker algorithm_manifest: JSON file containing CAD4TB score, quality checker score, warnings, and errors. CAD4TB 7: object containing the CAD4TB v7 score
2.2.1.5. Appendix D: Delete API
Command type: DELETE url = “<base_url>/api/v2/<level>/<level_pk>” In here: <level> is either “patient”, “study” or “series” headers = {“Authorization”: “Token <token>”}
- Example call:
response = requests.delete(url, headers=headers)
- Result
Response.content “”
Response.status_code 204