From cc7a6e73beed5935eb627a8d8d23b142772311eb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Yannick=20Lemar=C3=A9chal?= <10884038+ylemarechal@users.noreply.github.com> Date: Thu, 31 Jul 2025 15:46:00 +0200 Subject: [PATCH 1/6] =?UTF-8?q?=E2=9C=A8=20add=20local=20cache=20option=20?= =?UTF-8?q?for=20find=5Fxxx()?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- pyorthanc/_find.py | 128 +++++++++++++++++++++++++++++++-------------- 1 file changed, 90 insertions(+), 38 deletions(-) diff --git a/pyorthanc/_find.py b/pyorthanc/_find.py index 38f5707..72e8536 100644 --- a/pyorthanc/_find.py +++ b/pyorthanc/_find.py @@ -1,3 +1,5 @@ +import logging +import shelve from typing import Dict, List, Union from . import util @@ -15,6 +17,8 @@ def find_patients(client: Orthanc, query: Dict[str, str] = None, labels: Union[List[str], str] = None, labels_constraint: str = 'All', + local_cache=False, + local_cache_file='pyorthanc_cache', **kwargs) -> List[Patient]: """Finds patients in Orthanc according to queries and labels @@ -55,6 +59,8 @@ def find_patients(client: Orthanc, query=query, labels=labels, labels_constraint=labels_constraint, + local_cache=local_cache, + local_cache_file=local_cache_file, **kwargs ) @@ -63,6 +69,8 @@ def find_studies(client: Orthanc, query: Dict[str, str] = None, labels: Union[List[str], str] = None, labels_constraint: str = 'All', + local_cache=False, + local_cache_file='pyorthanc_cache', **kwargs) -> List[Study]: """Finds studies in Orthanc according to queries and labels @@ -104,6 +112,8 @@ def find_studies(client: Orthanc, query=query, labels=labels, labels_constraint=labels_constraint, + local_cache=local_cache, + local_cache_file=local_cache_file, **kwargs ) @@ -112,6 +122,8 @@ def find_series(client: Orthanc, query: Dict[str, str] = None, labels: Union[List[str], str] = None, labels_constraint: str = 'All', + local_cache=False, + local_cache_file='pyorthanc_cache', **kwargs) -> List[Series]: """Finds series in Orthanc according to queries and labels @@ -152,6 +164,8 @@ def find_series(client: Orthanc, query=query, labels=labels, labels_constraint=labels_constraint, + local_cache=local_cache, + local_cache_file=local_cache_file, **kwargs ) @@ -160,6 +174,8 @@ def find_instances(client: Orthanc, query: Dict[str, str] = None, labels: Union[List[str], str] = None, labels_constraint: str = 'All', + local_cache=False, + local_cache_file='pyorthanc_cache', **kwargs) -> List[Instance]: """Finds instances in Orthanc according to queries and labels @@ -200,6 +216,8 @@ def find_instances(client: Orthanc, query=query, labels=labels, labels_constraint=labels_constraint, + local_cache=local_cache, + local_cache_file=local_cache_file, **kwargs ) @@ -212,7 +230,9 @@ def query_orthanc(client: Orthanc, limit: int = DEFAULT_RESOURCES_LIMIT, since: int = 0, retrieve_all_resources: bool = True, - lock_children: bool = False) -> List[Resource]: + lock_children: bool = False, + local_cache=False, + local_cache_file='pyorthanc_cache') -> List[Resource | Patient | Study | Series | Instance]: """Query data in the Orthanc server Parameters @@ -237,6 +257,11 @@ def query_orthanc(client: Orthanc, If `lock_children` is True, the resource children (ex. instances of a series via `Series.instances`) will be cached at the first query rather than queried every time. This is useful when you want to filter the children of a resource and want to maintain the filter result. + local_cache + If `local_cache` is True, pyorthanc will store find result in a local file called pyorthanc_cache. + Usefull if data don't change between 2 pyorthanc scripts runs + local_cache_file + Name of filename for local cache. Returns ------- List[Resource] @@ -264,43 +289,70 @@ def query_orthanc(client: Orthanc, # In this function, client that return raw responses are not supported. client = util.ensure_non_raw_response(client) - data = { - 'Expand': True, - 'Level': level, - 'Limit': limit, - 'Since': since, - 'Query': {} - } - - if query is not None: - data['Query'] = query - - if labels is not None: - data['Labels'] = [labels] if isinstance(labels, str) else labels - data['LabelsConstraint'] = labels_constraint - - if retrieve_all_resources: - results = [] - while True: - result_for_interval = client.post_tools_find(data) - if len(result_for_interval) == 0: - break - - results += result_for_interval - data['Since'] += limit # Updating the lookup window - else: - results = client.post_tools_find(data) - - if level == 'Patient': - resources = [Patient(i['ID'], client, _lock_children=lock_children) for i in results] - elif level == 'Study': - resources = [Study(i['ID'], client, _lock_children=lock_children) for i in results] - elif level == 'Series': - resources = [Series(i['ID'], client, _lock_children=lock_children) for i in results] - elif level == 'Instance': - resources = [Instance(i['ID'], client, _lock_children=lock_children) for i in results] - else: - raise ValueError(f"Unknown level ['Patient', 'Study', 'Series', 'Instance'], got {level}") + local_cache_name = ((f'{level}-{query}-{labels}-{labels_constraint}-{since}-{limit}' + .replace(' ', '_') + .replace("'", "") + .replace("'", "") + .replace("[", "") + .replace("]", "")) + .lower()) + + if local_cache: + with shelve.open(local_cache_file) as db: + if local_cache_name in db: + logging.info('Cache IDs found. Using cache.') + if level == 'Patient': + resources = [Patient(id_, client, _lock_children=lock_children) for id_ in db[(local_cache_name)]] + if level == 'Study': + resources = [Study(id_, client, _lock_children=lock_children) for id_ in db[(local_cache_name)]] + if level == 'Series': + resources = [Series(id_, client, _lock_children=lock_children) for id_ in db[(local_cache_name)]] + if level == 'Instance': + resources = [Instance(id_, client, _lock_children=lock_children) for id_ in db[(local_cache_name)]] + + return resources + + data = { + 'Expand': True, + 'Level': level, + 'Limit': limit, + 'Since': since, + 'Query': {} + } + + if query is not None: + data['Query'] = query + + if labels is not None: + data['Labels'] = [labels] if isinstance(labels, str) else labels + data['LabelsConstraint'] = labels_constraint + + if retrieve_all_resources: + results = [] + while True: + result_for_interval = client.post_tools_find(data) + if len(result_for_interval) == 0: + break + + results += result_for_interval + data['Since'] += limit # Updating the lookup window + else: + results = client.post_tools_find(data) + + if level == 'Patient': + resources = [Patient(i['ID'], client, _lock_children=lock_children) for i in results] + elif level == 'Study': + resources = [Study(i['ID'], client, _lock_children=lock_children) for i in results] + elif level == 'Series': + resources = [Series(i['ID'], client, _lock_children=lock_children) for i in results] + elif level == 'Instance': + resources = [Instance(i['ID'], client, _lock_children=lock_children) for i in results] + else: + raise ValueError(f"Unknown level ['Patient', 'Study', 'Series', 'Instance'], got {level}") + + if local_cache: + with shelve.open(local_cache_file) as db: + db[local_cache_name] = [s.id_ for s in resources] return resources From 1446b4f0ad3441ccabfa82a055609821f3b3081b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Yannick=20Lemar=C3=A9chal?= <10884038+ylemarechal@users.noreply.github.com> Date: Thu, 31 Jul 2025 15:47:39 +0200 Subject: [PATCH 2/6] remove logging lib --- pyorthanc/_find.py | 2 -- 1 file changed, 2 deletions(-) diff --git a/pyorthanc/_find.py b/pyorthanc/_find.py index 72e8536..308f349 100644 --- a/pyorthanc/_find.py +++ b/pyorthanc/_find.py @@ -1,4 +1,3 @@ -import logging import shelve from typing import Dict, List, Union @@ -300,7 +299,6 @@ def query_orthanc(client: Orthanc, if local_cache: with shelve.open(local_cache_file) as db: if local_cache_name in db: - logging.info('Cache IDs found. Using cache.') if level == 'Patient': resources = [Patient(id_, client, _lock_children=lock_children) for id_ in db[(local_cache_name)]] if level == 'Study': From 51f4874b6d8aa10db06183471d3a4cd5b785355d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Yannick=20Lemar=C3=A9chal?= <10884038+ylemarechal@users.noreply.github.com> Date: Thu, 31 Jul 2025 15:49:36 +0200 Subject: [PATCH 3/6] fix wrong indent --- pyorthanc/_find.py | 82 +++++++++++++++++++++++----------------------- 1 file changed, 41 insertions(+), 41 deletions(-) diff --git a/pyorthanc/_find.py b/pyorthanc/_find.py index 308f349..291604b 100644 --- a/pyorthanc/_find.py +++ b/pyorthanc/_find.py @@ -310,47 +310,47 @@ def query_orthanc(client: Orthanc, return resources - data = { - 'Expand': True, - 'Level': level, - 'Limit': limit, - 'Since': since, - 'Query': {} - } - - if query is not None: - data['Query'] = query - - if labels is not None: - data['Labels'] = [labels] if isinstance(labels, str) else labels - data['LabelsConstraint'] = labels_constraint - - if retrieve_all_resources: - results = [] - while True: - result_for_interval = client.post_tools_find(data) - if len(result_for_interval) == 0: - break - - results += result_for_interval - data['Since'] += limit # Updating the lookup window - else: - results = client.post_tools_find(data) - - if level == 'Patient': - resources = [Patient(i['ID'], client, _lock_children=lock_children) for i in results] - elif level == 'Study': - resources = [Study(i['ID'], client, _lock_children=lock_children) for i in results] - elif level == 'Series': - resources = [Series(i['ID'], client, _lock_children=lock_children) for i in results] - elif level == 'Instance': - resources = [Instance(i['ID'], client, _lock_children=lock_children) for i in results] - else: - raise ValueError(f"Unknown level ['Patient', 'Study', 'Series', 'Instance'], got {level}") - - if local_cache: - with shelve.open(local_cache_file) as db: - db[local_cache_name] = [s.id_ for s in resources] + data = { + 'Expand': True, + 'Level': level, + 'Limit': limit, + 'Since': since, + 'Query': {} + } + + if query is not None: + data['Query'] = query + + if labels is not None: + data['Labels'] = [labels] if isinstance(labels, str) else labels + data['LabelsConstraint'] = labels_constraint + + if retrieve_all_resources: + results = [] + while True: + result_for_interval = client.post_tools_find(data) + if len(result_for_interval) == 0: + break + + results += result_for_interval + data['Since'] += limit # Updating the lookup window + else: + results = client.post_tools_find(data) + + if level == 'Patient': + resources = [Patient(i['ID'], client, _lock_children=lock_children) for i in results] + elif level == 'Study': + resources = [Study(i['ID'], client, _lock_children=lock_children) for i in results] + elif level == 'Series': + resources = [Series(i['ID'], client, _lock_children=lock_children) for i in results] + elif level == 'Instance': + resources = [Instance(i['ID'], client, _lock_children=lock_children) for i in results] + else: + raise ValueError(f"Unknown level ['Patient', 'Study', 'Series', 'Instance'], got {level}") + + if local_cache: + with shelve.open(local_cache_file) as db: + db[local_cache_name] = [s.id_ for s in resources] return resources From e3c73a9848d85f0ae83c5d1a64b952c54439c03b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Yannick=20Lemar=C3=A9chal?= <10884038+ylemarechal@users.noreply.github.com> Date: Fri, 1 Aug 2025 18:05:40 +0200 Subject: [PATCH 4/6] add type hints --- pyorthanc/_find.py | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/pyorthanc/_find.py b/pyorthanc/_find.py index 291604b..1d5b7c8 100644 --- a/pyorthanc/_find.py +++ b/pyorthanc/_find.py @@ -16,8 +16,8 @@ def find_patients(client: Orthanc, query: Dict[str, str] = None, labels: Union[List[str], str] = None, labels_constraint: str = 'All', - local_cache=False, - local_cache_file='pyorthanc_cache', + local_cache: bool = False, + local_cache_file: str ='pyorthanc_cache', **kwargs) -> List[Patient]: """Finds patients in Orthanc according to queries and labels @@ -68,8 +68,8 @@ def find_studies(client: Orthanc, query: Dict[str, str] = None, labels: Union[List[str], str] = None, labels_constraint: str = 'All', - local_cache=False, - local_cache_file='pyorthanc_cache', + local_cache: bool = False, + local_cache_file: str = 'pyorthanc_cache', **kwargs) -> List[Study]: """Finds studies in Orthanc according to queries and labels @@ -121,8 +121,8 @@ def find_series(client: Orthanc, query: Dict[str, str] = None, labels: Union[List[str], str] = None, labels_constraint: str = 'All', - local_cache=False, - local_cache_file='pyorthanc_cache', + local_cache: bool = False, + local_cache_file: str = 'pyorthanc_cache', **kwargs) -> List[Series]: """Finds series in Orthanc according to queries and labels @@ -173,8 +173,8 @@ def find_instances(client: Orthanc, query: Dict[str, str] = None, labels: Union[List[str], str] = None, labels_constraint: str = 'All', - local_cache=False, - local_cache_file='pyorthanc_cache', + local_cache: bool = False, + local_cache_file: str = 'pyorthanc_cache', **kwargs) -> List[Instance]: """Finds instances in Orthanc according to queries and labels @@ -230,8 +230,8 @@ def query_orthanc(client: Orthanc, since: int = 0, retrieve_all_resources: bool = True, lock_children: bool = False, - local_cache=False, - local_cache_file='pyorthanc_cache') -> List[Resource | Patient | Study | Series | Instance]: + local_cache: bool =False, + local_cache_file: str ='pyorthanc_cache') -> List[Resource | Patient | Study | Series | Instance]: """Query data in the Orthanc server Parameters From 4d2c3228159a34a3dbfb59db306e07089724d078 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Yannick=20Lemar=C3=A9chal?= <10884038+ylemarechal@users.noreply.github.com> Date: Fri, 1 Aug 2025 18:08:19 +0200 Subject: [PATCH 5/6] cleaning --- pyorthanc/_find.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/pyorthanc/_find.py b/pyorthanc/_find.py index 1d5b7c8..dbb1c7f 100644 --- a/pyorthanc/_find.py +++ b/pyorthanc/_find.py @@ -17,7 +17,7 @@ def find_patients(client: Orthanc, labels: Union[List[str], str] = None, labels_constraint: str = 'All', local_cache: bool = False, - local_cache_file: str ='pyorthanc_cache', + local_cache_file: str = 'pyorthanc_cache', **kwargs) -> List[Patient]: """Finds patients in Orthanc according to queries and labels @@ -230,8 +230,8 @@ def query_orthanc(client: Orthanc, since: int = 0, retrieve_all_resources: bool = True, lock_children: bool = False, - local_cache: bool =False, - local_cache_file: str ='pyorthanc_cache') -> List[Resource | Patient | Study | Series | Instance]: + local_cache: bool = False, + local_cache_file: str = 'pyorthanc_cache') -> List[Resource | Patient | Study | Series | Instance]: """Query data in the Orthanc server Parameters From e1b4873e9d8efa63c042389f22368c8a0c62117c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Yannick=20Lemar=C3=A9chal?= <10884038+ylemarechal@users.noreply.github.com> Date: Fri, 1 Aug 2025 19:40:05 +0200 Subject: [PATCH 6/6] change to elif --- pyorthanc/_find.py | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/pyorthanc/_find.py b/pyorthanc/_find.py index dbb1c7f..bacb95a 100644 --- a/pyorthanc/_find.py +++ b/pyorthanc/_find.py @@ -289,11 +289,11 @@ def query_orthanc(client: Orthanc, client = util.ensure_non_raw_response(client) local_cache_name = ((f'{level}-{query}-{labels}-{labels_constraint}-{since}-{limit}' - .replace(' ', '_') - .replace("'", "") - .replace("'", "") - .replace("[", "") - .replace("]", "")) + .replace(' ', '_') + .replace("'", "") + .replace("'", "") + .replace("[", "") + .replace("]", "")) .lower()) if local_cache: @@ -301,11 +301,11 @@ def query_orthanc(client: Orthanc, if local_cache_name in db: if level == 'Patient': resources = [Patient(id_, client, _lock_children=lock_children) for id_ in db[(local_cache_name)]] - if level == 'Study': + elif level == 'Study': resources = [Study(id_, client, _lock_children=lock_children) for id_ in db[(local_cache_name)]] - if level == 'Series': + elif level == 'Series': resources = [Series(id_, client, _lock_children=lock_children) for id_ in db[(local_cache_name)]] - if level == 'Instance': + elif level == 'Instance': resources = [Instance(id_, client, _lock_children=lock_children) for id_ in db[(local_cache_name)]] return resources