changeset 700:56a06ca9ec20

Handling worklist SCP requests in Python
author Sebastien Jodogne <s.jodogne@gmail.com>
date Fri, 11 Jun 2021 09:22:22 +0200
parents a777b9e6ef70
children f093160dd7f4
files Sphinx/source/plugins/python.rst Sphinx/source/plugins/python/worklist.py
diffstat 2 files changed, 55 insertions(+), 3 deletions(-) [+]
line wrap: on
line diff
--- a/Sphinx/source/plugins/python.rst	Fri Jun 11 06:56:18 2021 +0200
+++ b/Sphinx/source/plugins/python.rst	Fri Jun 11 09:22:22 2021 +0200
@@ -952,9 +952,28 @@
 It is now up to your Python callback to proces the C-MOVE SCU request,
 for instance by calling the route ``/modalities/{...}/store`` in the
 :ref:`REST API <rest-store-scu>` of Orthanc using
-``orthanc.RestApiPost()``.
-  
-  
+``orthanc.RestApiPost()``. It is highly advised to create a Python
+thread to handle the request, in order to avoid blocking Orthanc as
+much as possible.
+
+
+.. _python_worklists:
+
+Handling worklist SCP requests (new in 3.2)
+...........................................
+
+Starting with release 3.2 of the Python plugin, it is possible to
+answer worklist queries using a Python script. This is especially
+useful to create a bridge between Orthanc, HL7 messages and RIS
+systems. Indeed, Python provides many tools to handle HL7 such as
+`python-hl7 library <https://python-hl7.readthedocs.io/en/latest/>`__.
+
+The following Python script reproduces features similar to the
+:ref:`sample modality worklists plugin <worklists-plugin>`:
+
+.. literalinclude:: python/worklist.py
+                    :language: python
+
 
 Performance and concurrency
 ---------------------------
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Sphinx/source/plugins/python/worklist.py	Fri Jun 11 09:22:22 2021 +0200
@@ -0,0 +1,33 @@
+import json
+import orthanc
+import os
+
+# Path to the directory containing the DICOM worklists
+# https://hg.orthanc-server.com/orthanc/file/Orthanc-1.9.3/OrthancServer/Plugins/Samples/ModalityWorklists/WorklistsDatabase
+WORKLIST_DIR = '/tmp/WorklistsDatabase'
+
+def OnWorklist(answers, query, issuerAet, calledAet):
+    print('Received incoming C-FIND worklist request from %s:' % issuerAet)
+
+    # Get a memory buffer containing the DICOM instance
+    dicom = query.WorklistGetDicomQuery()
+
+    # Get the DICOM tags in the JSON format from the binary buffer
+    jsonTags = json.loads(orthanc.DicomBufferToJson(
+        dicom, orthanc.DicomToJsonFormat.SHORT, orthanc.DicomToJsonFlags.NONE, 0))
+
+    orthanc.LogWarning('C-FIND worklist request to be handled in Python: %s' %
+                       json.dumps(jsonTags, indent = 4, sort_keys = True))
+
+    # Loop over the available DICOM worklists
+    for path in os.listdir(WORKLIST_DIR):
+        if os.path.splitext(path) [1] == '.wl':
+            with open(os.path.join(WORKLIST_DIR, path), 'rb') as f:
+                content = f.read()
+                
+                # Test whether the query matches the current worklist
+                if query.WorklistIsMatch(content):
+                    orthanc.LogWarning('Matching worklist: %s' % path)
+                    answers.WorklistAddAnswer(query, content)
+
+orthanc.RegisterWorklistCallback(OnWorklist)