github.com/apache/beam/sdks/v2@v2.48.2/python/apache_beam/io/gcp/dicomclient.py (about) 1 # 2 # Licensed to the Apache Software Foundation (ASF) under one or more 3 # contributor license agreements. See the NOTICE file distributed with 4 # this work for additional information regarding copyright ownership. 5 # The ASF licenses this file to You under the Apache License, Version 2.0 6 # (the "License"); you may not use this file except in compliance with 7 # the License. You may obtain a copy of the License at 8 # 9 # http://www.apache.org/licenses/LICENSE-2.0 10 # 11 # Unless required by applicable law or agreed to in writing, software 12 # distributed under the License is distributed on an "AS IS" BASIS, 13 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 # See the License for the specific language governing permissions and 15 # limitations under the License. 16 # 17 18 # pytype: skip-file 19 20 from google.auth import default 21 from google.auth.transport import requests 22 23 24 class DicomApiHttpClient: 25 """DICOM api client that talk to api via http request""" 26 healthcare_base_url = "https://healthcare.googleapis.com/v1" 27 session = None 28 29 def get_session(self, credential): 30 if self.session: 31 return self.session 32 33 # if the credential is not provided, use the default credential. 34 if not credential: 35 credential, _ = default() 36 new_seesion = requests.AuthorizedSession(credential) 37 self.session = new_seesion 38 return new_seesion 39 40 def qido_search( 41 self, 42 project_id, 43 region, 44 dataset_id, 45 dicom_store_id, 46 search_type, 47 params=None, 48 credential=None): 49 """function for searching a DICOM store""" 50 51 # sending request to the REST healthcare api. 52 api_endpoint = "{}/projects/{}/locations/{}".format( 53 self.healthcare_base_url, project_id, region) 54 55 # base of dicomweb path. 56 dicomweb_path = "{}/datasets/{}/dicomStores/{}/dicomWeb/{}".format( 57 api_endpoint, dataset_id, dicom_store_id, search_type) 58 59 # Make an authenticated API request 60 session = self.get_session(credential) 61 headers = {"Content-Type": "application/dicom+json; charset=utf-8"} 62 page_size = 500 63 64 if params and 'limit' in params: 65 page_size = params['limit'] 66 elif params: 67 params['limit'] = page_size 68 else: 69 params = {'limit': page_size} 70 71 offset = 0 72 output = [] 73 # iterate to get all the results 74 while True: 75 params['offset'] = offset 76 response = session.get(dicomweb_path, headers=headers, params=params) 77 status = response.status_code 78 if status != 200: 79 if offset == 0: 80 return [], status 81 params['offset'] = offset - 1 82 params['limit'] = 1 83 response = session.get(dicomweb_path, headers=headers, params=params) 84 check_status = response.status_code 85 if check_status == 200: 86 # if the number of results equals to page size 87 return output, check_status 88 else: 89 # something wrong with the request or server 90 return [], status 91 results = response.json() 92 output += results 93 if len(results) < page_size: 94 # got all the results, return 95 break 96 offset += len(results) 97 98 return output, status 99 100 def dicomweb_store_instance( 101 self, 102 project_id, 103 region, 104 dataset_id, 105 dicom_store_id, 106 dcm_file, 107 credential=None): 108 """function for storing an instance.""" 109 110 api_endpoint = "{}/projects/{}/locations/{}".format( 111 self.healthcare_base_url, project_id, region) 112 113 dicomweb_path = "{}/datasets/{}/dicomStores/{}/dicomWeb/studies".format( 114 api_endpoint, dataset_id, dicom_store_id) 115 116 # Make an authenticated API request 117 session = self.get_session(credential) 118 content_type = "application/dicom" 119 headers = {"Content-Type": content_type} 120 121 response = session.post(dicomweb_path, data=dcm_file, headers=headers) 122 123 return None, response.status_code