Skip to content

Commit 9443400

Browse files
committed
metadata
1 parent 8ba9f10 commit 9443400

File tree

9 files changed

+60
-10
lines changed

9 files changed

+60
-10
lines changed

orthanc_api_client/instance.py

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ def __init__(self, json_instance: object):
1010
self.dicom_id = self.main_dicom_tags.get('SOPInstanceUID')
1111
self.series_orthanc_id = json_instance.get('ParentSeries')
1212
self.labels = json_instance.get('Labels') or []
13+
self.metadata = json_instance.get('Metadata') or None
1314

1415

1516
class Instance:
@@ -56,4 +57,9 @@ def tags(self): # lazy loading of tags ....
5657

5758
@property
5859
def labels(self):
59-
return self.info.labels
60+
return self.info.labels
61+
62+
def get_metadata(self, metadata_name: str) -> str:
63+
if self.info.metadata is None:
64+
self.info.metadata = self._api_client.instances.get_metadata(self.orthanc_id)
65+
return self.info.metadata.get(metadata_name)

orthanc_api_client/resources/instances.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,8 @@ def get_tags(self, orthanc_id: str) -> Tags:
3131
json_tags = self._api_client.get_json(f"{self._url_segment}/{orthanc_id}/tags")
3232
return Tags(json_tags)
3333

34+
def get_metadata(self, orthanc_id: str) -> dict:
35+
return self._api_client.get_json(f"{self._url_segment}/{orthanc_id}/metadata?expand")
3436

3537
def modify(self, orthanc_id: str, replace_tags: Any = {}, remove_tags: List[str] = [], keep_tags: List[str] = [], force: bool = False) -> bytes:
3638

orthanc_api_client/resources/resources.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -141,7 +141,7 @@ def set_string_metadata(self, orthanc_id: str, metadata_name: str, content: Opti
141141

142142
def get_binary_metadata(self, orthanc_id: str, metadata_name: str, default_value: Optional[str] = None) -> bytes:
143143

144-
content, revision = self.get_metadata_with_revision(
144+
content, revision = self.get_binary_metadata_with_revision(
145145
orthanc_id=orthanc_id,
146146
metadata_name=metadata_name,
147147
default_value=default_value
@@ -184,7 +184,7 @@ def get_string_metadata_with_revision(self, orthanc_id: str, metadata_name: str,
184184
return content.decode('utf-8') if content is not None else None, revision
185185

186186
def has_metadata(self, orthanc_id: str, metadata_name: str) -> bool:
187-
return self.get_metadata(orthanc_id=orthanc_id, metadata_name=metadata_name, default_value=None) is not None
187+
return self.get_binary_metadata(orthanc_id=orthanc_id, metadata_name=metadata_name, default_value=None) is not None
188188

189189
def _anonymize(self, orthanc_id: str, replace_tags={}, keep_tags=[], delete_original=True, force=False) -> str:
190190
"""

orthanc_api_client/resources/studies.py

Lines changed: 21 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,8 @@
44
from .resources import Resources
55
from ..tags import Tags
66
from ..exceptions import *
7-
from ..study import StudyInfo, Study
7+
from ..study import Study
8+
from ..instance import Instance
89
from ..helpers import to_dicom_date, to_dicom_time
910
from ..downloaded_instance import DownloadedInstance
1011
from ..labels_constraint import LabelsConstraint
@@ -25,6 +26,23 @@ def get_instances_ids(self, orthanc_id: str) -> List[str]:
2526

2627
return instances_ids
2728

29+
def get_instances(self, orthanc_id: str) -> List[Instance]:
30+
instances = []
31+
32+
instances_info = self._api_client.post(
33+
f"tools/find",
34+
json={
35+
"Level": "Instance",
36+
"Query": {},
37+
"ResponseContent": ["MainDicomTags", "Metadata", "Parent", "Labels"],
38+
"ParentStudy": orthanc_id
39+
}).json()
40+
41+
for instance_info in instances_info:
42+
instances.append(Instance.from_json(self._api_client, instance_info))
43+
44+
return instances
45+
2846
def get_series_ids(self, orthanc_id: str) -> List[str]:
2947
study_info = self._api_client.get_json(f"{self._url_segment}/{orthanc_id}")
3048
return study_info["Series"]
@@ -58,11 +76,11 @@ def lookup(self, dicom_id: str) -> str:
5876
def find(self,
5977
query: object,
6078
case_sensitive: bool = True,
61-
labels: [str] = [],
79+
labels: List[str] = [],
6280
labels_constraint: LabelsConstraint = LabelsConstraint.ANY,
6381
limit: int = 0,
6482
since: int = 0,
65-
order_by: [dict] = []
83+
order_by: List[dict] = []
6684
) -> List[Study]:
6785
"""
6886
find a study in Orthanc based on the query and the labels

release-notes.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,11 @@
1+
v 0.19.0
2+
========
3+
4+
- Added `Instance.get_metadata()`
5+
- Added `Study.get_instances()` that also retrieves the metadata in a single API call
6+
- fix `Instances.has_metadata`
7+
8+
19
v 0.18.8
210
========
311

setup.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@
2828
# For a discussion on single-sourcing the version across setup.py and the
2929
# project code, see
3030
# https://packaging.python.org/guides/single-sourcing-package-version/
31-
version='0.18.8', # Required
31+
version='0.19.0', # Required
3232

3333
# This is a one-line description or tagline of what your project does. This
3434
# corresponds to the "Summary" metadata field:

tests/docker-setup/docker-compose.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
version: "3"
22
services:
33
orthanc-a:
4-
image: orthancteam/orthanc-pre-release:2025.01.20
4+
image: orthancteam/orthanc:25.8.2
55
ports: ["10042:8042"]
66
environment:
77
VERBOSE_STARTUP: "true"
@@ -58,7 +58,7 @@ services:
5858
ORTHANC__HTTP_THREADS_COUNT: "10"
5959

6060
orthanc-c:
61-
image: orthancteam/orthanc:24.2.3
61+
image: orthancteam/orthanc:25.8.2
6262
ports: ["10044:8042"]
6363
environment:
6464
VERBOSE_STARTUP: "true"

tests/docker-setup/orthanc-b/Dockerfile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
FROM orthancteam/orthanc:24.10.1
1+
FROM orthancteam/orthanc:25.8.2
22

33
RUN pip install --break-system-packages pydicom==3.0.1
44

tests/test_api_client.py

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -167,6 +167,16 @@ def test_study(self):
167167
self.assertTrue(os.path.exists(file.name))
168168
self.assertTrue(os.path.getsize(file.name) > 0)
169169

170+
def test_study_instances(self):
171+
self.oa.delete_all_content()
172+
173+
instances_ids = self.oa.upload_folder(here / "stimuli/MR/Brain")
174+
study_id = self.oa.instances.get_parent_study_id(instances_ids[0])
175+
176+
instances = self.oa.studies.get_instances(study_id)
177+
self.assertEqual(3, len(instances))
178+
self.assertEqual('1.2.840.10008.5.1.4.1.1.4', instances[0].get_metadata('SopClassUid'))
179+
170180

171181

172182
def test_series(self):
@@ -642,6 +652,9 @@ def test_metadata_with_revision(self):
642652
default_value=None
643653
)
644654
self.assertEqual(None, value)
655+
self.assertFalse(self.oa.instances.has_metadata(instances_ids[0], '1024'))
656+
instance = self.oa.instances.get(instances_ids[0])
657+
self.assertIsNone(instance.get_metadata('1024'))
645658

646659
content = b'123456789'
647660
revision = self.oa.instances.set_binary_metadata(
@@ -657,6 +670,9 @@ def test_metadata_with_revision(self):
657670
)
658671

659672
self.assertEqual(content, content_readback.encode('utf-8'))
673+
self.assertTrue(self.oa.instances.has_metadata(instances_ids[0], '1025'))
674+
instance = self.oa.instances.get(instances_ids[0])
675+
self.assertIsNotNone(instance.get_metadata('1025'))
660676

661677
# update if match current revision
662678
self.oa.instances.set_string_metadata(

0 commit comments

Comments
 (0)