Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ dependencies = [
"requests>=2.18",
"retrying>=1.3.3",
"Pillow>=8.3",
"pydicom>=2.2",
"pydicom>=3.0.0",
"typing-extensions>=4.0; python_version < '3.8.0'",
]

Expand Down
4 changes: 2 additions & 2 deletions src/dicomweb_client/file.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@
from pydicom.datadict import dictionary_VR, keyword_for_tag, tag_for_keyword
from pydicom.dataelem import DataElement
from pydicom.dataset import Dataset, FileMetaDataset
from pydicom.encaps import encapsulate, get_frame_offsets
from pydicom.encaps import encapsulate, parse_basic_offsets
from pydicom.errors import InvalidDicomError
from pydicom.filebase import DicomFileLike
from pydicom.filereader import data_element_offset_to_value, dcmread
Expand Down Expand Up @@ -350,7 +350,7 @@ def _read_bot(fp: DicomFileLike) -> np.ndarray:
fp.is_implicit_VR, 'OB'
)
fp.seek(pixel_data_element_value_offset - 4, 1)
is_empty, offsets = get_frame_offsets(fp)
offsets = parse_basic_offsets(fp)
return np.array(offsets, dtype=np.uint32)


Expand Down
23 changes: 22 additions & 1 deletion src/dicomweb_client/web.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
)

import pydicom
from pydicom.valuerep import INT_VR, FLOAT_VR, VR
import requests
import retrying

Expand Down Expand Up @@ -60,7 +61,7 @@ def _load_xml_dataset(dataset: Element) -> pydicom.dataset.Dataset:
for element in dataset:
keyword = element.attrib['keyword']
vr = element.attrib['vr']
value: Optional[Union[List[Any], str]]
value: Optional[Union[List[Any], str, int, float]]
if vr == 'SQ':
value = [
_load_xml_dataset(item)
Expand All @@ -74,6 +75,26 @@ def _load_xml_dataset(dataset: Element) -> pydicom.dataset.Dataset:
value = [v.text.strip() for v in value]
else:
value = None

# Convert string values to appropriate Python types for
# numeric VRs to satisfy pydicom 3.0+ stricter type validation
if value is not None:
try:
vr_enum = VR(vr)
if vr_enum in INT_VR:
if isinstance(value, list):
value = [int(v) for v in value]
else:
value = int(value)
elif vr_enum in FLOAT_VR:
if isinstance(value, list):
value = [float(v) for v in value]
else:
value = float(value)
except ValueError:
# VR not recognized, leave value as-is
pass

setattr(ds, keyword, value)
return ds

Expand Down
32 changes: 21 additions & 11 deletions tests/test_web.py
Original file line number Diff line number Diff line change
Expand Up @@ -776,10 +776,20 @@ def test_retrieve_instance_singlepart(httpserver, client, cache_dir):
cache_filename = str(cache_dir.joinpath('file.dcm'))
with open(cache_filename, 'rb') as f:
data = f.read()
media_type = 'application/dicom'
boundary = 'boundary'
headers = {
'content-type': 'application/dicom'
'content-type': (
'multipart/related; '
f'type="{media_type}"; '
f'boundary="{boundary}"'
),
}
httpserver.serve_content(content=data, code=200, headers=headers)
message = DICOMwebClient._encode_multipart_message(
content=[data],
content_type=headers['content-type']
)
httpserver.serve_content(content=message, code=200, headers=headers)
study_instance_uid = '1.2.3'
series_instance_uid = '1.2.4'
sop_instance_uid = '1.2.5'
Expand Down Expand Up @@ -1285,8 +1295,8 @@ def test_retrieve_instance_frames_rendered_png(httpserver, client, cache_dir):

def test_store_instance_error_with_retries(httpserver, client, cache_dir):
dataset = pydicom.Dataset.from_json({})
dataset.is_little_endian = True
dataset.is_implicit_VR = True
dataset.file_meta = pydicom.dataset.FileMetaDataset()
dataset.file_meta.TransferSyntaxUID = pydicom.uid.ImplicitVRLittleEndian
max_attempts = 2
client.set_http_retry_params(
retry=True,
Expand All @@ -1311,8 +1321,8 @@ def test_store_instance_error_with_retries_and_additional_params(
httpserver, client, cache_dir
):
dataset = pydicom.Dataset.from_json({})
dataset.is_little_endian = True
dataset.is_implicit_VR = True
dataset.file_meta = pydicom.dataset.FileMetaDataset()
dataset.file_meta.TransferSyntaxUID = pydicom.uid.ImplicitVRLittleEndian
max_attempts = 2
client.set_http_retry_params(
retry=True,
Expand All @@ -1339,8 +1349,8 @@ def test_store_instance_error_with_retries_and_additional_params(

def test_store_instance_error_with_no_retries(httpserver, client, cache_dir):
dataset = pydicom.Dataset.from_json({})
dataset.is_little_endian = True
dataset.is_implicit_VR = True
dataset.file_meta = pydicom.dataset.FileMetaDataset()
dataset.file_meta.TransferSyntaxUID = pydicom.uid.ImplicitVRLittleEndian
client.set_http_retry_params(retry=False)
httpserver.serve_content(
content='',
Expand All @@ -1360,8 +1370,8 @@ def test_store_instance_error_with_no_retries_and_additional_params(
httpserver, client, cache_dir
):
dataset = pydicom.Dataset.from_json({})
dataset.is_little_endian = True
dataset.is_implicit_VR = True
dataset.file_meta = pydicom.dataset.FileMetaDataset()
dataset.file_meta.TransferSyntaxUID = pydicom.uid.ImplicitVRLittleEndian
client.set_http_retry_params(retry=False)
httpserver.serve_content(
content='',
Expand Down Expand Up @@ -1527,7 +1537,7 @@ def test_delete_instance_error_with_additional_params(


def test_load_json_dataset_da(httpserver, client, cache_dir):
value = ['2018-11-21']
value = ['20181121'] # DA format must be YYYYMMDD
dicom_json = {
'00080020': {
'vr': 'DA',
Expand Down
Loading