healthcare/api-client/v1/dicom/dicomweb.py (282 lines of code) (raw):

# Copyright 2018 Google LLC # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. import argparse import json import os # [START healthcare_dicomweb_store_instance] def dicomweb_store_instance(project_id, location, dataset_id, dicom_store_id, dcm_file): """Handles the POST requests specified in the DICOMweb standard. See https://github.com/GoogleCloudPlatform/python-docs-samples/tree/main/healthcare/api-client/v1/dicom before running the sample.""" # Imports the google.auth.transport.requests transport from google.auth.transport import requests # Imports a module to allow authentication using Application Default Credentials (ADC) import google.auth # Gets credentials from the environment. google.auth.default() returns credentials and the # associated project ID, but in this sample, the project ID is passed in manually. credentials, _ = google.auth.default() scoped_credentials = credentials.with_scopes( ["https://www.googleapis.com/auth/cloud-platform"] ) # Creates a requests Session object with the credentials. session = requests.AuthorizedSession(scoped_credentials) # URL to the Cloud Healthcare API endpoint and version base_url = "https://healthcare.googleapis.com/v1" # TODO(developer): Uncomment these lines and replace with your values. # project_id = 'my-project' # replace with your GCP project ID # location = 'us-central1' # replace with the parent dataset's location # dataset_id = 'my-dataset' # replace with the parent dataset's ID # dicom_store_id = 'my-dicom-store' # replace with the DICOM store ID # dcm_file = 'dicom000_0001.dcm' # replace with a DICOM file url = f"{base_url}/projects/{project_id}/locations/{location}" dicomweb_path = "{}/datasets/{}/dicomStores/{}/dicomWeb/studies".format( url, dataset_id, dicom_store_id ) with open(dcm_file, "rb") as dcm: dcm_content = dcm.read() # Sets required "application/dicom" header on the request headers = {"Content-Type": "application/dicom"} response = session.post(dicomweb_path, data=dcm_content, headers=headers) response.raise_for_status() print("Stored DICOM instance:") print(response.text) return response # [END healthcare_dicomweb_store_instance] # [START healthcare_dicomweb_search_instances] def dicomweb_search_instance(project_id, location, dataset_id, dicom_store_id): """Handles the GET requests specified in DICOMweb standard. See https://github.com/GoogleCloudPlatform/python-docs-samples/tree/main/healthcare/api-client/v1/dicom before running the sample.""" # Imports the google.auth.transport.requests transport from google.auth.transport import requests # Imports a module to allow authentication using Application Default Credentials (ADC) import google.auth # Gets credentials from the environment. google.auth.default() returns credentials and the # associated project ID, but in this sample, the project ID is passed in manually. credentials, _ = google.auth.default() scoped_credentials = credentials.with_scopes( ["https://www.googleapis.com/auth/cloud-platform"] ) # Creates a requests Session object with the credentials. session = requests.AuthorizedSession(scoped_credentials) # URL to the Cloud Healthcare API endpoint and version base_url = "https://healthcare.googleapis.com/v1" # TODO(developer): Uncomment these lines and replace with your values. # project_id = 'my-project' # replace with your GCP project ID # location = 'us-central1' # replace with the parent dataset's location # dataset_id = 'my-dataset' # replace with the parent dataset's ID # dicom_store_id = 'my-dicom-store' # replace with the DICOM store ID url = f"{base_url}/projects/{project_id}/locations/{location}" dicomweb_path = "{}/datasets/{}/dicomStores/{}/dicomWeb/instances".format( url, dataset_id, dicom_store_id ) # Sets required application/dicom+json; charset=utf-8 header on the request headers = {"Content-Type": "application/dicom+json; charset=utf-8"} response = session.get(dicomweb_path, headers=headers) response.raise_for_status() instances = response.json() print("Instances:") print(json.dumps(instances, indent=2)) return instances # [END healthcare_dicomweb_search_instances] # [START healthcare_dicomweb_retrieve_study] def dicomweb_retrieve_study( project_id, location, dataset_id, dicom_store_id, study_uid ): """Handles the GET requests specified in the DICOMweb standard. See https://github.com/GoogleCloudPlatform/python-docs-samples/tree/main/healthcare/api-client/v1/dicom before running the sample.""" # Imports the google.auth.transport.requests transport from google.auth.transport import requests # Imports a module to allow authentication using Application Default Credentials (ADC) import google.auth # Gets credentials from the environment. google.auth.default() returns credentials and the # associated project ID, but in this sample, the project ID is passed in manually. credentials, _ = google.auth.default() scoped_credentials = credentials.with_scopes( ["https://www.googleapis.com/auth/cloud-platform"] ) # Creates a requests Session object with the credentials. session = requests.AuthorizedSession(scoped_credentials) # URL to the Cloud Healthcare API endpoint and version base_url = "https://healthcare.googleapis.com/v1" # TODO(developer): Uncomment these lines and replace with your values. # project_id = 'my-project' # replace with your GCP project ID # location = 'us-central1' # replace with the parent dataset's location # dataset_id = 'my-dataset' # replace with the parent dataset's ID # dicom_store_id = 'my-dicom-store' # replace with the DICOM store ID # study_uid = '1.3.6.1.4.1.5062.55.1.227' # replace with the study UID url = f"{base_url}/projects/{project_id}/locations/{location}" dicomweb_path = "{}/datasets/{}/dicomStores/{}/dicomWeb/studies/{}".format( url, dataset_id, dicom_store_id, study_uid ) # When specifying the output file, use an extension like ".multipart." # Then, parse the downloaded multipart file to get each individual # DICOM file. file_name = "study.multipart" response = session.get(dicomweb_path) response.raise_for_status() with open(file_name, "wb") as f: f.write(response.content) print(f"Retrieved study and saved to {file_name} in current directory") return response # [END healthcare_dicomweb_retrieve_study] # [START healthcare_dicomweb_search_studies] def dicomweb_search_studies(project_id, location, dataset_id, dicom_store_id): """Handles the GET requests specified in the DICOMweb standard. See https://github.com/GoogleCloudPlatform/python-docs-samples/tree/main/healthcare/api-client/v1/dicom before running the sample.""" # Imports the google.auth.transport.requests transport from google.auth.transport import requests # Imports a module to allow authentication using Application Default Credentials (ADC) import google.auth # Gets credentials from the environment. google.auth.default() returns credentials and the # associated project ID, but in this sample, the project ID is passed in manually. credentials, _ = google.auth.default() scoped_credentials = credentials.with_scopes( ["https://www.googleapis.com/auth/cloud-platform"] ) # Creates a requests Session object with the credentials. session = requests.AuthorizedSession(scoped_credentials) # URL to the Cloud Healthcare API endpoint and version base_url = "https://healthcare.googleapis.com/v1" # TODO(developer): Uncomment these lines and replace with your values. # project_id = 'my-project' # replace with your GCP project ID # location = 'us-central1' # replace with the parent dataset's location # dataset_id = 'my-dataset' # replace with the parent dataset's ID # dicom_store_id = 'my-dicom-store' # replace with the DICOM store ID url = f"{base_url}/projects/{project_id}/locations/{location}" dicomweb_path = "{}/datasets/{}/dicomStores/{}/dicomWeb/studies".format( url, dataset_id, dicom_store_id ) # Refine your search by appending DICOM tags to the # request in the form of query parameters. This sample # searches for studies containing a patient's name. params = {"PatientName": "Sally Zhang"} response = session.get(dicomweb_path, params=params) response.raise_for_status() print(f"Studies found: response is {response}") # Uncomment the following lines to process the response as JSON. # patients = response.json() # print('Patients found matching query:') # print(json.dumps(patients, indent=2)) # return patients # [END healthcare_dicomweb_search_studies] # [START healthcare_dicomweb_retrieve_instance] def dicomweb_retrieve_instance( project_id, location, dataset_id, dicom_store_id, study_uid, series_uid, instance_uid, ): """Handles the GET requests specified in the DICOMweb standard. See https://github.com/GoogleCloudPlatform/python-docs-samples/tree/main/healthcare/api-client/v1/dicom before running the sample.""" # Imports the google.auth.transport.requests transport from google.auth.transport import requests # Imports a module to allow authentication using Application Default Credentials (ADC) import google.auth # Gets credentials from the environment. google.auth.default() returns credentials and the # associated project ID, but in this sample, the project ID is passed in manually. credentials, _ = google.auth.default() scoped_credentials = credentials.with_scopes( ["https://www.googleapis.com/auth/cloud-platform"] ) # Creates a requests Session object with the credentials. session = requests.AuthorizedSession(scoped_credentials) # URL to the Cloud Healthcare API endpoint and version base_url = "https://healthcare.googleapis.com/v1" # TODO(developer): Uncomment these lines and replace with your values. # project_id = 'my-project' # replace with your GCP project ID # location = 'us-central1' # replace with the parent dataset's location # dataset_id = 'my-dataset' # replace with the parent dataset's ID # dicom_store_id = 'my-dicom-store' # replace with the DICOM store ID # study_uid = '1.3.6.1.4.1.5062.55.1.2270943358.716200484.1363785608958.61.0' # replace with the study UID # series_uid = '2.24.52329571877967561426579904912379710633' # replace with the series UID # instance_uid = '1.3.6.2.4.2.14619.5.2.1.6280.6001.129311971280445372188125744148' # replace with the instance UID url = f"{base_url}/projects/{project_id}/locations/{location}" dicom_store_path = "{}/datasets/{}/dicomStores/{}".format( url, dataset_id, dicom_store_id ) dicomweb_path = "{}/dicomWeb/studies/{}/series/{}/instances/{}".format( dicom_store_path, study_uid, series_uid, instance_uid ) file_name = "instance.dcm" # Set the required Accept header on the request headers = {"Accept": "application/dicom; transfer-syntax=*"} response = session.get(dicomweb_path, headers=headers) response.raise_for_status() with open(file_name, "wb") as f: f.write(response.content) print( "Retrieved DICOM instance and saved to {} in current directory".format( file_name ) ) return response # [END healthcare_dicomweb_retrieve_instance] # [START healthcare_dicomweb_retrieve_rendered] def dicomweb_retrieve_rendered( project_id, location, dataset_id, dicom_store_id, study_uid, series_uid, instance_uid, ): """Handles the GET requests specified in the DICOMweb standard. See https://github.com/GoogleCloudPlatform/python-docs-samples/tree/main/healthcare/api-client/v1/dicom before running the sample.""" # Imports the google.auth.transport.requests transport from google.auth.transport import requests # Imports a module to allow authentication using Application Default Credentials (ADC) import google.auth # Gets credentials from the environment. google.auth.default() returns credentials and the # associated project ID, but in this sample, the project ID is passed in manually. credentials, _ = google.auth.default() scoped_credentials = credentials.with_scopes( ["https://www.googleapis.com/auth/cloud-platform"] ) # Creates a requests Session object with the credentials. session = requests.AuthorizedSession(scoped_credentials) # URL to the Cloud Healthcare API endpoint and version base_url = "https://healthcare.googleapis.com/v1" # TODO(developer): Uncomment these lines and replace with your values. # project_id = 'my-project' # replace with your GCP project ID # location = 'us-central1' # replace with the parent dataset's location # dataset_id = 'my-dataset' # replace with the parent dataset's ID # dicom_store_id = 'my-dicom-store' # replace with the DICOM store ID # study_uid = '1.3.6.1.4.1.5062.55.1.2270943358.716200484.1363785608958.61.0' # replace with the study UID # series_uid = '2.24.52329571877967561426579904912379710633' # replace with the series UID # instance_uid = '1.3.6.2.4.2.14619.5.2.1.6280.6001.129311971280445372188125744148' # replace with the instance UID url = f"{base_url}/projects/{project_id}/locations/{location}" dicom_store_path = "{}/datasets/{}/dicomStores/{}".format( url, dataset_id, dicom_store_id ) dicomweb_path = "{}/dicomWeb/studies/{}/series/{}/instances/{}/rendered".format( dicom_store_path, study_uid, series_uid, instance_uid ) file_name = "rendered_image.png" # Sets the required Accept header on the request for a PNG image headers = {"Accept": "image/png"} response = session.get(dicomweb_path, headers=headers) response.raise_for_status() with open(file_name, "wb") as f: f.write(response.content) print( "Retrieved rendered image and saved to {} in current directory".format( file_name ) ) return response # [END healthcare_dicomweb_retrieve_rendered] # [START healthcare_dicomweb_delete_study] def dicomweb_delete_study(project_id, location, dataset_id, dicom_store_id, study_uid): """Handles DELETE requests equivalent to the GET requests specified in the WADO-RS standard. See https://github.com/GoogleCloudPlatform/python-docs-samples/tree/main/healthcare/api-client/v1/dicom before running the sample.""" # Imports the google.auth.transport.requests transport from google.auth.transport import requests # Imports a module to allow authentication using Application Default Credentials (ADC) import google.auth # Gets credentials from the environment. google.auth.default() returns credentials and the # associated project ID, but in this sample, the project ID is passed in manually. credentials, _ = google.auth.default() scoped_credentials = credentials.with_scopes( ["https://www.googleapis.com/auth/cloud-platform"] ) # Creates a requests Session object with the credentials. session = requests.AuthorizedSession(scoped_credentials) # URL to the Cloud Healthcare API endpoint and version base_url = "https://healthcare.googleapis.com/v1" # TODO(developer): Uncomment these lines and replace with your values. # project_id = 'my-project' # replace with your GCP project ID # location = 'us-central1' # replace with the parent dataset's location # dataset_id = 'my-dataset' # replace with the parent dataset's ID # dicom_store_id = 'my-dicom-store' # replace with the DICOM store ID # study_uid = '1.3.6.1.4.1.5062.55.1.2270943358.716200484.1363785608958.61.0' # replace with the study UID url = f"{base_url}/projects/{project_id}/locations/{location}" dicomweb_path = "{}/datasets/{}/dicomStores/{}/dicomWeb/studies/{}".format( url, dataset_id, dicom_store_id, study_uid ) # Sets the required application/dicom+json; charset=utf-8 header on the request headers = {"Content-Type": "application/dicom+json; charset=utf-8"} response = session.delete(dicomweb_path, headers=headers) response.raise_for_status() print("Deleted study.") return response # [END healthcare_dicomweb_delete_study] def parse_command_line_args(): """Parses command line arguments.""" parser = argparse.ArgumentParser( description=__doc__, formatter_class=argparse.RawDescriptionHelpFormatter ) parser.add_argument( "--project_id", default=(os.environ.get("GOOGLE_CLOUD_PROJECT")), help="GCP project name", ) parser.add_argument("--location", default="us-central1", help="GCP location") parser.add_argument("--dataset_id", default=None, help="Name of dataset") parser.add_argument("--dicom_store_id", default=None, help="Name of DICOM store") parser.add_argument( "--dcm_file", default=None, help="File name for DCM file to store." ) parser.add_argument( "--study_uid", default=None, help="Unique identifier for a study." ) parser.add_argument( "--series_uid", default=None, help="Unique identifier for a series." ) parser.add_argument( "--instance_uid", default=None, help="Unique identifier for an instance." ) command = parser.add_subparsers(dest="command") command.add_parser("dicomweb-store-instance", help=dicomweb_store_instance.__doc__) command.add_parser( "dicomweb-search-instance", help=dicomweb_search_instance.__doc__ ) command.add_parser("dicomweb-retrieve-study", help=dicomweb_retrieve_study.__doc__) command.add_parser("dicomweb-search-studies", help=dicomweb_search_studies.__doc__) command.add_parser( "dicomweb-retrieve-instance", help=dicomweb_retrieve_instance.__doc__ ) command.add_parser( "dicomweb-retrieve-rendered", help=dicomweb_retrieve_rendered.__doc__ ) command.add_parser("dicomweb-delete-study", help=dicomweb_delete_study.__doc__) return parser.parse_args() def run_command(args): """Calls the program using the specified command.""" if args.project_id is None: print( "You must specify a project ID or set the " '"GOOGLE_CLOUD_PROJECT" environment variable.' ) return elif args.command == "dicomweb-store-instance": dicomweb_store_instance( args.project_id, args.location, args.dataset_id, args.dicom_store_id, args.dcm_file, ) elif args.command == "dicomweb-search-instance": dicomweb_search_instance( args.project_id, args.location, args.dataset_id, args.dicom_store_id, ) elif args.command == "dicomweb-retrieve-study": dicomweb_retrieve_study( args.project_id, args.location, args.dataset_id, args.dicom_store_id, args.study_uid, ) elif args.command == "dicomweb-retrieve-instance": dicomweb_retrieve_instance( args.project_id, args.location, args.dataset_id, args.dicom_store_id, args.study_uid, args.series_uid, args.instance_uid, ) elif args.command == "dicomweb-search-studies": dicomweb_search_studies( args.project_id, args.location, args.dataset_id, args.dicom_store_id, ) elif args.command == "dicomweb-retrieve-rendered": dicomweb_retrieve_rendered( args.project_id, args.location, args.dataset_id, args.dicom_store_id, args.study_uid, args.series_uid, args.instance_uid, ) elif args.command == "dicomweb-delete-study": dicomweb_delete_study( args.project_id, args.location, args.dataset_id, args.dicom_store_id, args.study_uid, ) def main(): args = parse_command_line_args() run_command(args) if __name__ == "__main__": main()