annotate Sphinx/source/plugins/python.rst @ 348:d8359cecdc89

pillow sample
author Sebastien Jodogne <s.jodogne@gmail.com>
date Fri, 27 Mar 2020 12:20:40 +0100
parents 04fae9d4b65f
children 60080d792f25
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
343
fff45618262d creating the documentation of the Python plugin
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
1 .. _python-plugin:
fff45618262d creating the documentation of the Python plugin
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
2
fff45618262d creating the documentation of the Python plugin
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
3
fff45618262d creating the documentation of the Python plugin
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
4 Python plugin for Orthanc
fff45618262d creating the documentation of the Python plugin
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
5 =========================
fff45618262d creating the documentation of the Python plugin
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
6
fff45618262d creating the documentation of the Python plugin
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
7 .. contents::
fff45618262d creating the documentation of the Python plugin
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
8
fff45618262d creating the documentation of the Python plugin
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
9 Work-in-progress.
fff45618262d creating the documentation of the Python plugin
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
10
345
f81b533a0fd0 python samples
Sebastien Jodogne <s.jodogne@gmail.com>
parents: 343
diff changeset
11 The Python API is automatically generated from the `Orthanc plugin SDK
f81b533a0fd0 python samples
Sebastien Jodogne <s.jodogne@gmail.com>
parents: 343
diff changeset
12 in C
f81b533a0fd0 python samples
Sebastien Jodogne <s.jodogne@gmail.com>
parents: 343
diff changeset
13 <https://hg.orthanc-server.com/orthanc/file/Orthanc-1.5.7/Plugins/Include/orthanc/OrthancCPlugin.h>`__
f81b533a0fd0 python samples
Sebastien Jodogne <s.jodogne@gmail.com>
parents: 343
diff changeset
14 using the `Clang <https://en.wikipedia.org/wiki/Clang>`__ compiler
f81b533a0fd0 python samples
Sebastien Jodogne <s.jodogne@gmail.com>
parents: 343
diff changeset
15 front-end. The coverage of the C SDK is about 75% (105 functions are
f81b533a0fd0 python samples
Sebastien Jodogne <s.jodogne@gmail.com>
parents: 343
diff changeset
16 automatically wrapped in Python out of a total of 139 functions in C).
343
fff45618262d creating the documentation of the Python plugin
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
17
348
d8359cecdc89 pillow sample
Sebastien Jodogne <s.jodogne@gmail.com>
parents: 347
diff changeset
18 This provides much more flexibility than the Lua scripts.
d8359cecdc89 pillow sample
Sebastien Jodogne <s.jodogne@gmail.com>
parents: 347
diff changeset
19
343
fff45618262d creating the documentation of the Python plugin
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
20
fff45618262d creating the documentation of the Python plugin
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
21 Samples
fff45618262d creating the documentation of the Python plugin
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
22 -------
fff45618262d creating the documentation of the Python plugin
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
23
fff45618262d creating the documentation of the Python plugin
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
24 Extending the REST API
fff45618262d creating the documentation of the Python plugin
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
25 ......................
fff45618262d creating the documentation of the Python plugin
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
26
fff45618262d creating the documentation of the Python plugin
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
27 .. highlight:: python
fff45618262d creating the documentation of the Python plugin
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
28
fff45618262d creating the documentation of the Python plugin
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
29 Here is a basic Python script that registers two new routes in the
fff45618262d creating the documentation of the Python plugin
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
30 REST API::
fff45618262d creating the documentation of the Python plugin
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
31
fff45618262d creating the documentation of the Python plugin
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
32 import orthanc
fff45618262d creating the documentation of the Python plugin
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
33 import pprint
fff45618262d creating the documentation of the Python plugin
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
34
fff45618262d creating the documentation of the Python plugin
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
35 def OnRest(output, uri, **request):
fff45618262d creating the documentation of the Python plugin
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
36 pprint.pprint(request)
fff45618262d creating the documentation of the Python plugin
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
37 print('Accessing uri: %s' % uri)
fff45618262d creating the documentation of the Python plugin
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
38 output.AnswerBuffer('ok\n', 'text/plain')
fff45618262d creating the documentation of the Python plugin
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
39
fff45618262d creating the documentation of the Python plugin
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
40 orthanc.RegisterRestCallback('/(to)(t)o', OnRest)
fff45618262d creating the documentation of the Python plugin
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
41 orthanc.RegisterRestCallback('/tata', OnRest)
fff45618262d creating the documentation of the Python plugin
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
42
fff45618262d creating the documentation of the Python plugin
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
43 .. highlight:: json
fff45618262d creating the documentation of the Python plugin
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
44
fff45618262d creating the documentation of the Python plugin
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
45 Here is the associated minimal configuration file for Orthanc
fff45618262d creating the documentation of the Python plugin
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
46 (provided the Python script is saved as ``rest.py``)::
fff45618262d creating the documentation of the Python plugin
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
47
fff45618262d creating the documentation of the Python plugin
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
48 {
fff45618262d creating the documentation of the Python plugin
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
49 "Plugins" : [ "." ],
fff45618262d creating the documentation of the Python plugin
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
50 "PythonScript" : "rest.py",
fff45618262d creating the documentation of the Python plugin
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
51 "PythonVerbose" : false
fff45618262d creating the documentation of the Python plugin
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
52 }
fff45618262d creating the documentation of the Python plugin
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
53
fff45618262d creating the documentation of the Python plugin
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
54 .. highlight:: bash
fff45618262d creating the documentation of the Python plugin
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
55
fff45618262d creating the documentation of the Python plugin
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
56 The route can then be accessed as::
fff45618262d creating the documentation of the Python plugin
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
57
fff45618262d creating the documentation of the Python plugin
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
58 $ curl http://localhost:8042/toto
fff45618262d creating the documentation of the Python plugin
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
59 ok
fff45618262d creating the documentation of the Python plugin
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff changeset
60
345
f81b533a0fd0 python samples
Sebastien Jodogne <s.jodogne@gmail.com>
parents: 343
diff changeset
61
f81b533a0fd0 python samples
Sebastien Jodogne <s.jodogne@gmail.com>
parents: 343
diff changeset
62 Listening to changes
f81b533a0fd0 python samples
Sebastien Jodogne <s.jodogne@gmail.com>
parents: 343
diff changeset
63 ....................
f81b533a0fd0 python samples
Sebastien Jodogne <s.jodogne@gmail.com>
parents: 343
diff changeset
64
346
bdf8757449e3 more python samples
Sebastien Jodogne <s.jodogne@gmail.com>
parents: 345
diff changeset
65 .. highlight:: python
bdf8757449e3 more python samples
Sebastien Jodogne <s.jodogne@gmail.com>
parents: 345
diff changeset
66
345
f81b533a0fd0 python samples
Sebastien Jodogne <s.jodogne@gmail.com>
parents: 343
diff changeset
67 This sample uploads a DICOM file as soon as Orthanc is started::
f81b533a0fd0 python samples
Sebastien Jodogne <s.jodogne@gmail.com>
parents: 343
diff changeset
68
f81b533a0fd0 python samples
Sebastien Jodogne <s.jodogne@gmail.com>
parents: 343
diff changeset
69 import orthanc
f81b533a0fd0 python samples
Sebastien Jodogne <s.jodogne@gmail.com>
parents: 343
diff changeset
70
f81b533a0fd0 python samples
Sebastien Jodogne <s.jodogne@gmail.com>
parents: 343
diff changeset
71 def OnChange(changeType, level, resource):
f81b533a0fd0 python samples
Sebastien Jodogne <s.jodogne@gmail.com>
parents: 343
diff changeset
72 if changeType == orthanc.ChangeType.ORTHANC_STARTED:
f81b533a0fd0 python samples
Sebastien Jodogne <s.jodogne@gmail.com>
parents: 343
diff changeset
73 print('Started')
f81b533a0fd0 python samples
Sebastien Jodogne <s.jodogne@gmail.com>
parents: 343
diff changeset
74
f81b533a0fd0 python samples
Sebastien Jodogne <s.jodogne@gmail.com>
parents: 343
diff changeset
75 with open('/tmp/sample.dcm', 'rb') as f:
f81b533a0fd0 python samples
Sebastien Jodogne <s.jodogne@gmail.com>
parents: 343
diff changeset
76 orthanc.RestApiPost('/instances', f.read())
f81b533a0fd0 python samples
Sebastien Jodogne <s.jodogne@gmail.com>
parents: 343
diff changeset
77
f81b533a0fd0 python samples
Sebastien Jodogne <s.jodogne@gmail.com>
parents: 343
diff changeset
78 elif changeType == orthanc.ChangeType.ORTHANC_STOPPED:
f81b533a0fd0 python samples
Sebastien Jodogne <s.jodogne@gmail.com>
parents: 343
diff changeset
79 print('Stopped')
f81b533a0fd0 python samples
Sebastien Jodogne <s.jodogne@gmail.com>
parents: 343
diff changeset
80
f81b533a0fd0 python samples
Sebastien Jodogne <s.jodogne@gmail.com>
parents: 343
diff changeset
81 elif changeType == orthanc.ChangeType.NEW_INSTANCE:
f81b533a0fd0 python samples
Sebastien Jodogne <s.jodogne@gmail.com>
parents: 343
diff changeset
82 print('A new instance was uploaded: %s' % resource)
f81b533a0fd0 python samples
Sebastien Jodogne <s.jodogne@gmail.com>
parents: 343
diff changeset
83
f81b533a0fd0 python samples
Sebastien Jodogne <s.jodogne@gmail.com>
parents: 343
diff changeset
84 orthanc.RegisterOnChangeCallback(OnChange)
f81b533a0fd0 python samples
Sebastien Jodogne <s.jodogne@gmail.com>
parents: 343
diff changeset
85
f81b533a0fd0 python samples
Sebastien Jodogne <s.jodogne@gmail.com>
parents: 343
diff changeset
86
f81b533a0fd0 python samples
Sebastien Jodogne <s.jodogne@gmail.com>
parents: 343
diff changeset
87 Accessing the content of a new instance
346
bdf8757449e3 more python samples
Sebastien Jodogne <s.jodogne@gmail.com>
parents: 345
diff changeset
88 .......................................
bdf8757449e3 more python samples
Sebastien Jodogne <s.jodogne@gmail.com>
parents: 345
diff changeset
89
bdf8757449e3 more python samples
Sebastien Jodogne <s.jodogne@gmail.com>
parents: 345
diff changeset
90 .. highlight:: python
345
f81b533a0fd0 python samples
Sebastien Jodogne <s.jodogne@gmail.com>
parents: 343
diff changeset
91
f81b533a0fd0 python samples
Sebastien Jodogne <s.jodogne@gmail.com>
parents: 343
diff changeset
92 ::
f81b533a0fd0 python samples
Sebastien Jodogne <s.jodogne@gmail.com>
parents: 343
diff changeset
93
f81b533a0fd0 python samples
Sebastien Jodogne <s.jodogne@gmail.com>
parents: 343
diff changeset
94 import orthanc
f81b533a0fd0 python samples
Sebastien Jodogne <s.jodogne@gmail.com>
parents: 343
diff changeset
95 import json
f81b533a0fd0 python samples
Sebastien Jodogne <s.jodogne@gmail.com>
parents: 343
diff changeset
96 import pprint
f81b533a0fd0 python samples
Sebastien Jodogne <s.jodogne@gmail.com>
parents: 343
diff changeset
97
f81b533a0fd0 python samples
Sebastien Jodogne <s.jodogne@gmail.com>
parents: 343
diff changeset
98 def OnStoredInstance(dicom, instanceId):
f81b533a0fd0 python samples
Sebastien Jodogne <s.jodogne@gmail.com>
parents: 343
diff changeset
99 print('Received instance %s of size %d (transfer syntax %s, SOP class UID %s)' % (
f81b533a0fd0 python samples
Sebastien Jodogne <s.jodogne@gmail.com>
parents: 343
diff changeset
100 instanceId, dicom.GetInstanceSize(),
f81b533a0fd0 python samples
Sebastien Jodogne <s.jodogne@gmail.com>
parents: 343
diff changeset
101 dicom.GetInstanceMetadata('TransferSyntax'),
f81b533a0fd0 python samples
Sebastien Jodogne <s.jodogne@gmail.com>
parents: 343
diff changeset
102 dicom.GetInstanceMetadata('SopClassUid')))
f81b533a0fd0 python samples
Sebastien Jodogne <s.jodogne@gmail.com>
parents: 343
diff changeset
103
f81b533a0fd0 python samples
Sebastien Jodogne <s.jodogne@gmail.com>
parents: 343
diff changeset
104 # Print the origin information
f81b533a0fd0 python samples
Sebastien Jodogne <s.jodogne@gmail.com>
parents: 343
diff changeset
105 if dicom.GetInstanceOrigin() == orthanc.InstanceOrigin.DICOM_PROTOCOL:
f81b533a0fd0 python samples
Sebastien Jodogne <s.jodogne@gmail.com>
parents: 343
diff changeset
106 print('This instance was received through the DICOM protocol')
f81b533a0fd0 python samples
Sebastien Jodogne <s.jodogne@gmail.com>
parents: 343
diff changeset
107 elif dicom.GetInstanceOrigin() == orthanc.InstanceOrigin.REST_API:
f81b533a0fd0 python samples
Sebastien Jodogne <s.jodogne@gmail.com>
parents: 343
diff changeset
108 print('This instance was received through the REST API')
f81b533a0fd0 python samples
Sebastien Jodogne <s.jodogne@gmail.com>
parents: 343
diff changeset
109
f81b533a0fd0 python samples
Sebastien Jodogne <s.jodogne@gmail.com>
parents: 343
diff changeset
110 # Print the DICOM tags
f81b533a0fd0 python samples
Sebastien Jodogne <s.jodogne@gmail.com>
parents: 343
diff changeset
111 pprint.pprint(json.loads(dicom.GetInstanceSimplifiedJson()))
f81b533a0fd0 python samples
Sebastien Jodogne <s.jodogne@gmail.com>
parents: 343
diff changeset
112
f81b533a0fd0 python samples
Sebastien Jodogne <s.jodogne@gmail.com>
parents: 343
diff changeset
113 orthanc.RegisterOnStoredInstanceCallback(OnStoredInstance)
346
bdf8757449e3 more python samples
Sebastien Jodogne <s.jodogne@gmail.com>
parents: 345
diff changeset
114
bdf8757449e3 more python samples
Sebastien Jodogne <s.jodogne@gmail.com>
parents: 345
diff changeset
115
bdf8757449e3 more python samples
Sebastien Jodogne <s.jodogne@gmail.com>
parents: 345
diff changeset
116 Calling pydicom
bdf8757449e3 more python samples
Sebastien Jodogne <s.jodogne@gmail.com>
parents: 345
diff changeset
117 ...............
bdf8757449e3 more python samples
Sebastien Jodogne <s.jodogne@gmail.com>
parents: 345
diff changeset
118
bdf8757449e3 more python samples
Sebastien Jodogne <s.jodogne@gmail.com>
parents: 345
diff changeset
119 .. highlight:: python
bdf8757449e3 more python samples
Sebastien Jodogne <s.jodogne@gmail.com>
parents: 345
diff changeset
120
bdf8757449e3 more python samples
Sebastien Jodogne <s.jodogne@gmail.com>
parents: 345
diff changeset
121 Here is a sample Python plugin that registers a REST callback to dump
bdf8757449e3 more python samples
Sebastien Jodogne <s.jodogne@gmail.com>
parents: 345
diff changeset
122 the content of the dataset of one given DICOM instance stored in
bdf8757449e3 more python samples
Sebastien Jodogne <s.jodogne@gmail.com>
parents: 345
diff changeset
123 Orthanc, using `pydicom <https://pydicom.github.io/>`__::
bdf8757449e3 more python samples
Sebastien Jodogne <s.jodogne@gmail.com>
parents: 345
diff changeset
124
bdf8757449e3 more python samples
Sebastien Jodogne <s.jodogne@gmail.com>
parents: 345
diff changeset
125 import io
bdf8757449e3 more python samples
Sebastien Jodogne <s.jodogne@gmail.com>
parents: 345
diff changeset
126 import orthanc
bdf8757449e3 more python samples
Sebastien Jodogne <s.jodogne@gmail.com>
parents: 345
diff changeset
127 import pydicom
bdf8757449e3 more python samples
Sebastien Jodogne <s.jodogne@gmail.com>
parents: 345
diff changeset
128
bdf8757449e3 more python samples
Sebastien Jodogne <s.jodogne@gmail.com>
parents: 345
diff changeset
129 def DecodeInstance(output, uri, **request):
bdf8757449e3 more python samples
Sebastien Jodogne <s.jodogne@gmail.com>
parents: 345
diff changeset
130 if request['method'] == 'GET':
347
04fae9d4b65f auto-routing
Sebastien Jodogne <s.jodogne@gmail.com>
parents: 346
diff changeset
131 # Retrieve the instance ID from the regular expression (*)
346
bdf8757449e3 more python samples
Sebastien Jodogne <s.jodogne@gmail.com>
parents: 345
diff changeset
132 instanceId = request['groups'][0]
347
04fae9d4b65f auto-routing
Sebastien Jodogne <s.jodogne@gmail.com>
parents: 346
diff changeset
133 # Get the content of the DICOM file
346
bdf8757449e3 more python samples
Sebastien Jodogne <s.jodogne@gmail.com>
parents: 345
diff changeset
134 f = orthanc.GetDicomForInstance(instanceId)
347
04fae9d4b65f auto-routing
Sebastien Jodogne <s.jodogne@gmail.com>
parents: 346
diff changeset
135 # Parse it using pydicom
346
bdf8757449e3 more python samples
Sebastien Jodogne <s.jodogne@gmail.com>
parents: 345
diff changeset
136 dicom = pydicom.dcmread(io.BytesIO(f))
347
04fae9d4b65f auto-routing
Sebastien Jodogne <s.jodogne@gmail.com>
parents: 346
diff changeset
137 # Return a string representation the dataset to the caller
346
bdf8757449e3 more python samples
Sebastien Jodogne <s.jodogne@gmail.com>
parents: 345
diff changeset
138 output.AnswerBuffer(str(dicom), 'text/plain')
bdf8757449e3 more python samples
Sebastien Jodogne <s.jodogne@gmail.com>
parents: 345
diff changeset
139 else:
bdf8757449e3 more python samples
Sebastien Jodogne <s.jodogne@gmail.com>
parents: 345
diff changeset
140 output.SendMethodNotAllowed('GET')
bdf8757449e3 more python samples
Sebastien Jodogne <s.jodogne@gmail.com>
parents: 345
diff changeset
141
347
04fae9d4b65f auto-routing
Sebastien Jodogne <s.jodogne@gmail.com>
parents: 346
diff changeset
142 orthanc.RegisterRestCallback('/pydicom/(.*)', DecodeInstance) # (*)
346
bdf8757449e3 more python samples
Sebastien Jodogne <s.jodogne@gmail.com>
parents: 345
diff changeset
143
bdf8757449e3 more python samples
Sebastien Jodogne <s.jodogne@gmail.com>
parents: 345
diff changeset
144 .. highlight:: bash
bdf8757449e3 more python samples
Sebastien Jodogne <s.jodogne@gmail.com>
parents: 345
diff changeset
145
bdf8757449e3 more python samples
Sebastien Jodogne <s.jodogne@gmail.com>
parents: 345
diff changeset
146 This can be called as follows::
bdf8757449e3 more python samples
Sebastien Jodogne <s.jodogne@gmail.com>
parents: 345
diff changeset
147
bdf8757449e3 more python samples
Sebastien Jodogne <s.jodogne@gmail.com>
parents: 345
diff changeset
148 $ curl http://localhost:8042/pydicom/19816330-cb02e1cf-df3a8fe8-bf510623-ccefe9f5
bdf8757449e3 more python samples
Sebastien Jodogne <s.jodogne@gmail.com>
parents: 345
diff changeset
149
347
04fae9d4b65f auto-routing
Sebastien Jodogne <s.jodogne@gmail.com>
parents: 346
diff changeset
150
04fae9d4b65f auto-routing
Sebastien Jodogne <s.jodogne@gmail.com>
parents: 346
diff changeset
151 Auto-routing studies
04fae9d4b65f auto-routing
Sebastien Jodogne <s.jodogne@gmail.com>
parents: 346
diff changeset
152 ....................
04fae9d4b65f auto-routing
Sebastien Jodogne <s.jodogne@gmail.com>
parents: 346
diff changeset
153
04fae9d4b65f auto-routing
Sebastien Jodogne <s.jodogne@gmail.com>
parents: 346
diff changeset
154 .. highlight:: python
04fae9d4b65f auto-routing
Sebastien Jodogne <s.jodogne@gmail.com>
parents: 346
diff changeset
155
04fae9d4b65f auto-routing
Sebastien Jodogne <s.jodogne@gmail.com>
parents: 346
diff changeset
156 Here is a sample Python plugin that routes any :ref:`stable study
04fae9d4b65f auto-routing
Sebastien Jodogne <s.jodogne@gmail.com>
parents: 346
diff changeset
157 <lua-callbacks>` to a modality named ``samples`` (as declared in the
04fae9d4b65f auto-routing
Sebastien Jodogne <s.jodogne@gmail.com>
parents: 346
diff changeset
158 ``DicomModalities`` configuration option)::
04fae9d4b65f auto-routing
Sebastien Jodogne <s.jodogne@gmail.com>
parents: 346
diff changeset
159
04fae9d4b65f auto-routing
Sebastien Jodogne <s.jodogne@gmail.com>
parents: 346
diff changeset
160 import orthanc
04fae9d4b65f auto-routing
Sebastien Jodogne <s.jodogne@gmail.com>
parents: 346
diff changeset
161
04fae9d4b65f auto-routing
Sebastien Jodogne <s.jodogne@gmail.com>
parents: 346
diff changeset
162 def OnChange(changeType, level, resourceId):
04fae9d4b65f auto-routing
Sebastien Jodogne <s.jodogne@gmail.com>
parents: 346
diff changeset
163 if changeType == orthanc.ChangeType.STABLE_STUDY:
04fae9d4b65f auto-routing
Sebastien Jodogne <s.jodogne@gmail.com>
parents: 346
diff changeset
164 print('Stable study: %s' % resourceId)
04fae9d4b65f auto-routing
Sebastien Jodogne <s.jodogne@gmail.com>
parents: 346
diff changeset
165 orthanc.RestApiPost('/modalities/sample/store', resourceId)
04fae9d4b65f auto-routing
Sebastien Jodogne <s.jodogne@gmail.com>
parents: 346
diff changeset
166
04fae9d4b65f auto-routing
Sebastien Jodogne <s.jodogne@gmail.com>
parents: 346
diff changeset
167 orthanc.RegisterOnChangeCallback(OnChange)
348
d8359cecdc89 pillow sample
Sebastien Jodogne <s.jodogne@gmail.com>
parents: 347
diff changeset
168
d8359cecdc89 pillow sample
Sebastien Jodogne <s.jodogne@gmail.com>
parents: 347
diff changeset
169
d8359cecdc89 pillow sample
Sebastien Jodogne <s.jodogne@gmail.com>
parents: 347
diff changeset
170 Render a thumbnail using PIL/Pillow
d8359cecdc89 pillow sample
Sebastien Jodogne <s.jodogne@gmail.com>
parents: 347
diff changeset
171 ...................................
d8359cecdc89 pillow sample
Sebastien Jodogne <s.jodogne@gmail.com>
parents: 347
diff changeset
172
d8359cecdc89 pillow sample
Sebastien Jodogne <s.jodogne@gmail.com>
parents: 347
diff changeset
173 .. highlight:: python
d8359cecdc89 pillow sample
Sebastien Jodogne <s.jodogne@gmail.com>
parents: 347
diff changeset
174
d8359cecdc89 pillow sample
Sebastien Jodogne <s.jodogne@gmail.com>
parents: 347
diff changeset
175 ::
d8359cecdc89 pillow sample
Sebastien Jodogne <s.jodogne@gmail.com>
parents: 347
diff changeset
176
d8359cecdc89 pillow sample
Sebastien Jodogne <s.jodogne@gmail.com>
parents: 347
diff changeset
177 from PIL import Image
d8359cecdc89 pillow sample
Sebastien Jodogne <s.jodogne@gmail.com>
parents: 347
diff changeset
178 import io
d8359cecdc89 pillow sample
Sebastien Jodogne <s.jodogne@gmail.com>
parents: 347
diff changeset
179 import orthanc
d8359cecdc89 pillow sample
Sebastien Jodogne <s.jodogne@gmail.com>
parents: 347
diff changeset
180
d8359cecdc89 pillow sample
Sebastien Jodogne <s.jodogne@gmail.com>
parents: 347
diff changeset
181 def DecodeInstance(output, uri, **request):
d8359cecdc89 pillow sample
Sebastien Jodogne <s.jodogne@gmail.com>
parents: 347
diff changeset
182 if request['method'] == 'GET':
d8359cecdc89 pillow sample
Sebastien Jodogne <s.jodogne@gmail.com>
parents: 347
diff changeset
183 # Retrieve the instance ID from the regular expression (*)
d8359cecdc89 pillow sample
Sebastien Jodogne <s.jodogne@gmail.com>
parents: 347
diff changeset
184 instanceId = request['groups'][0]
d8359cecdc89 pillow sample
Sebastien Jodogne <s.jodogne@gmail.com>
parents: 347
diff changeset
185
d8359cecdc89 pillow sample
Sebastien Jodogne <s.jodogne@gmail.com>
parents: 347
diff changeset
186 # Render the instance, then open it in Python using PIL/Pillow
d8359cecdc89 pillow sample
Sebastien Jodogne <s.jodogne@gmail.com>
parents: 347
diff changeset
187 png = orthanc.RestApiGet('/instances/%s/rendered' % instanceId)
d8359cecdc89 pillow sample
Sebastien Jodogne <s.jodogne@gmail.com>
parents: 347
diff changeset
188 image = Image.open(io.BytesIO(png))
d8359cecdc89 pillow sample
Sebastien Jodogne <s.jodogne@gmail.com>
parents: 347
diff changeset
189
d8359cecdc89 pillow sample
Sebastien Jodogne <s.jodogne@gmail.com>
parents: 347
diff changeset
190 # Downsize the image as a 64x64 thumbnail
d8359cecdc89 pillow sample
Sebastien Jodogne <s.jodogne@gmail.com>
parents: 347
diff changeset
191 image.thumbnail((64, 64), Image.ANTIALIAS)
d8359cecdc89 pillow sample
Sebastien Jodogne <s.jodogne@gmail.com>
parents: 347
diff changeset
192
d8359cecdc89 pillow sample
Sebastien Jodogne <s.jodogne@gmail.com>
parents: 347
diff changeset
193 # Save the thumbnail as JPEG, then send the buffer to the caller
d8359cecdc89 pillow sample
Sebastien Jodogne <s.jodogne@gmail.com>
parents: 347
diff changeset
194 jpeg = io.BytesIO()
d8359cecdc89 pillow sample
Sebastien Jodogne <s.jodogne@gmail.com>
parents: 347
diff changeset
195 image.save(jpeg, format = "JPEG", quality = 80)
d8359cecdc89 pillow sample
Sebastien Jodogne <s.jodogne@gmail.com>
parents: 347
diff changeset
196 jpeg.seek(0)
d8359cecdc89 pillow sample
Sebastien Jodogne <s.jodogne@gmail.com>
parents: 347
diff changeset
197 output.AnswerBuffer(jpeg.read(), 'text/plain')
d8359cecdc89 pillow sample
Sebastien Jodogne <s.jodogne@gmail.com>
parents: 347
diff changeset
198
d8359cecdc89 pillow sample
Sebastien Jodogne <s.jodogne@gmail.com>
parents: 347
diff changeset
199 else:
d8359cecdc89 pillow sample
Sebastien Jodogne <s.jodogne@gmail.com>
parents: 347
diff changeset
200 output.SendMethodNotAllowed('GET')
d8359cecdc89 pillow sample
Sebastien Jodogne <s.jodogne@gmail.com>
parents: 347
diff changeset
201
d8359cecdc89 pillow sample
Sebastien Jodogne <s.jodogne@gmail.com>
parents: 347
diff changeset
202 orthanc.RegisterRestCallback('/pydicom/(.*)', DecodeInstance) # (*)