Skip to content

Commit 5f4a9c4

Browse files
noeroggguuss
authored andcommitted
Add DICOMweb retrieve instance/image and download them to machi… (#2331)
* Add DICOMweb retrieve instance/image and download them to machine
1 parent 767eaa3 commit 5f4a9c4

File tree

2 files changed

+231
-7
lines changed

2 files changed

+231
-7
lines changed

healthcare/api-client/dicom/dicomweb.py

Lines changed: 133 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -131,20 +131,110 @@ def dicomweb_retrieve_study(
131131
dicomweb_path = '{}/datasets/{}/dicomStores/{}/dicomWeb/studies/{}'.format(
132132
url, dataset_id, dicom_store_id, study_uid)
133133

134+
file_name = 'study.dcm'
135+
136+
# Make an authenticated API request
137+
session = get_session(service_account_json)
138+
139+
response = session.get(dicomweb_path)
140+
141+
response.raise_for_status()
142+
143+
with open(file_name, 'wb') as f:
144+
f.write(response.content)
145+
print('Retrieved study and saved to file ' +
146+
'{} in current directory'.format(file_name))
147+
148+
return response
149+
# [END healthcare_dicomweb_retrieve_study]
150+
151+
152+
# [START healthcare_dicomweb_retrieve_instance]
153+
def dicomweb_retrieve_instance(
154+
service_account_json,
155+
base_url,
156+
project_id,
157+
cloud_region,
158+
dataset_id,
159+
dicom_store_id,
160+
study_uid,
161+
series_uid,
162+
instance_uid):
163+
"""Handles the GET requests specified in the DICOMweb standard."""
164+
url = '{}/projects/{}/locations/{}'.format(base_url,
165+
project_id, cloud_region)
166+
167+
dicom_store_path = '{}/datasets/{}/dicomStores/{}'.format(
168+
url, dataset_id, dicom_store_id)
169+
170+
dicomweb_path = '{}/dicomWeb/studies/{}/series/{}/instances/{}'.format(
171+
dicom_store_path, study_uid, series_uid, instance_uid)
172+
173+
file_name = 'instance.dcm'
174+
134175
# Make an authenticated API request
135176
session = get_session(service_account_json)
136177

137178
headers = {
138-
'Content-Type': 'application/dicom+json; charset=utf-8'
179+
'Accept': 'application/dicom; transfer-syntax=*'
139180
}
140181

141182
response = session.get(dicomweb_path, headers=headers)
183+
142184
response.raise_for_status()
143185

144-
print('Retrieved study with UID: {}'.format(study_uid))
186+
with open(file_name, 'wb') as f:
187+
f.write(response.content)
188+
print('Retrieved DICOM instance and saved to file ' +
189+
'{} in current directory'.format(file_name))
145190

146191
return response
147-
# [END healthcare_dicomweb_retrieve_study]
192+
# [END healthcare_dicomweb_retrieve_instance]
193+
194+
195+
# [START healthcare_dicomweb_retrieve_rendered]
196+
def dicomweb_retrieve_rendered(
197+
service_account_json,
198+
base_url,
199+
project_id,
200+
cloud_region,
201+
dataset_id,
202+
dicom_store_id,
203+
study_uid,
204+
series_uid,
205+
instance_uid):
206+
"""Handles the GET requests specified in the DICOMweb standard."""
207+
url = '{}/projects/{}/locations/{}'.format(base_url,
208+
project_id, cloud_region)
209+
210+
dicom_store_path = '{}/datasets/{}/dicomStores/{}'.format(
211+
url, dataset_id, dicom_store_id)
212+
213+
instance_path = '{}/dicomWeb/studies/{}/series/{}/instances/{}'.format(
214+
dicom_store_path, study_uid, series_uid, instance_uid)
215+
216+
dicomweb_path = '{}/rendered'.format(instance_path)
217+
218+
file_name = 'rendered_image.png'
219+
220+
# Make an authenticated API request
221+
session = get_session(service_account_json)
222+
223+
headers = {
224+
'Accept': 'image/png'
225+
}
226+
227+
response = session.get(dicomweb_path, headers=headers)
228+
229+
response.raise_for_status()
230+
231+
with open(file_name, 'wb') as f:
232+
f.write(response.content)
233+
print('Retrieved rendered image and saved to file ' +
234+
'{} in current directory'.format(file_name))
235+
236+
return response
237+
# [END healthcare_dicomweb_retrieve_rendered]
148238

149239

150240
# [START healthcare_dicomweb_delete_study]
@@ -228,6 +318,16 @@ def parse_command_line_args():
228318
default=None,
229319
help='Unique identifier for a study.')
230320

321+
parser.add_argument(
322+
'--series_uid',
323+
default=None,
324+
help='Unique identifier for a series.')
325+
326+
parser.add_argument(
327+
'--instance_uid',
328+
default=None,
329+
help='Unique identifier for an instance.')
330+
231331
command = parser.add_subparsers(dest='command')
232332

233333
command.add_parser(
@@ -239,6 +339,12 @@ def parse_command_line_args():
239339
command.add_parser(
240340
'dicomweb-retrieve-study',
241341
help=dicomweb_retrieve_study.__doc__)
342+
command.add_parser(
343+
'dicomweb-retrieve-instance',
344+
help=dicomweb_retrieve_instance.__doc__)
345+
command.add_parser(
346+
'dicomweb-retrieve-rendered',
347+
help=dicomweb_retrieve_rendered.__doc__)
242348
command.add_parser(
243349
'dicomweb-delete-study',
244350
help=dicomweb_delete_study.__doc__)
@@ -282,6 +388,30 @@ def run_command(args):
282388
args.dicom_store_id,
283389
args.study_uid)
284390

391+
elif args.command == 'dicomweb-retrieve-instance':
392+
dicomweb_retrieve_instance(
393+
args.service_account_json,
394+
args.base_url,
395+
args.project_id,
396+
args.cloud_region,
397+
args.dataset_id,
398+
args.dicom_store_id,
399+
args.study_uid,
400+
args.series_uid,
401+
args.instance_uid)
402+
403+
elif args.command == 'dicomweb-retrieve-rendered':
404+
dicomweb_retrieve_rendered(
405+
args.service_account_json,
406+
args.base_url,
407+
args.project_id,
408+
args.cloud_region,
409+
args.dataset_id,
410+
args.dicom_store_id,
411+
args.study_uid,
412+
args.series_uid,
413+
args.instance_uid)
414+
285415
elif args.command == 'dicomweb-delete-study':
286416
dicomweb_delete_study(
287417
args.service_account_json,

healthcare/api-client/dicom/dicomweb_test.py

Lines changed: 98 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -34,9 +34,13 @@
3434
RESOURCES = os.path.join(os.path.dirname(__file__), 'resources')
3535
dcm_file_name = 'dicom_00000001_000.dcm'
3636
dcm_file = os.path.join(RESOURCES, dcm_file_name)
37-
# The study_uid is not assigned by the server and is part of the
38-
# metadata of dcm_file
37+
# The study_uid, series_uid, and instance_uid are not assigned by the
38+
# server and are part of the metadata of dcm_file
3939
study_uid = '1.3.6.1.4.1.11129.5.5.111396399361969898205364400549799252857604'
40+
series_uid = '1.3.6.1.4.1.11129.5.5.195628213694300498946760767481291263511724'
41+
instance_uid = '{}.{}'.format(
42+
'1.3.6.1.4.1.11129.5.5',
43+
'153751009835107614666834563294684339746480')
4044

4145

4246
@pytest.fixture(scope='module')
@@ -154,10 +158,100 @@ def test_dicomweb_retrieve_study(test_dataset, test_dicom_store, capsys):
154158
dicom_store_id,
155159
study_uid)
156160

161+
# Assert study was downloaded
162+
assert os.path.isfile('study.dcm')
163+
157164
out, _ = capsys.readouterr()
158165

159-
# Check that store instance worked
160-
assert 'Retrieved study with UID:' in out
166+
# Check that retrieve study worked
167+
assert 'Retrieved study' in out
168+
169+
# Delete downloaded study
170+
os.remove('study.dcm')
171+
172+
dicomweb.dicomweb_delete_study(
173+
service_account_json,
174+
base_url,
175+
project_id,
176+
cloud_region,
177+
dataset_id,
178+
dicom_store_id,
179+
study_uid)
180+
181+
182+
def test_dicomweb_retrieve_instance(test_dataset, test_dicom_store, capsys):
183+
dicomweb.dicomweb_store_instance(
184+
service_account_json,
185+
base_url,
186+
project_id,
187+
cloud_region,
188+
dataset_id,
189+
dicom_store_id,
190+
dcm_file)
191+
192+
dicomweb.dicomweb_retrieve_instance(
193+
service_account_json,
194+
base_url,
195+
project_id,
196+
cloud_region,
197+
dataset_id,
198+
dicom_store_id,
199+
study_uid,
200+
series_uid,
201+
instance_uid)
202+
203+
# Assert instance was downloaded
204+
assert os.path.isfile('instance.dcm')
205+
206+
out, _ = capsys.readouterr()
207+
208+
# Check that retrieve instance worked
209+
assert 'Retrieved DICOM instance' in out
210+
211+
# Delete downloaded instance
212+
os.remove('instance.dcm')
213+
214+
dicomweb.dicomweb_delete_study(
215+
service_account_json,
216+
base_url,
217+
project_id,
218+
cloud_region,
219+
dataset_id,
220+
dicom_store_id,
221+
study_uid)
222+
223+
224+
def test_dicomweb_retrieve_rendered(test_dataset, test_dicom_store, capsys):
225+
dicomweb.dicomweb_store_instance(
226+
service_account_json,
227+
base_url,
228+
project_id,
229+
cloud_region,
230+
dataset_id,
231+
dicom_store_id,
232+
dcm_file)
233+
234+
dicomweb.dicomweb_retrieve_rendered(
235+
service_account_json,
236+
base_url,
237+
project_id,
238+
cloud_region,
239+
dataset_id,
240+
dicom_store_id,
241+
study_uid,
242+
series_uid,
243+
instance_uid)
244+
245+
# Assert rendered image was downloaded
246+
assert os.path.isfile('rendered_image.png')
247+
248+
out, _ = capsys.readouterr()
249+
250+
# Check that retrieve rendered image worked
251+
assert 'Retrieved rendered image' in out
252+
253+
# Delete downloaded rendered image
254+
os.remove('rendered_image.png')
161255

162256
dicomweb.dicomweb_delete_study(
163257
service_account_json,

0 commit comments

Comments
 (0)