changeset 727:698eb280060a

pynetdicom sample
author Sebastien Jodogne <s.jodogne@gmail.com>
date Mon, 28 Jun 2021 07:48:48 +0200
parents 26940c3246c3
children 512bb983454c
files Sphinx/source/plugins/python.rst Sphinx/source/plugins/python/pynetdicom.py
diffstat 2 files changed, 65 insertions(+), 1 deletions(-) [+]
line wrap: on
line diff
--- a/Sphinx/source/plugins/python.rst	Fri Jun 25 20:44:09 2021 +0200
+++ b/Sphinx/source/plugins/python.rst	Mon Jun 28 07:48:48 2021 +0200
@@ -662,7 +662,40 @@
   I: (fffe,e0dd) na (SequenceDelimitationItem for re-encod.) #   0, 0 SequenceDelimitationItem
   I:
 
-                               
+
+.. _pynetdicom:
+
+Replacing DICOM SCP of Orthanc by pynetdicom
+............................................
+
+.. highlight:: json
+
+Thanks to Python plugins, it is also possible to replace the built-in
+DICOM SCP of Orthanc by `pynetdicom
+<https://pydicom.github.io/pynetdicom/stable/examples/storage.html>`__
+so as to customize how the DICOM protocol is handled. Firstly, in the
+configuration file, make sure to disable the Orthanc SCP by setting
+``DicomServerEnabled`` to ``false``::
+
+  {
+    "Plugins" : [ "." ],
+    "PythonScript" : "pynetdicom.py",
+    "DicomServerEnabled" : false
+  }
+
+Secondly, here a basic plugin illustrating how to start and stop the
+pynetdicom server, and handle incoming C-STORE requests:
+
+.. literalinclude:: python/pynetdicom.py
+                    :language: python
+
+As can be seen in this listing, whenever the pynetdicom receives an
+incoming C-STORE request, it makes a POST call to the URI
+``/instances`` in the REST API of Orthanc in order to store the
+embedded DICOM dataset into Orthanc. Obviously, one can build more
+complex DICOM servers by handling more messages than C-STORE alone.
+
+  
 
 Performance and concurrency
 ---------------------------
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Sphinx/source/plugins/python/pynetdicom.py	Mon Jun 28 07:48:48 2021 +0200
@@ -0,0 +1,31 @@
+import json
+import orthanc
+import pynetdicom
+
+def HandleStore(event):
+    orthanc.LogWarning('Handling C-STORE using pynetdicom')
+    orthanc.RestApiPost('/instances', event.request.DataSet.getvalue())
+    return 0x0000
+
+ae = pynetdicom.AE()
+ae.supported_contexts = pynetdicom.AllStoragePresentationContexts
+
+SCP = None
+
+def OnChange(changeType, level, resource):
+    global SCP
+    
+    if changeType == orthanc.ChangeType.ORTHANC_STARTED:
+        port = json.loads(orthanc.GetConfiguration()).get('DicomPort', 4242)
+        
+        SCP = ae.start_server(('', port), block = False, evt_handlers = [
+            (pynetdicom.evt.EVT_C_STORE, HandleStore),
+        ])
+        
+        orthanc.LogWarning('DICOM server using pynetdicom has started')
+
+    elif changeType == orthanc.ChangeType.ORTHANC_STOPPED:
+        orthanc.LogWarning('Stopping pynetdicom')
+        SCP.shutdown()
+
+orthanc.RegisterOnChangeCallback(OnChange)