Mercurial > hg > orthanc-book
annotate Sphinx/source/plugins/python.rst @ 1113:a588960a72e5 default tip
spelling
author | Alain Mazy <am@orthanc.team> |
---|---|
date | Mon, 28 Oct 2024 09:23:08 +0100 |
parents | e70e9f412627 |
children |
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 |
371
5cb37e6b014b
explicit links to the source code of python plugin
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
364
diff
changeset
|
9 |
364
234de55ed125
usage of the python plugin
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
354
diff
changeset
|
10 Overview |
234de55ed125
usage of the python plugin
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
354
diff
changeset
|
11 -------- |
234de55ed125
usage of the python plugin
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
354
diff
changeset
|
12 |
234de55ed125
usage of the python plugin
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
354
diff
changeset
|
13 This plugin can be used to write :ref:`Orthanc plugins |
234de55ed125
usage of the python plugin
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
354
diff
changeset
|
14 <creating-plugins>` using the `Python programming language |
234de55ed125
usage of the python plugin
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
354
diff
changeset
|
15 <https://en.wikipedia.org/wiki/Python_(programming_language)>`__ |
234de55ed125
usage of the python plugin
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
354
diff
changeset
|
16 instead of the more complex C/C++ programming languages. |
343
fff45618262d
creating the documentation of the Python plugin
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
17 |
364
234de55ed125
usage of the python plugin
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
354
diff
changeset
|
18 Python plugins have access to more features and a more consistent SDK |
709
9d5e17100a8d
update statistics from 2.0 to 3.2
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
708
diff
changeset
|
19 than :ref:`Lua scripts <lua>`. The largest part of the Python API is |
9d5e17100a8d
update statistics from 2.0 to 3.2
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
708
diff
changeset
|
20 automatically generated from the `Orthanc plugin SDK in C |
1075 | 21 <https://orthanc.uclouvain.be/hg/orthanc/file/Orthanc-1.12.4/OrthancServer/Plugins/Include/orthanc/OrthancCPlugin.h>`__ |
345 | 22 using the `Clang <https://en.wikipedia.org/wiki/Clang>`__ compiler |
364
234de55ed125
usage of the python plugin
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
354
diff
changeset
|
23 front-end. |
234de55ed125
usage of the python plugin
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
354
diff
changeset
|
24 |
1090 | 25 As of release 4.3 of the plugin, **the coverage of the C SDK is about |
26 85%** (140 functions are automatically wrapped in Python out of a | |
27 total of 165 functions from the Orthanc SDK 1.10.0). Starting with | |
28 release 4.3, the code model that is used to generate the Python | |
29 wrapper is shared with the :ref:`Java wrapper <java-plugin>`. | |
343
fff45618262d
creating the documentation of the Python plugin
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
30 |
371
5cb37e6b014b
explicit links to the source code of python plugin
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
364
diff
changeset
|
31 |
5cb37e6b014b
explicit links to the source code of python plugin
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
364
diff
changeset
|
32 Source code |
5cb37e6b014b
explicit links to the source code of python plugin
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
364
diff
changeset
|
33 ----------- |
5cb37e6b014b
explicit links to the source code of python plugin
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
364
diff
changeset
|
34 |
5cb37e6b014b
explicit links to the source code of python plugin
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
364
diff
changeset
|
35 * Link to the `official releases of this plugin |
993
05b106383b2a
migration to UCLouvain servers
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
991
diff
changeset
|
36 <https://orthanc.uclouvain.be/downloads/sources/orthanc-python/index.html>`__. |
371
5cb37e6b014b
explicit links to the source code of python plugin
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
364
diff
changeset
|
37 |
5cb37e6b014b
explicit links to the source code of python plugin
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
364
diff
changeset
|
38 * Link to the `code repository |
991
1316bc62b5d5
migration to UCLouvain servers
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
984
diff
changeset
|
39 <https://orthanc.uclouvain.be/hg/orthanc-python/>`__. |
371
5cb37e6b014b
explicit links to the source code of python plugin
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
364
diff
changeset
|
40 |
1090 | 41 * Link to the `Python interface |
42 <https://orthanc.uclouvain.be/downloads/cross-platform/orthanc-python/index.html>`__ | |
43 (cf. :ref:`below <python-code-completion>` for more information | |
44 about the ``orthanc.pyi`` file). | |
45 | |
371
5cb37e6b014b
explicit links to the source code of python plugin
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
364
diff
changeset
|
46 |
353 | 47 Licensing |
48 --------- | |
49 | |
50 Pay attention to the fact that this plugin is licensed under the terms | |
51 of the `AGPL license | |
52 <https://en.wikipedia.org/wiki/GNU_Affero_General_Public_License>`__. | |
53 | |
54 This has an important consequence: If you distribute Orthanc to | |
364
234de55ed125
usage of the python plugin
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
354
diff
changeset
|
55 clients together with one Python script, or if you put an Orthanc |
234de55ed125
usage of the python plugin
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
354
diff
changeset
|
56 server equipped with one Python script on a Web portal, you **must** |
234de55ed125
usage of the python plugin
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
354
diff
changeset
|
57 disclose the source code of your Python script to the Orthanc |
354 | 58 community under the terms of the AGPL license. |
59 | |
60 We suggest you to put the source code of your Python scripts on the | |
61 dedicated `"OrthancContributed" repository on GitHub | |
62 <https://github.com/jodogne/OrthancContributed/tree/master/Plugins>`__, | |
984
46e2941b57dd
replace link to google users group by link to discourse
Alain Mazy <am@osimis.io>
parents:
978
diff
changeset
|
63 and/or to send it to the `Orthanc Users discussion forum |
46e2941b57dd
replace link to google users group by link to discourse
Alain Mazy <am@osimis.io>
parents:
978
diff
changeset
|
64 <https://discourse.orthanc-server.org>`__. |
353 | 65 |
66 Check out the :ref:`FAQ about licensing <licensing>` for more context. | |
67 | |
68 | |
364
234de55ed125
usage of the python plugin
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
354
diff
changeset
|
69 Usage |
234de55ed125
usage of the python plugin
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
354
diff
changeset
|
70 ----- |
234de55ed125
usage of the python plugin
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
354
diff
changeset
|
71 |
234de55ed125
usage of the python plugin
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
354
diff
changeset
|
72 Docker |
234de55ed125
usage of the python plugin
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
354
diff
changeset
|
73 ...... |
234de55ed125
usage of the python plugin
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
354
diff
changeset
|
74 |
697
7581dc208323
Handling DICOM SCP requests using a Python plugin
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
696
diff
changeset
|
75 .. highlight:: python |
364
234de55ed125
usage of the python plugin
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
354
diff
changeset
|
76 |
234de55ed125
usage of the python plugin
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
354
diff
changeset
|
77 The most direct way of starting Orthanc together with the Python |
234de55ed125
usage of the python plugin
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
354
diff
changeset
|
78 plugin is through :ref:`Docker <docker>`. Let's create the file |
234de55ed125
usage of the python plugin
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
354
diff
changeset
|
79 ``/tmp/hello.py`` that contains the following basic Python script:: |
234de55ed125
usage of the python plugin
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
354
diff
changeset
|
80 |
234de55ed125
usage of the python plugin
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
354
diff
changeset
|
81 print('Hello world!') |
234de55ed125
usage of the python plugin
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
354
diff
changeset
|
82 |
234de55ed125
usage of the python plugin
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
354
diff
changeset
|
83 .. highlight:: json |
234de55ed125
usage of the python plugin
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
354
diff
changeset
|
84 |
234de55ed125
usage of the python plugin
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
354
diff
changeset
|
85 Let's also create the file ``/tmp/orthanc.json`` that contains the |
234de55ed125
usage of the python plugin
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
354
diff
changeset
|
86 following minimal :ref:`configuration for Orthanc <configuration>`:: |
234de55ed125
usage of the python plugin
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
354
diff
changeset
|
87 |
234de55ed125
usage of the python plugin
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
354
diff
changeset
|
88 { |
234de55ed125
usage of the python plugin
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
354
diff
changeset
|
89 "StorageDirectory" : "/var/lib/orthanc/db", |
234de55ed125
usage of the python plugin
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
354
diff
changeset
|
90 "RemoteAccessAllowed" : true, |
234de55ed125
usage of the python plugin
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
354
diff
changeset
|
91 "Plugins" : [ |
234de55ed125
usage of the python plugin
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
354
diff
changeset
|
92 "/usr/local/share/orthanc/plugins" |
234de55ed125
usage of the python plugin
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
354
diff
changeset
|
93 ], |
234de55ed125
usage of the python plugin
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
354
diff
changeset
|
94 "PythonScript" : "/etc/orthanc/hello.py" |
234de55ed125
usage of the python plugin
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
354
diff
changeset
|
95 } |
234de55ed125
usage of the python plugin
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
354
diff
changeset
|
96 |
234de55ed125
usage of the python plugin
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
354
diff
changeset
|
97 .. highlight:: bash |
234de55ed125
usage of the python plugin
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
354
diff
changeset
|
98 |
234de55ed125
usage of the python plugin
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
354
diff
changeset
|
99 Given these two files, Orthanc can be started as follows:: |
234de55ed125
usage of the python plugin
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
354
diff
changeset
|
100 |
234de55ed125
usage of the python plugin
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
354
diff
changeset
|
101 $ docker run -p 4242:4242 -p 8042:8042 --rm \ |
234de55ed125
usage of the python plugin
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
354
diff
changeset
|
102 -v /tmp/orthanc.json:/etc/orthanc/orthanc.json:ro \ |
234de55ed125
usage of the python plugin
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
354
diff
changeset
|
103 -v /tmp/hello.py:/etc/orthanc/hello.py:ro \ |
234de55ed125
usage of the python plugin
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
354
diff
changeset
|
104 jodogne/orthanc-python |
234de55ed125
usage of the python plugin
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
354
diff
changeset
|
105 |
234de55ed125
usage of the python plugin
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
354
diff
changeset
|
106 .. highlight:: text |
234de55ed125
usage of the python plugin
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
354
diff
changeset
|
107 |
234de55ed125
usage of the python plugin
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
354
diff
changeset
|
108 You'll see the following excerpt in the log, which indicates that the Python plugin is properly loaded:: |
234de55ed125
usage of the python plugin
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
354
diff
changeset
|
109 |
234de55ed125
usage of the python plugin
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
354
diff
changeset
|
110 W0331 15:48:12.990661 PluginsManager.cpp:269] Registering plugin 'python' (version mainline) |
234de55ed125
usage of the python plugin
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
354
diff
changeset
|
111 W0331 15:48:12.990691 PluginsManager.cpp:168] Python plugin is initializing |
234de55ed125
usage of the python plugin
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
354
diff
changeset
|
112 W0331 15:48:12.990743 PluginsManager.cpp:168] Using Python script "hello.py" from directory: /etc/orthanc |
234de55ed125
usage of the python plugin
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
354
diff
changeset
|
113 W0331 15:48:12.990819 PluginsManager.cpp:168] Program name: /usr/local/sbin/Orthanc |
234de55ed125
usage of the python plugin
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
354
diff
changeset
|
114 Hello world! |
234de55ed125
usage of the python plugin
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
354
diff
changeset
|
115 |
234de55ed125
usage of the python plugin
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
354
diff
changeset
|
116 |
962 | 117 `Here <https://github.com/orthanc-server/orthanc-setup-samples/tree/master/docker/python/>`__ is a full example |
1023
5d4701d8fe28
replaced osimis/orthanc by orthancteam/orthanc
Alain Mazy <am@osimis.io>
parents:
1021
diff
changeset
|
118 of a more complex setup using the :ref:`orthancteam/orthanc <docker-orthancteam>` images. |
405 | 119 |
800 | 120 |
121 Microsoft Windows | |
122 ................. | |
123 | |
927 | 124 Pre-compiled binaries for Microsoft Windows are now part of the |
993
05b106383b2a
migration to UCLouvain servers
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
991
diff
changeset
|
125 `Windows installers <https://www.orthanc-server.com/download-windows.php>`__ |
927 | 126 but not installed by default. They are also `available here |
993
05b106383b2a
migration to UCLouvain servers
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
991
diff
changeset
|
127 <https://orthanc.uclouvain.be/downloads/windows-32/orthanc-python/index.html>`__. |
800 | 128 |
129 Beware that one version of the Python plugin can only be run against | |
130 one version of the Python interpreter. This version is clearly | |
131 indicated in the filename of the precompiled binaries. | |
132 | |
133 Pay also attention to pick the right 32/64 bits version. If you are | |
134 running Orthanc 64bits, install Python in 64bits and select the 64bits | |
135 Python plugin too. | |
136 | |
137 When you install Python on your Windows machine, make sure to install | |
138 Python for ``All Users`` and select the ``Add Python to Path`` option. | |
139 | |
364
234de55ed125
usage of the python plugin
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
354
diff
changeset
|
140 Compiling from source |
234de55ed125
usage of the python plugin
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
354
diff
changeset
|
141 ..................... |
234de55ed125
usage of the python plugin
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
354
diff
changeset
|
142 |
800 | 143 For GNU/Linux |
144 ^^^^^^^^^^^^^ | |
145 | |
364
234de55ed125
usage of the python plugin
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
354
diff
changeset
|
146 .. highlight:: bash |
234de55ed125
usage of the python plugin
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
354
diff
changeset
|
147 |
234de55ed125
usage of the python plugin
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
354
diff
changeset
|
148 The procedure to compile this plugin from source is similar to that |
234de55ed125
usage of the python plugin
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
354
diff
changeset
|
149 for the :ref:`core of Orthanc <compiling>`. The following commands |
234de55ed125
usage of the python plugin
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
354
diff
changeset
|
150 should work for most UNIX-like distribution (including GNU/Linux):: |
234de55ed125
usage of the python plugin
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
354
diff
changeset
|
151 |
234de55ed125
usage of the python plugin
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
354
diff
changeset
|
152 $ mkdir Build |
234de55ed125
usage of the python plugin
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
354
diff
changeset
|
153 $ cd Build |
234de55ed125
usage of the python plugin
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
354
diff
changeset
|
154 $ cmake .. -DPYTHON_VERSION=3.7 -DSTATIC_BUILD=ON -DCMAKE_BUILD_TYPE=Release |
234de55ed125
usage of the python plugin
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
354
diff
changeset
|
155 $ make |
234de55ed125
usage of the python plugin
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
354
diff
changeset
|
156 |
234de55ed125
usage of the python plugin
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
354
diff
changeset
|
157 Before running CMake, make sure that the Python interpreter and its |
234de55ed125
usage of the python plugin
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
354
diff
changeset
|
158 associated development library are installed. On Ubuntu 18.04 LTS, you |
234de55ed125
usage of the python plugin
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
354
diff
changeset
|
159 would for instance install packages ``libpython3.7-dev`` and |
234de55ed125
usage of the python plugin
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
354
diff
changeset
|
160 ``python3.7``. |
234de55ed125
usage of the python plugin
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
354
diff
changeset
|
161 |
234de55ed125
usage of the python plugin
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
354
diff
changeset
|
162 The compilation will produce the shared library ``OrthancPython``, |
234de55ed125
usage of the python plugin
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
354
diff
changeset
|
163 that can be loaded by properly setting the ``Plugins`` |
234de55ed125
usage of the python plugin
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
354
diff
changeset
|
164 :ref:`configuration option <configuration>` of Orthanc. |
234de55ed125
usage of the python plugin
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
354
diff
changeset
|
165 |
234de55ed125
usage of the python plugin
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
354
diff
changeset
|
166 **Warning:** The shared library is only compatible with the Python |
234de55ed125
usage of the python plugin
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
354
diff
changeset
|
167 interpreter whose version corresponds to the value of the |
234de55ed125
usage of the python plugin
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
354
diff
changeset
|
168 ``PYTHON_VERSION`` argument that was given to CMake. |
501
98592b9e7ad5
force version of python on os x
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
490
diff
changeset
|
169 |
98592b9e7ad5
force version of python on os x
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
490
diff
changeset
|
170 **Note for OS X:** As indicated by `Stephen Douglas Scotti |
98592b9e7ad5
force version of python on os x
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
490
diff
changeset
|
171 <https://groups.google.com/g/orthanc-users/c/RnmZKFv8FaY/m/HhvOD2A2CAAJ>`__, |
98592b9e7ad5
force version of python on os x
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
490
diff
changeset
|
172 here is a sample invocation of CMake to force the version of Python to |
98592b9e7ad5
force version of python on os x
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
490
diff
changeset
|
173 be used on OS X:: |
98592b9e7ad5
force version of python on os x
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
490
diff
changeset
|
174 |
98592b9e7ad5
force version of python on os x
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
490
diff
changeset
|
175 $ cmake .. -DPYTHON_VERSION=3.8 -DSTATIC_BUILD=ON -DCMAKE_BUILD_TYPE=Release \ |
98592b9e7ad5
force version of python on os x
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
490
diff
changeset
|
176 -DPYTHON_LIBRARY=/usr/local/Cellar/python@3.8/3.8.5/Frameworks/Python.framework/Versions/3.8/lib/libpython3.8.dylib \ |
98592b9e7ad5
force version of python on os x
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
490
diff
changeset
|
177 -DPYTHON_INCLUDE_DIR=/usr/local/Cellar/python@3.8/3.8.5/Frameworks/Python.framework/Versions/3.8/include/python3.8/ |
98592b9e7ad5
force version of python on os x
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
490
diff
changeset
|
178 |
364
234de55ed125
usage of the python plugin
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
354
diff
changeset
|
179 |
800 | 180 For Microsoft Windows |
181 ^^^^^^^^^^^^^^^^^^^^^ | |
364
234de55ed125
usage of the python plugin
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
354
diff
changeset
|
182 |
234de55ed125
usage of the python plugin
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
354
diff
changeset
|
183 .. highlight:: text |
234de55ed125
usage of the python plugin
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
354
diff
changeset
|
184 |
442
8b2c648c0f46
clarifications about windows precompiled binaries
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
405
diff
changeset
|
185 You are of course free to compile the plugin from sources. You'll have |
8b2c648c0f46
clarifications about windows precompiled binaries
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
405
diff
changeset
|
186 to explicitly specify the path to your Python installation while |
8b2c648c0f46
clarifications about windows precompiled binaries
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
405
diff
changeset
|
187 invoking CMake. For instance:: |
364
234de55ed125
usage of the python plugin
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
354
diff
changeset
|
188 |
800 | 189 C:\orthanc-python\Build> cmake .. -DPYTHON_VERSION=3.8 -DPYTHON_WINDOWS_ROOT=C:/Python38 \ |
364
234de55ed125
usage of the python plugin
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
354
diff
changeset
|
190 -DSTATIC_BUILD=ON -DCMAKE_BUILD_TYPE=Release -G "Visual Studio 15 2017" |
234de55ed125
usage of the python plugin
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
354
diff
changeset
|
191 |
442
8b2c648c0f46
clarifications about windows precompiled binaries
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
405
diff
changeset
|
192 **Note about debug builds**: Usually, building Python modules such as the Python |
377
ffe62e6c086f
Added a note about the debug libraries when building under Windows with Visual Studio.
Benjamin Golinvaux <bgo@osimis.io>
parents:
375
diff
changeset
|
193 plugin for Orthanc in debug mode (where ``_DEBUG`` is defined) leads to a module |
442
8b2c648c0f46
clarifications about windows precompiled binaries
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
405
diff
changeset
|
194 (``.exe`` or ``.dll``) that requires a debug build of Python, and debug versions of all |
377
ffe62e6c086f
Added a note about the debug libraries when building under Windows with Visual Studio.
Benjamin Golinvaux <bgo@osimis.io>
parents:
375
diff
changeset
|
195 the Python libraries. This is quite cumbersome, for it requires building Python |
ffe62e6c086f
Added a note about the debug libraries when building under Windows with Visual Studio.
Benjamin Golinvaux <bgo@osimis.io>
parents:
375
diff
changeset
|
196 on your own or downloading additional debug files. |
ffe62e6c086f
Added a note about the debug libraries when building under Windows with Visual Studio.
Benjamin Golinvaux <bgo@osimis.io>
parents:
375
diff
changeset
|
197 |
ffe62e6c086f
Added a note about the debug libraries when building under Windows with Visual Studio.
Benjamin Golinvaux <bgo@osimis.io>
parents:
375
diff
changeset
|
198 Since using a debug build of Python is only necessary in very specific cases |
ffe62e6c086f
Added a note about the debug libraries when building under Windows with Visual Studio.
Benjamin Golinvaux <bgo@osimis.io>
parents:
375
diff
changeset
|
199 (such as the debugging of code at the boundary between Python and an extension), |
ffe62e6c086f
Added a note about the debug libraries when building under Windows with Visual Studio.
Benjamin Golinvaux <bgo@osimis.io>
parents:
375
diff
changeset
|
200 we have changed the default behavior to use the release Python library by default. |
ffe62e6c086f
Added a note about the debug libraries when building under Windows with Visual Studio.
Benjamin Golinvaux <bgo@osimis.io>
parents:
375
diff
changeset
|
201 |
ffe62e6c086f
Added a note about the debug libraries when building under Windows with Visual Studio.
Benjamin Golinvaux <bgo@osimis.io>
parents:
375
diff
changeset
|
202 This means that you are able to build this plugin in debug mode with the |
ffe62e6c086f
Added a note about the debug libraries when building under Windows with Visual Studio.
Benjamin Golinvaux <bgo@osimis.io>
parents:
375
diff
changeset
|
203 standard Python distribution. |
ffe62e6c086f
Added a note about the debug libraries when building under Windows with Visual Studio.
Benjamin Golinvaux <bgo@osimis.io>
parents:
375
diff
changeset
|
204 |
ffe62e6c086f
Added a note about the debug libraries when building under Windows with Visual Studio.
Benjamin Golinvaux <bgo@osimis.io>
parents:
375
diff
changeset
|
205 In case you need to use the Python debug libraries, you can instruct the build |
ffe62e6c086f
Added a note about the debug libraries when building under Windows with Visual Studio.
Benjamin Golinvaux <bgo@osimis.io>
parents:
375
diff
changeset
|
206 system to do so by setting the ``PYTHON_WINDOWS_USE_RELEASE_LIBS`` CMake option, |
ffe62e6c086f
Added a note about the debug libraries when building under Windows with Visual Studio.
Benjamin Golinvaux <bgo@osimis.io>
parents:
375
diff
changeset
|
207 that is ``ON`` by default, to ``OFF``. The previous build example would then be, |
ffe62e6c086f
Added a note about the debug libraries when building under Windows with Visual Studio.
Benjamin Golinvaux <bgo@osimis.io>
parents:
375
diff
changeset
|
208 should you require a full debug build:: |
ffe62e6c086f
Added a note about the debug libraries when building under Windows with Visual Studio.
Benjamin Golinvaux <bgo@osimis.io>
parents:
375
diff
changeset
|
209 |
800 | 210 C:\orthanc-python\Build> cmake .. -DPYTHON_VERSION=3.8 -DPYTHON_WINDOWS_ROOT=C:/Python38 \ |
377
ffe62e6c086f
Added a note about the debug libraries when building under Windows with Visual Studio.
Benjamin Golinvaux <bgo@osimis.io>
parents:
375
diff
changeset
|
211 -DSTATIC_BUILD=ON -DPYTHON_WINDOWS_USE_RELEASE_LIBS=OFF \ |
ffe62e6c086f
Added a note about the debug libraries when building under Windows with Visual Studio.
Benjamin Golinvaux <bgo@osimis.io>
parents:
375
diff
changeset
|
212 -DCMAKE_BUILD_TYPE=Debug -G "Visual Studio 15 2017" |
ffe62e6c086f
Added a note about the debug libraries when building under Windows with Visual Studio.
Benjamin Golinvaux <bgo@osimis.io>
parents:
375
diff
changeset
|
213 |
ffe62e6c086f
Added a note about the debug libraries when building under Windows with Visual Studio.
Benjamin Golinvaux <bgo@osimis.io>
parents:
375
diff
changeset
|
214 Please note that this CMake option only impacts **debug** builds under Windows, |
ffe62e6c086f
Added a note about the debug libraries when building under Windows with Visual Studio.
Benjamin Golinvaux <bgo@osimis.io>
parents:
375
diff
changeset
|
215 when using (any version of) the Microsoft Visual Studio compiler. |
364
234de55ed125
usage of the python plugin
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
354
diff
changeset
|
216 |
442
8b2c648c0f46
clarifications about windows precompiled binaries
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
405
diff
changeset
|
217 The precompiled binaries all use release (i.e. non-debug) versions of Python. |
8b2c648c0f46
clarifications about windows precompiled binaries
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
405
diff
changeset
|
218 |
8b2c648c0f46
clarifications about windows precompiled binaries
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
405
diff
changeset
|
219 |
364
234de55ed125
usage of the python plugin
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
354
diff
changeset
|
220 Configuration options |
234de55ed125
usage of the python plugin
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
354
diff
changeset
|
221 --------------------- |
234de55ed125
usage of the python plugin
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
354
diff
changeset
|
222 |
978
e7a3b3d76f1c
documentation of new options in Python plugin 4.1
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
975
diff
changeset
|
223 The two main configuration options that are available for this plugin |
364
234de55ed125
usage of the python plugin
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
354
diff
changeset
|
224 are the following: |
234de55ed125
usage of the python plugin
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
354
diff
changeset
|
225 |
234de55ed125
usage of the python plugin
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
354
diff
changeset
|
226 * ``PythonScript`` indicates where the Python script is located. If |
234de55ed125
usage of the python plugin
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
354
diff
changeset
|
227 this configuration option is not provided, the Python plugin is not |
234de55ed125
usage of the python plugin
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
354
diff
changeset
|
228 started. |
234de55ed125
usage of the python plugin
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
354
diff
changeset
|
229 |
234de55ed125
usage of the python plugin
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
354
diff
changeset
|
230 * ``PythonVerbose`` is a Boolean value to make the Python interpreter |
234de55ed125
usage of the python plugin
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
354
diff
changeset
|
231 verbose. |
978
e7a3b3d76f1c
documentation of new options in Python plugin 4.1
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
975
diff
changeset
|
232 |
e7a3b3d76f1c
documentation of new options in Python plugin 4.1
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
975
diff
changeset
|
233 Consequently, a minimal :ref:`configuration file <configuration>` for |
e7a3b3d76f1c
documentation of new options in Python plugin 4.1
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
975
diff
changeset
|
234 Orthanc could be:: |
e7a3b3d76f1c
documentation of new options in Python plugin 4.1
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
975
diff
changeset
|
235 |
e7a3b3d76f1c
documentation of new options in Python plugin 4.1
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
975
diff
changeset
|
236 { |
e7a3b3d76f1c
documentation of new options in Python plugin 4.1
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
975
diff
changeset
|
237 "Plugins" : [ "." ], |
e7a3b3d76f1c
documentation of new options in Python plugin 4.1
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
975
diff
changeset
|
238 "PythonScript" : "my-plugin.py", |
e7a3b3d76f1c
documentation of new options in Python plugin 4.1
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
975
diff
changeset
|
239 "PythonVerbose" : false |
e7a3b3d76f1c
documentation of new options in Python plugin 4.1
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
975
diff
changeset
|
240 } |
e7a3b3d76f1c
documentation of new options in Python plugin 4.1
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
975
diff
changeset
|
241 |
e7a3b3d76f1c
documentation of new options in Python plugin 4.1
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
975
diff
changeset
|
242 Starting with release 4.1 of the Python plugin, it is also possible to |
e7a3b3d76f1c
documentation of new options in Python plugin 4.1
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
975
diff
changeset
|
243 specify the configuration of the plugin in a dedicated ``Python`` |
e7a3b3d76f1c
documentation of new options in Python plugin 4.1
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
975
diff
changeset
|
244 section as follows:: |
e7a3b3d76f1c
documentation of new options in Python plugin 4.1
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
975
diff
changeset
|
245 |
e7a3b3d76f1c
documentation of new options in Python plugin 4.1
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
975
diff
changeset
|
246 { |
e7a3b3d76f1c
documentation of new options in Python plugin 4.1
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
975
diff
changeset
|
247 "Plugins" : [ "." ], |
e7a3b3d76f1c
documentation of new options in Python plugin 4.1
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
975
diff
changeset
|
248 "Python" : { |
e7a3b3d76f1c
documentation of new options in Python plugin 4.1
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
975
diff
changeset
|
249 "Path" : "my-plugin.py", // Alias for the global "PythonScript" option |
e7a3b3d76f1c
documentation of new options in Python plugin 4.1
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
975
diff
changeset
|
250 "Verbose" : false, // Alias for the global "PythonVerbose" option |
1090 | 251 "DisplayMemoryUsage" : false, |
252 "AllowThreads" : false | |
978
e7a3b3d76f1c
documentation of new options in Python plugin 4.1
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
975
diff
changeset
|
253 } |
e7a3b3d76f1c
documentation of new options in Python plugin 4.1
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
975
diff
changeset
|
254 } |
e7a3b3d76f1c
documentation of new options in Python plugin 4.1
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
975
diff
changeset
|
255 |
e7a3b3d76f1c
documentation of new options in Python plugin 4.1
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
975
diff
changeset
|
256 The option ``Python.DisplayMemoryUsage`` was introduced in release 4.1 |
e7a3b3d76f1c
documentation of new options in Python plugin 4.1
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
975
diff
changeset
|
257 of the plugin. If set to ``true``, Orthanc will display the memory |
e7a3b3d76f1c
documentation of new options in Python plugin 4.1
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
975
diff
changeset
|
258 usage of the Python interpreter every second. |
364
234de55ed125
usage of the python plugin
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
354
diff
changeset
|
259 |
1090 | 260 The option ``Python.AllowThreads`` was introduced in release 4.3 of |
261 the plugin. If set to ``true``, the Python GIL (`Global Interpreter | |
262 Lock <https://en.wikipedia.org/wiki/Global_interpreter_lock>`__) is | |
263 released during the calls to the native SDK. **This allows multiple | |
1091 | 264 Python threads to simultaneously access the Orthanc core.** |
265 Internally, this corresponds to the ``Py_BEGIN_ALLOW_THREADS`` | |
266 `construction of Python | |
267 <https://docs.python.org/3/c-api/init.html#releasing-the-gil-from-extension-code>`__. However, | |
268 this could possibly introduce concurrency issues: Make sure that your | |
269 Python code is **thread-safe** before enabling this option! Indeed, | |
270 different threads must not modify the Python objects that are used | |
271 during a call to the SDK of Orthanc. | |
1090 | 272 |
343
fff45618262d
creating the documentation of the Python plugin
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
273 |
1041 | 274 .. warning:: |
275 Never call your Python plugin ``orthanc.py``! Otherwise, your plugin will | |
276 conflict with the ``orthanc`` module that is installed at runtime. | |
277 | |
278 | |
1090 | 279 .. _python-code-completion: |
280 | |
281 Documentation and code completion | |
282 --------------------------------- | |
283 | |
284 Starting with release 4.3 of the Python plugin for Orthanc, a `Python | |
285 interface (cf. PEP 484 - Type Hints) | |
286 <https://peps.python.org/pep-0484/>`__ is available. By downloading | |
287 the file ``orthanc.pyi`` `from this location | |
288 <https://orthanc.uclouvain.be/downloads/cross-platform/orthanc-python/index.html>`__ | |
289 and putting it in the same folder as your Python script, your IDE will | |
290 provide you code completion, as well as full documentation of the | |
291 Orthanc SDK in the Python language. This file is notably known to work | |
292 with Visual Studio Code and PyCharm. | |
293 | |
294 | |
295 | |
343
fff45618262d
creating the documentation of the Python plugin
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
296 Samples |
fff45618262d
creating the documentation of the Python plugin
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
297 ------- |
fff45618262d
creating the documentation of the Python plugin
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
298 |
fff45618262d
creating the documentation of the Python plugin
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
299 Extending the REST API |
fff45618262d
creating the documentation of the Python plugin
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
300 ...................... |
fff45618262d
creating the documentation of the Python plugin
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
301 |
fff45618262d
creating the documentation of the Python plugin
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
302 Here is a basic Python script that registers two new routes in the |
703
a589668768d7
moving python samples in separate files (2)
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
702
diff
changeset
|
303 REST API: |
343
fff45618262d
creating the documentation of the Python plugin
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
304 |
703
a589668768d7
moving python samples in separate files (2)
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
702
diff
changeset
|
305 .. literalinclude:: python/extending-rest-api.py |
a589668768d7
moving python samples in separate files (2)
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
702
diff
changeset
|
306 :language: python |
343
fff45618262d
creating the documentation of the Python plugin
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
307 |
fff45618262d
creating the documentation of the Python plugin
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
308 .. highlight:: json |
fff45618262d
creating the documentation of the Python plugin
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
309 |
fff45618262d
creating the documentation of the Python plugin
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
310 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
|
311 (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
|
312 |
fff45618262d
creating the documentation of the Python plugin
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
313 { |
fff45618262d
creating the documentation of the Python plugin
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
314 "Plugins" : [ "." ], |
fff45618262d
creating the documentation of the Python plugin
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
315 "PythonScript" : "rest.py", |
fff45618262d
creating the documentation of the Python plugin
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
316 "PythonVerbose" : false |
fff45618262d
creating the documentation of the Python plugin
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
317 } |
fff45618262d
creating the documentation of the Python plugin
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
318 |
fff45618262d
creating the documentation of the Python plugin
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
319 .. highlight:: bash |
fff45618262d
creating the documentation of the Python plugin
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
320 |
fff45618262d
creating the documentation of the Python plugin
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
321 The route can then be accessed as:: |
fff45618262d
creating the documentation of the Python plugin
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
322 |
fff45618262d
creating the documentation of the Python plugin
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
323 $ curl http://localhost:8042/toto |
fff45618262d
creating the documentation of the Python plugin
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
324 ok |
fff45618262d
creating the documentation of the Python plugin
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
diff
changeset
|
325 |
469
46949efa5818
Implementing basic paging using a Python script
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
462
diff
changeset
|
326 |
1013 | 327 Overriding the core REST API |
328 ............................ | |
329 | |
330 You may also use a python plugin to replace an existing REST API route: | |
331 | |
332 .. literalinclude:: python/extending-rest-api-2.py | |
333 :language: python | |
334 | |
335 | |
336 | |
337 When calling the REST API from a python plugin, you may use e.g. | |
338 ``RestApiPost`` to call the native Orthanc REST API and must | |
339 call ``RestApiPostAfterPlugin`` to call the REST API from plugins. | |
340 | |
341 | |
1075 | 342 Note however, that, as of Orthanc 1.12.4, the Orthanc plugin SDK |
1013 | 343 does not support multiple plugins implementing the same route. |
344 Orthanc will actually accept e.g a Python plugin that overrides | |
345 a DICOMWeb route but it is impossible to tell which route | |
346 will be called in the end since this depends on the registration | |
347 order of the plugins that is not deterministic. | |
348 | |
349 | |
350 | |
351 | |
469
46949efa5818
Implementing basic paging using a Python script
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
462
diff
changeset
|
352 .. _python-changes: |
345 | 353 |
354 Listening to changes | |
355 .................... | |
356 | |
703
a589668768d7
moving python samples in separate files (2)
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
702
diff
changeset
|
357 This sample uploads a DICOM file as soon as Orthanc is started: |
345 | 358 |
703
a589668768d7
moving python samples in separate files (2)
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
702
diff
changeset
|
359 .. literalinclude:: python/listening-changes.py |
a589668768d7
moving python samples in separate files (2)
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
702
diff
changeset
|
360 :language: python |
345 | 361 |
590
404aca6160f0
warning about deadlock in python
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
568
diff
changeset
|
362 |
404aca6160f0
warning about deadlock in python
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
568
diff
changeset
|
363 .. warning:: |
600
4038ae299b18
note about deadlocks in python plugins
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
591
diff
changeset
|
364 In releases <= 3.0 of the Python plugin, deadlocks might emerge if |
4038ae299b18
note about deadlocks in python plugins
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
591
diff
changeset
|
365 you call other core primitives of Orthanc (such as the REST API) in |
4038ae299b18
note about deadlocks in python plugins
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
591
diff
changeset
|
366 your callback function. This issue has been `fixed in release 3.1 |
991
1316bc62b5d5
migration to UCLouvain servers
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
984
diff
changeset
|
367 <https://orthanc.uclouvain.be/hg/orthanc-python/rev/46fe70776d61>`__. |
590
404aca6160f0
warning about deadlock in python
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
568
diff
changeset
|
368 |
600
4038ae299b18
note about deadlocks in python plugins
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
591
diff
changeset
|
369 As a **temporary workaround** against such deadlocks in releases <= |
4038ae299b18
note about deadlocks in python plugins
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
591
diff
changeset
|
370 3.0, if you have to call other primitives of Orthanc, you should make |
4038ae299b18
note about deadlocks in python plugins
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
591
diff
changeset
|
371 these calls in a separate thread, passing the pending events to be |
4038ae299b18
note about deadlocks in python plugins
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
591
diff
changeset
|
372 processed through a message queue. Here is the template of a possible |
4038ae299b18
note about deadlocks in python plugins
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
591
diff
changeset
|
373 solution to postpone such deadlocks as much as possible by relying on |
703
a589668768d7
moving python samples in separate files (2)
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
702
diff
changeset
|
374 the multithreading primitives of Python: |
591
2397b0e12bc8
solution to avoid deadlock in Python OnChange()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
590
diff
changeset
|
375 |
703
a589668768d7
moving python samples in separate files (2)
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
702
diff
changeset
|
376 .. literalinclude:: python/changes-deadlock-3.0.py |
a589668768d7
moving python samples in separate files (2)
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
702
diff
changeset
|
377 :language: python |
600
4038ae299b18
note about deadlocks in python plugins
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
591
diff
changeset
|
378 |
4038ae299b18
note about deadlocks in python plugins
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
591
diff
changeset
|
379 Beware that **this workaround is imperfect** and deadlocks have been |
4038ae299b18
note about deadlocks in python plugins
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
591
diff
changeset
|
380 observed even if using it! Make sure to upgrade your plugin to solve |
4038ae299b18
note about deadlocks in python plugins
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
591
diff
changeset
|
381 this issue for good. Note that this temporary workaround is not needed |
4038ae299b18
note about deadlocks in python plugins
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
591
diff
changeset
|
382 in releases >= 3.1 of the plugin. |
4038ae299b18
note about deadlocks in python plugins
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
591
diff
changeset
|
383 |
591
2397b0e12bc8
solution to avoid deadlock in Python OnChange()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
590
diff
changeset
|
384 |
590
404aca6160f0
warning about deadlock in python
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
568
diff
changeset
|
385 |
345 | 386 Accessing the content of a new instance |
346
bdf8757449e3
more python samples
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
345
diff
changeset
|
387 ....................................... |
bdf8757449e3
more python samples
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
345
diff
changeset
|
388 |
703
a589668768d7
moving python samples in separate files (2)
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
702
diff
changeset
|
389 .. literalinclude:: python/accessing-new-instance.py |
a589668768d7
moving python samples in separate files (2)
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
702
diff
changeset
|
390 :language: python |
346
bdf8757449e3
more python samples
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
345
diff
changeset
|
391 |
590
404aca6160f0
warning about deadlock in python
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
568
diff
changeset
|
392 .. warning:: |
404aca6160f0
warning about deadlock in python
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
568
diff
changeset
|
393 Your callback function will be called synchronously with |
404aca6160f0
warning about deadlock in python
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
568
diff
changeset
|
394 the core of Orthanc. This implies that deadlocks might emerge if |
404aca6160f0
warning about deadlock in python
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
568
diff
changeset
|
395 you call other core primitives of Orthanc in your callback (such |
404aca6160f0
warning about deadlock in python
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
568
diff
changeset
|
396 deadlocks are particular visible in the presence of other plugins |
404aca6160f0
warning about deadlock in python
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
568
diff
changeset
|
397 or Lua scripts). It is thus strongly advised to avoid any call to |
404aca6160f0
warning about deadlock in python
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
568
diff
changeset
|
398 the REST API of Orthanc in the callback. If you have to call other |
404aca6160f0
warning about deadlock in python
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
568
diff
changeset
|
399 primitives of Orthanc, you should make these calls in a separate |
404aca6160f0
warning about deadlock in python
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
568
diff
changeset
|
400 thread, passing the pending events to be processed through a |
404aca6160f0
warning about deadlock in python
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
568
diff
changeset
|
401 message queue. |
404aca6160f0
warning about deadlock in python
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
568
diff
changeset
|
402 |
404aca6160f0
warning about deadlock in python
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
568
diff
changeset
|
403 |
346
bdf8757449e3
more python samples
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
345
diff
changeset
|
404 Calling pydicom |
bdf8757449e3
more python samples
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
345
diff
changeset
|
405 ............... |
bdf8757449e3
more python samples
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
345
diff
changeset
|
406 |
bdf8757449e3
more python samples
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
345
diff
changeset
|
407 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
|
408 the content of the dataset of one given DICOM instance stored in |
703
a589668768d7
moving python samples in separate files (2)
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
702
diff
changeset
|
409 Orthanc, using `pydicom <https://pydicom.github.io/>`__: |
346
bdf8757449e3
more python samples
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
345
diff
changeset
|
410 |
703
a589668768d7
moving python samples in separate files (2)
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
702
diff
changeset
|
411 .. literalinclude:: python/pydicom.py |
a589668768d7
moving python samples in separate files (2)
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
702
diff
changeset
|
412 :language: python |
346
bdf8757449e3
more python samples
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
345
diff
changeset
|
413 |
bdf8757449e3
more python samples
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
345
diff
changeset
|
414 .. highlight:: bash |
bdf8757449e3
more python samples
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
345
diff
changeset
|
415 |
703
a589668768d7
moving python samples in separate files (2)
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
702
diff
changeset
|
416 This callback can be called as follows:: |
346
bdf8757449e3
more python samples
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
345
diff
changeset
|
417 |
bdf8757449e3
more python samples
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
345
diff
changeset
|
418 $ curl http://localhost:8042/pydicom/19816330-cb02e1cf-df3a8fe8-bf510623-ccefe9f5 |
bdf8757449e3
more python samples
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
345
diff
changeset
|
419 |
347 | 420 |
421 Auto-routing studies | |
422 .................... | |
423 | |
424 Here is a sample Python plugin that routes any :ref:`stable study | |
642
a76d83a00c68
definition of stable resources
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
638
diff
changeset
|
425 <stable-resources>` to a modality named ``samples`` (as declared in the |
703
a589668768d7
moving python samples in separate files (2)
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
702
diff
changeset
|
426 ``DicomModalities`` configuration option): |
347 | 427 |
703
a589668768d7
moving python samples in separate files (2)
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
702
diff
changeset
|
428 .. literalinclude:: python/autorouting-1.py |
a589668768d7
moving python samples in separate files (2)
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
702
diff
changeset
|
429 :language: python |
348 | 430 |
539 | 431 Note that, if you want to use an orthanc plugin to transfer the study, |
703
a589668768d7
moving python samples in separate files (2)
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
702
diff
changeset
|
432 you should use the ``RestApiPostAfterPlugins()`` method: |
539 | 433 |
703
a589668768d7
moving python samples in separate files (2)
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
702
diff
changeset
|
434 .. literalinclude:: python/autorouting-2.py |
a589668768d7
moving python samples in separate files (2)
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
702
diff
changeset
|
435 :language: python |
a589668768d7
moving python samples in separate files (2)
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
702
diff
changeset
|
436 |
539 | 437 |
1046 | 438 .. _python-pil-thumbnail: |
439 | |
352 | 440 Rendering a thumbnail using PIL/Pillow |
441 ...................................... | |
348 | 442 |
703
a589668768d7
moving python samples in separate files (2)
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
702
diff
changeset
|
443 .. literalinclude:: python/pil.py |
a589668768d7
moving python samples in separate files (2)
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
702
diff
changeset
|
444 :language: python |
351 | 445 |
446 | |
369
181b02cea7ab
inspecting Python API
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
364
diff
changeset
|
447 .. _python-introspection: |
181b02cea7ab
inspecting Python API
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
364
diff
changeset
|
448 |
181b02cea7ab
inspecting Python API
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
364
diff
changeset
|
449 Inspecting the available API |
181b02cea7ab
inspecting Python API
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
364
diff
changeset
|
450 ............................ |
181b02cea7ab
inspecting Python API
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
364
diff
changeset
|
451 |
181b02cea7ab
inspecting Python API
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
364
diff
changeset
|
452 Thanks to Python's introspection primitives, it is possible to inspect |
181b02cea7ab
inspecting Python API
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
364
diff
changeset
|
453 the API of the ``orthanc`` module in order to dump all the available |
703
a589668768d7
moving python samples in separate files (2)
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
702
diff
changeset
|
454 features: |
369
181b02cea7ab
inspecting Python API
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
364
diff
changeset
|
455 |
703
a589668768d7
moving python samples in separate files (2)
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
702
diff
changeset
|
456 .. literalinclude:: python/inspect-api.py |
a589668768d7
moving python samples in separate files (2)
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
702
diff
changeset
|
457 :language: python |
369
181b02cea7ab
inspecting Python API
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
364
diff
changeset
|
458 |
703
a589668768d7
moving python samples in separate files (2)
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
702
diff
changeset
|
459 |
373
847996394688
Scheduling a task for periodic execution
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
369
diff
changeset
|
460 .. _python-scheduler: |
847996394688
Scheduling a task for periodic execution
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
369
diff
changeset
|
461 |
847996394688
Scheduling a task for periodic execution
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
369
diff
changeset
|
462 Scheduling a task for periodic execution |
847996394688
Scheduling a task for periodic execution
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
369
diff
changeset
|
463 ........................................ |
847996394688
Scheduling a task for periodic execution
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
369
diff
changeset
|
464 |
847996394688
Scheduling a task for periodic execution
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
369
diff
changeset
|
465 The following Python script will periodically (every second) run the |
704
ba2403ebd4b7
moving python samples in separate files (3)
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
703
diff
changeset
|
466 function ``Hello()`` thanks to the ``threading`` module: |
373
847996394688
Scheduling a task for periodic execution
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
369
diff
changeset
|
467 |
704
ba2403ebd4b7
moving python samples in separate files (3)
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
703
diff
changeset
|
468 .. literalinclude:: python/periodic-execution.py |
ba2403ebd4b7
moving python samples in separate files (3)
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
703
diff
changeset
|
469 :language: python |
373
847996394688
Scheduling a task for periodic execution
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
369
diff
changeset
|
470 |
378
16dc3561b41e
Filtering and returning metadata using Python
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
375
diff
changeset
|
471 |
16dc3561b41e
Filtering and returning metadata using Python
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
375
diff
changeset
|
472 .. _python-metadata: |
16dc3561b41e
Filtering and returning metadata using Python
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
375
diff
changeset
|
473 |
16dc3561b41e
Filtering and returning metadata using Python
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
375
diff
changeset
|
474 Filtering and returning metadata |
16dc3561b41e
Filtering and returning metadata using Python
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
375
diff
changeset
|
475 ................................ |
16dc3561b41e
Filtering and returning metadata using Python
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
375
diff
changeset
|
476 |
16dc3561b41e
Filtering and returning metadata using Python
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
375
diff
changeset
|
477 Besides the main DICOM tags, Orthanc associates some metadata to each |
16dc3561b41e
Filtering and returning metadata using Python
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
375
diff
changeset
|
478 resource it stores (this includes the date of last update, the |
16dc3561b41e
Filtering and returning metadata using Python
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
375
diff
changeset
|
479 transfer syntax, the remote AET...). People are often interested in |
16dc3561b41e
Filtering and returning metadata using Python
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
375
diff
changeset
|
480 getting such metadata while calling the ``/tools/find`` route in the |
16dc3561b41e
Filtering and returning metadata using Python
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
375
diff
changeset
|
481 :ref:`REST API <rest-find>`, or even in filtering this metadata the |
16dc3561b41e
Filtering and returning metadata using Python
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
375
diff
changeset
|
482 same way they look for DICOM tags. |
16dc3561b41e
Filtering and returning metadata using Python
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
375
diff
changeset
|
483 |
16dc3561b41e
Filtering and returning metadata using Python
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
375
diff
changeset
|
484 This feature is not built in the core of Orthanc, as metadata is not |
16dc3561b41e
Filtering and returning metadata using Python
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
375
diff
changeset
|
485 indexed in the Orthanc database, contrarily to the main DICOM |
16dc3561b41e
Filtering and returning metadata using Python
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
375
diff
changeset
|
486 tags. Filtering metadata requires a linear search over all the |
16dc3561b41e
Filtering and returning metadata using Python
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
375
diff
changeset
|
487 matching resources, which induces a cost in the performance. |
16dc3561b41e
Filtering and returning metadata using Python
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
375
diff
changeset
|
488 |
16dc3561b41e
Filtering and returning metadata using Python
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
375
diff
changeset
|
489 Nevertheless, here is a full sample Python script that overwrites the |
704
ba2403ebd4b7
moving python samples in separate files (3)
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
703
diff
changeset
|
490 ``/tools/find`` route in order to give access to metadata: |
378
16dc3561b41e
Filtering and returning metadata using Python
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
375
diff
changeset
|
491 |
704
ba2403ebd4b7
moving python samples in separate files (3)
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
703
diff
changeset
|
492 .. literalinclude:: python/filtering-metadata.py |
ba2403ebd4b7
moving python samples in separate files (3)
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
703
diff
changeset
|
493 :language: python |
378
16dc3561b41e
Filtering and returning metadata using Python
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
375
diff
changeset
|
494 |
16dc3561b41e
Filtering and returning metadata using Python
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
375
diff
changeset
|
495 |
16dc3561b41e
Filtering and returning metadata using Python
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
375
diff
changeset
|
496 **Warning:** In the sample above, the filtering of the metadata is |
16dc3561b41e
Filtering and returning metadata using Python
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
375
diff
changeset
|
497 done using Python's `library for regular expressions |
16dc3561b41e
Filtering and returning metadata using Python
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
375
diff
changeset
|
498 <https://docs.python.org/3/library/re.html>`__. It is evidently |
16dc3561b41e
Filtering and returning metadata using Python
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
375
diff
changeset
|
499 possible to adapt this script in order to use the DICOM conventions |
16dc3561b41e
Filtering and returning metadata using Python
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
375
diff
changeset
|
500 about `attribute matching |
16dc3561b41e
Filtering and returning metadata using Python
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
375
diff
changeset
|
501 <http://dicom.nema.org/medical/dicom/2019e/output/chtml/part04/sect_C.2.2.2.html>`__. |
16dc3561b41e
Filtering and returning metadata using Python
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
375
diff
changeset
|
502 |
469
46949efa5818
Implementing basic paging using a Python script
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
462
diff
changeset
|
503 .. highlight:: bash |
378
16dc3561b41e
Filtering and returning metadata using Python
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
375
diff
changeset
|
504 |
16dc3561b41e
Filtering and returning metadata using Python
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
375
diff
changeset
|
505 Here is a sample call to retrieve all the studies that were last |
16dc3561b41e
Filtering and returning metadata using Python
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
375
diff
changeset
|
506 updated in 2019 thanks to this Python script:: |
16dc3561b41e
Filtering and returning metadata using Python
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
375
diff
changeset
|
507 |
16dc3561b41e
Filtering and returning metadata using Python
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
375
diff
changeset
|
508 $ curl http://localhost:8042/tools/find -d '{"Level":"Study","Query":{},"Expand":true,"Metadata":{"LastUpdate":"^2019.*$"}}' |
369
181b02cea7ab
inspecting Python API
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
364
diff
changeset
|
509 |
181b02cea7ab
inspecting Python API
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
364
diff
changeset
|
510 |
469
46949efa5818
Implementing basic paging using a Python script
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
462
diff
changeset
|
511 .. _python-paging: |
46949efa5818
Implementing basic paging using a Python script
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
462
diff
changeset
|
512 |
46949efa5818
Implementing basic paging using a Python script
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
462
diff
changeset
|
513 Implementing basic paging |
46949efa5818
Implementing basic paging using a Python script
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
462
diff
changeset
|
514 ......................... |
46949efa5818
Implementing basic paging using a Python script
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
462
diff
changeset
|
515 |
46949efa5818
Implementing basic paging using a Python script
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
462
diff
changeset
|
516 As explained in the FAQ, the :ref:`Orthanc Explorer interface is |
46949efa5818
Implementing basic paging using a Python script
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
462
diff
changeset
|
517 low-level <improving-interface>`, and is not adapted for |
46949efa5818
Implementing basic paging using a Python script
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
462
diff
changeset
|
518 end-users. One common need is to implement paging of studies, which |
46949efa5818
Implementing basic paging using a Python script
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
462
diff
changeset
|
519 calls for server-side sorting of studies. This can be done using the |
46949efa5818
Implementing basic paging using a Python script
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
462
diff
changeset
|
520 following sample Python plugin that registers a new route |
704
ba2403ebd4b7
moving python samples in separate files (3)
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
703
diff
changeset
|
521 ``/sort-studies`` in the REST API of Orthanc: |
469
46949efa5818
Implementing basic paging using a Python script
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
462
diff
changeset
|
522 |
704
ba2403ebd4b7
moving python samples in separate files (3)
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
703
diff
changeset
|
523 .. literalinclude:: python/paging.py |
ba2403ebd4b7
moving python samples in separate files (3)
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
703
diff
changeset
|
524 :language: python |
469
46949efa5818
Implementing basic paging using a Python script
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
462
diff
changeset
|
525 |
46949efa5818
Implementing basic paging using a Python script
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
462
diff
changeset
|
526 .. highlight:: bash |
46949efa5818
Implementing basic paging using a Python script
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
462
diff
changeset
|
527 |
46949efa5818
Implementing basic paging using a Python script
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
462
diff
changeset
|
528 Here is a sample call to this new REST route, that could be issued by |
46949efa5818
Implementing basic paging using a Python script
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
462
diff
changeset
|
529 any JavaScript framework (the ``json_pp`` command-line pretty-prints a |
46949efa5818
Implementing basic paging using a Python script
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
462
diff
changeset
|
530 JSON file):: |
46949efa5818
Implementing basic paging using a Python script
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
462
diff
changeset
|
531 |
46949efa5818
Implementing basic paging using a Python script
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
462
diff
changeset
|
532 $ curl http://localhost:8042/sort-studies | json_pp |
46949efa5818
Implementing basic paging using a Python script
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
462
diff
changeset
|
533 |
46949efa5818
Implementing basic paging using a Python script
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
462
diff
changeset
|
534 This route also implement paging (i.e. it can limit and offset the |
46949efa5818
Implementing basic paging using a Python script
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
462
diff
changeset
|
535 returned studies):: |
46949efa5818
Implementing basic paging using a Python script
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
462
diff
changeset
|
536 |
46949efa5818
Implementing basic paging using a Python script
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
462
diff
changeset
|
537 $ curl 'http://localhost:8042/sort-studies?offset=2&limit=2' | json_pp |
46949efa5818
Implementing basic paging using a Python script
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
462
diff
changeset
|
538 |
46949efa5818
Implementing basic paging using a Python script
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
462
diff
changeset
|
539 Obviously, this basic sample can be improved in many ways. To improve |
46949efa5818
Implementing basic paging using a Python script
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
462
diff
changeset
|
540 performance, one could for instance cache the result of |
46949efa5818
Implementing basic paging using a Python script
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
462
diff
changeset
|
541 ``/studies?expand`` in memory by :ref:`listening to changes |
46949efa5818
Implementing basic paging using a Python script
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
462
diff
changeset
|
542 <python-changes>` in the list of studies |
46949efa5818
Implementing basic paging using a Python script
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
462
diff
changeset
|
543 (cf. ``orthanc.ChangeType.NEW_STUDY`` and |
46949efa5818
Implementing basic paging using a Python script
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
462
diff
changeset
|
544 ``orthanc.ChangeType.DELETED``). |
46949efa5818
Implementing basic paging using a Python script
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
462
diff
changeset
|
545 |
46949efa5818
Implementing basic paging using a Python script
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
462
diff
changeset
|
546 |
551
d0332c5a2cb8
Python plugin: excel generation example
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
539
diff
changeset
|
547 .. _python_excel: |
d0332c5a2cb8
Python plugin: excel generation example
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
539
diff
changeset
|
548 |
d0332c5a2cb8
Python plugin: excel generation example
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
539
diff
changeset
|
549 Creating a Microsoft Excel report |
d0332c5a2cb8
Python plugin: excel generation example
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
539
diff
changeset
|
550 ................................. |
d0332c5a2cb8
Python plugin: excel generation example
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
539
diff
changeset
|
551 |
d0332c5a2cb8
Python plugin: excel generation example
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
539
diff
changeset
|
552 As Orthanc plugins have access to any installed Python module, it is |
d0332c5a2cb8
Python plugin: excel generation example
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
539
diff
changeset
|
553 very easy to implement a server-side plugin that generates a report in |
704
ba2403ebd4b7
moving python samples in separate files (3)
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
703
diff
changeset
|
554 the Microsoft Excel ``.xls`` format. Here is a working example: |
551
d0332c5a2cb8
Python plugin: excel generation example
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
539
diff
changeset
|
555 |
704
ba2403ebd4b7
moving python samples in separate files (3)
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
703
diff
changeset
|
556 .. literalinclude:: python/excel.py |
ba2403ebd4b7
moving python samples in separate files (3)
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
703
diff
changeset
|
557 :language: python |
551
d0332c5a2cb8
Python plugin: excel generation example
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
539
diff
changeset
|
558 |
d0332c5a2cb8
Python plugin: excel generation example
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
539
diff
changeset
|
559 If opening the ``http://localhost:8042/report.xls`` URI, this Python |
d0332c5a2cb8
Python plugin: excel generation example
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
539
diff
changeset
|
560 will generate a workbook with one sheet that contains the list of |
d0332c5a2cb8
Python plugin: excel generation example
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
539
diff
changeset
|
561 studies, with the patient ID, the patient name and the study |
d0332c5a2cb8
Python plugin: excel generation example
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
539
diff
changeset
|
562 description. |
d0332c5a2cb8
Python plugin: excel generation example
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
539
diff
changeset
|
563 |
469
46949efa5818
Implementing basic paging using a Python script
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
462
diff
changeset
|
564 |
556
6a3d48510b0b
Python sample: "Forbid or allow access to REST resources (authorization)", deprecating advanced authorization plugin
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
555
diff
changeset
|
565 .. _python_authorization: |
6a3d48510b0b
Python sample: "Forbid or allow access to REST resources (authorization)", deprecating advanced authorization plugin
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
555
diff
changeset
|
566 |
697
7581dc208323
Handling DICOM SCP requests using a Python plugin
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
696
diff
changeset
|
567 Forbid or allow access to REST resources (authorization, new in 3.0) |
7581dc208323
Handling DICOM SCP requests using a Python plugin
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
696
diff
changeset
|
568 .................................................................... |
556
6a3d48510b0b
Python sample: "Forbid or allow access to REST resources (authorization)", deprecating advanced authorization plugin
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
555
diff
changeset
|
569 |
6a3d48510b0b
Python sample: "Forbid or allow access to REST resources (authorization)", deprecating advanced authorization plugin
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
555
diff
changeset
|
570 The following Python script installs a callback that is triggered |
704
ba2403ebd4b7
moving python samples in separate files (3)
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
703
diff
changeset
|
571 whenever the HTTP server of Orthanc is accessed: |
556
6a3d48510b0b
Python sample: "Forbid or allow access to REST resources (authorization)", deprecating advanced authorization plugin
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
555
diff
changeset
|
572 |
704
ba2403ebd4b7
moving python samples in separate files (3)
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
703
diff
changeset
|
573 .. literalinclude:: python/authorization-1.py |
ba2403ebd4b7
moving python samples in separate files (3)
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
703
diff
changeset
|
574 :language: python |
556
6a3d48510b0b
Python sample: "Forbid or allow access to REST resources (authorization)", deprecating advanced authorization plugin
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
555
diff
changeset
|
575 |
6a3d48510b0b
Python sample: "Forbid or allow access to REST resources (authorization)", deprecating advanced authorization plugin
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
555
diff
changeset
|
576 |
6a3d48510b0b
Python sample: "Forbid or allow access to REST resources (authorization)", deprecating advanced authorization plugin
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
555
diff
changeset
|
577 If access is not granted, the ``Filter`` callback must return |
6a3d48510b0b
Python sample: "Forbid or allow access to REST resources (authorization)", deprecating advanced authorization plugin
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
555
diff
changeset
|
578 ``False``. As a consequence, the HTTP status code would be set to |
6a3d48510b0b
Python sample: "Forbid or allow access to REST resources (authorization)", deprecating advanced authorization plugin
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
555
diff
changeset
|
579 ``403 Forbidden``. If access is granted, the ``Filter`` must return |
6a3d48510b0b
Python sample: "Forbid or allow access to REST resources (authorization)", deprecating advanced authorization plugin
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
555
diff
changeset
|
580 ``true``. The ``request`` argument contains more information about the |
6a3d48510b0b
Python sample: "Forbid or allow access to REST resources (authorization)", deprecating advanced authorization plugin
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
555
diff
changeset
|
581 request (such as the HTTP headers, the IP address of the caller and |
6a3d48510b0b
Python sample: "Forbid or allow access to REST resources (authorization)", deprecating advanced authorization plugin
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
555
diff
changeset
|
582 the GET arguments). |
6a3d48510b0b
Python sample: "Forbid or allow access to REST resources (authorization)", deprecating advanced authorization plugin
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
555
diff
changeset
|
583 |
6a3d48510b0b
Python sample: "Forbid or allow access to REST resources (authorization)", deprecating advanced authorization plugin
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
555
diff
changeset
|
584 Note that this is similar to the ``IncomingHttpRequestFilter()`` |
6a3d48510b0b
Python sample: "Forbid or allow access to REST resources (authorization)", deprecating advanced authorization plugin
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
555
diff
changeset
|
585 callback that is available in :ref:`Lua scripts <lua-filter-rest>`. |
6a3d48510b0b
Python sample: "Forbid or allow access to REST resources (authorization)", deprecating advanced authorization plugin
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
555
diff
changeset
|
586 |
6a3d48510b0b
Python sample: "Forbid or allow access to REST resources (authorization)", deprecating advanced authorization plugin
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
555
diff
changeset
|
587 Thanks to Python, it is extremely easy to call remote Web services for |
704
ba2403ebd4b7
moving python samples in separate files (3)
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
703
diff
changeset
|
588 authorization. Here is an example using the ``requests`` library: |
556
6a3d48510b0b
Python sample: "Forbid or allow access to REST resources (authorization)", deprecating advanced authorization plugin
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
555
diff
changeset
|
589 |
704
ba2403ebd4b7
moving python samples in separate files (3)
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
703
diff
changeset
|
590 .. literalinclude:: python/authorization-2.py |
ba2403ebd4b7
moving python samples in separate files (3)
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
703
diff
changeset
|
591 :language: python |
556
6a3d48510b0b
Python sample: "Forbid or allow access to REST resources (authorization)", deprecating advanced authorization plugin
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
555
diff
changeset
|
592 |
6a3d48510b0b
Python sample: "Forbid or allow access to REST resources (authorization)", deprecating advanced authorization plugin
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
555
diff
changeset
|
593 This filter could be used together with the following Web service |
6a3d48510b0b
Python sample: "Forbid or allow access to REST resources (authorization)", deprecating advanced authorization plugin
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
555
diff
changeset
|
594 implemented using `Node.js |
704
ba2403ebd4b7
moving python samples in separate files (3)
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
703
diff
changeset
|
595 <https://en.wikipedia.org/wiki/Node.js>`__: |
556
6a3d48510b0b
Python sample: "Forbid or allow access to REST resources (authorization)", deprecating advanced authorization plugin
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
555
diff
changeset
|
596 |
704
ba2403ebd4b7
moving python samples in separate files (3)
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
703
diff
changeset
|
597 .. literalinclude:: python/authorization-node-service.js |
ba2403ebd4b7
moving python samples in separate files (3)
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
703
diff
changeset
|
598 :language: javascript |
556
6a3d48510b0b
Python sample: "Forbid or allow access to REST resources (authorization)", deprecating advanced authorization plugin
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
555
diff
changeset
|
599 |
6a3d48510b0b
Python sample: "Forbid or allow access to REST resources (authorization)", deprecating advanced authorization plugin
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
555
diff
changeset
|
600 |
708
cd70d23f34bc
Lookup DICOM dictionary in Python scripts
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
707
diff
changeset
|
601 .. _python_lookup_dictionary: |
cd70d23f34bc
Lookup DICOM dictionary in Python scripts
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
707
diff
changeset
|
602 |
cd70d23f34bc
Lookup DICOM dictionary in Python scripts
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
707
diff
changeset
|
603 Lookup DICOM dictionary (new in 3.2) |
cd70d23f34bc
Lookup DICOM dictionary in Python scripts
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
707
diff
changeset
|
604 .................................... |
cd70d23f34bc
Lookup DICOM dictionary in Python scripts
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
707
diff
changeset
|
605 |
cd70d23f34bc
Lookup DICOM dictionary in Python scripts
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
707
diff
changeset
|
606 Python plugins can access the dictionary of the DICOM tags that are |
cd70d23f34bc
Lookup DICOM dictionary in Python scripts
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
707
diff
changeset
|
607 handled by Orthanc: |
cd70d23f34bc
Lookup DICOM dictionary in Python scripts
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
707
diff
changeset
|
608 |
cd70d23f34bc
Lookup DICOM dictionary in Python scripts
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
707
diff
changeset
|
609 .. literalinclude:: python/lookup-dictionary.py |
cd70d23f34bc
Lookup DICOM dictionary in Python scripts
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
707
diff
changeset
|
610 :language: python |
cd70d23f34bc
Lookup DICOM dictionary in Python scripts
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
707
diff
changeset
|
611 |
cd70d23f34bc
Lookup DICOM dictionary in Python scripts
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
707
diff
changeset
|
612 .. highlight:: text |
cd70d23f34bc
Lookup DICOM dictionary in Python scripts
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
707
diff
changeset
|
613 |
cd70d23f34bc
Lookup DICOM dictionary in Python scripts
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
707
diff
changeset
|
614 Note how Python introspection is used in order to map the values in |
cd70d23f34bc
Lookup DICOM dictionary in Python scripts
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
707
diff
changeset
|
615 enumeration ``orthanc.ValueRepresentation`` to a string description of |
cd70d23f34bc
Lookup DICOM dictionary in Python scripts
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
707
diff
changeset
|
616 the value representation. If started, the plugin above would output |
cd70d23f34bc
Lookup DICOM dictionary in Python scripts
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
707
diff
changeset
|
617 the following information in the Orthanc logs:: |
cd70d23f34bc
Lookup DICOM dictionary in Python scripts
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
707
diff
changeset
|
618 |
cd70d23f34bc
Lookup DICOM dictionary in Python scripts
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
707
diff
changeset
|
619 W0611 14:04:08.563957 PluginsManager.cpp:168] Entry in the dictionary: { |
cd70d23f34bc
Lookup DICOM dictionary in Python scripts
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
707
diff
changeset
|
620 "Element": 32, |
cd70d23f34bc
Lookup DICOM dictionary in Python scripts
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
707
diff
changeset
|
621 "Group": 16, |
cd70d23f34bc
Lookup DICOM dictionary in Python scripts
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
707
diff
changeset
|
622 "MaxMultiplicity": 1, |
cd70d23f34bc
Lookup DICOM dictionary in Python scripts
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
707
diff
changeset
|
623 "MinMultiplicity": 1, |
cd70d23f34bc
Lookup DICOM dictionary in Python scripts
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
707
diff
changeset
|
624 "ValueRepresentation": 11 |
cd70d23f34bc
Lookup DICOM dictionary in Python scripts
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
707
diff
changeset
|
625 } |
cd70d23f34bc
Lookup DICOM dictionary in Python scripts
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
707
diff
changeset
|
626 W0611 14:04:08.563975 PluginsManager.cpp:168] Name of the value representation: LO |
cd70d23f34bc
Lookup DICOM dictionary in Python scripts
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
707
diff
changeset
|
627 |
cd70d23f34bc
Lookup DICOM dictionary in Python scripts
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
707
diff
changeset
|
628 |
695
f4fc12ed00ee
creating dicom instances in Python
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
678
diff
changeset
|
629 .. _python_create_dicom: |
556
6a3d48510b0b
Python sample: "Forbid or allow access to REST resources (authorization)", deprecating advanced authorization plugin
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
555
diff
changeset
|
630 |
696 | 631 Creating DICOM instances (new in 3.2) |
695
f4fc12ed00ee
creating dicom instances in Python
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
678
diff
changeset
|
632 ..................................... |
f4fc12ed00ee
creating dicom instances in Python
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
678
diff
changeset
|
633 |
f4fc12ed00ee
creating dicom instances in Python
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
678
diff
changeset
|
634 The following sample Python script will write on the disk a new DICOM |
f4fc12ed00ee
creating dicom instances in Python
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
678
diff
changeset
|
635 instance including the traditional Lena sample image, and will decode |
704
ba2403ebd4b7
moving python samples in separate files (3)
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
703
diff
changeset
|
636 the single frame of this DICOM instance: |
695
f4fc12ed00ee
creating dicom instances in Python
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
678
diff
changeset
|
637 |
704
ba2403ebd4b7
moving python samples in separate files (3)
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
703
diff
changeset
|
638 .. literalinclude:: python/create-dicom.py |
ba2403ebd4b7
moving python samples in separate files (3)
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
703
diff
changeset
|
639 :language: python |
695
f4fc12ed00ee
creating dicom instances in Python
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
678
diff
changeset
|
640 |
f4fc12ed00ee
creating dicom instances in Python
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
678
diff
changeset
|
641 |
706
c62539d00251
Conversions between Orthanc and Python images
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
704
diff
changeset
|
642 .. _python_pil_conversions: |
c62539d00251
Conversions between Orthanc and Python images
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
704
diff
changeset
|
643 |
c62539d00251
Conversions between Orthanc and Python images
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
704
diff
changeset
|
644 Conversions between Orthanc and Python images (new in 3.2) |
c62539d00251
Conversions between Orthanc and Python images
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
704
diff
changeset
|
645 .......................................................... |
c62539d00251
Conversions between Orthanc and Python images
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
704
diff
changeset
|
646 |
c62539d00251
Conversions between Orthanc and Python images
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
704
diff
changeset
|
647 The Python method ``orthanc.Image.GetImageBuffer()`` returns a copy of |
c62539d00251
Conversions between Orthanc and Python images
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
704
diff
changeset
|
648 the memory buffer of an image that is handled Orthanc. Conversely, the |
c62539d00251
Conversions between Orthanc and Python images
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
704
diff
changeset
|
649 Python function ``orthanc.CreateImageFromBuffer()`` can be used to |
c62539d00251
Conversions between Orthanc and Python images
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
704
diff
changeset
|
650 create an Orthanc image from a Python buffer. Taken together, these |
c62539d00251
Conversions between Orthanc and Python images
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
704
diff
changeset
|
651 two functions can be used to do bidirectional conversions between |
c62539d00251
Conversions between Orthanc and Python images
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
704
diff
changeset
|
652 Orthanc images and Python images. |
c62539d00251
Conversions between Orthanc and Python images
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
704
diff
changeset
|
653 |
c62539d00251
Conversions between Orthanc and Python images
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
704
diff
changeset
|
654 Here is a full working example using PIL/Pillow that shows how to |
707 | 655 decode one frame of a DICOM instance using Orthanc, then to modify |
656 this image using PIL, and finally to upload the modified image as a | |
657 new DICOM instance: | |
706
c62539d00251
Conversions between Orthanc and Python images
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
704
diff
changeset
|
658 |
c62539d00251
Conversions between Orthanc and Python images
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
704
diff
changeset
|
659 .. literalinclude:: python/pil-conversions.py |
c62539d00251
Conversions between Orthanc and Python images
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
704
diff
changeset
|
660 :language: python |
c62539d00251
Conversions between Orthanc and Python images
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
704
diff
changeset
|
661 |
c62539d00251
Conversions between Orthanc and Python images
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
704
diff
changeset
|
662 |
697
7581dc208323
Handling DICOM SCP requests using a Python plugin
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
696
diff
changeset
|
663 .. _python_dicom_scp: |
695
f4fc12ed00ee
creating dicom instances in Python
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
678
diff
changeset
|
664 |
697
7581dc208323
Handling DICOM SCP requests using a Python plugin
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
696
diff
changeset
|
665 Handling DICOM SCP requests (new in 3.2) |
7581dc208323
Handling DICOM SCP requests using a Python plugin
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
696
diff
changeset
|
666 ........................................ |
7581dc208323
Handling DICOM SCP requests using a Python plugin
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
696
diff
changeset
|
667 |
7581dc208323
Handling DICOM SCP requests using a Python plugin
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
696
diff
changeset
|
668 Starting with release 3.2 of the Python plugin, it is possible to |
7581dc208323
Handling DICOM SCP requests using a Python plugin
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
696
diff
changeset
|
669 replace the C-FIND SCP and C-MOVE SCP of Orthanc by a Python |
7581dc208323
Handling DICOM SCP requests using a Python plugin
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
696
diff
changeset
|
670 script. This feature can notably be used to create a custom DICOM |
704
ba2403ebd4b7
moving python samples in separate files (3)
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
703
diff
changeset
|
671 proxy. Here is a minimal example: |
697
7581dc208323
Handling DICOM SCP requests using a Python plugin
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
696
diff
changeset
|
672 |
704
ba2403ebd4b7
moving python samples in separate files (3)
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
703
diff
changeset
|
673 .. literalinclude:: python/dicom-find-move-scp.py |
ba2403ebd4b7
moving python samples in separate files (3)
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
703
diff
changeset
|
674 :language: python |
ba2403ebd4b7
moving python samples in separate files (3)
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
703
diff
changeset
|
675 |
697
7581dc208323
Handling DICOM SCP requests using a Python plugin
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
696
diff
changeset
|
676 |
7581dc208323
Handling DICOM SCP requests using a Python plugin
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
696
diff
changeset
|
677 .. highlight:: text |
7581dc208323
Handling DICOM SCP requests using a Python plugin
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
696
diff
changeset
|
678 |
7581dc208323
Handling DICOM SCP requests using a Python plugin
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
696
diff
changeset
|
679 In this sample, the C-FIND SCP will send one single answer that |
7581dc208323
Handling DICOM SCP requests using a Python plugin
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
696
diff
changeset
|
680 reproduces the values provided by the SCU:: |
7581dc208323
Handling DICOM SCP requests using a Python plugin
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
696
diff
changeset
|
681 |
699 | 682 $ findscu localhost 4242 -S -k QueryRetrieveLevel=STUDY -k PatientName=TEST -k SeriesDescription= |
697
7581dc208323
Handling DICOM SCP requests using a Python plugin
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
696
diff
changeset
|
683 I: --------------------------- |
7581dc208323
Handling DICOM SCP requests using a Python plugin
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
696
diff
changeset
|
684 I: Find Response: 1 (Pending) |
7581dc208323
Handling DICOM SCP requests using a Python plugin
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
696
diff
changeset
|
685 I: |
7581dc208323
Handling DICOM SCP requests using a Python plugin
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
696
diff
changeset
|
686 I: # Dicom-Data-Set |
7581dc208323
Handling DICOM SCP requests using a Python plugin
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
696
diff
changeset
|
687 I: # Used TransferSyntax: Little Endian Explicit |
7581dc208323
Handling DICOM SCP requests using a Python plugin
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
696
diff
changeset
|
688 I: (0008,0005) CS [ISO_IR 100] # 10, 1 SpecificCharacterSet |
7581dc208323
Handling DICOM SCP requests using a Python plugin
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
696
diff
changeset
|
689 I: (0008,0052) CS [HELLO0-STUDY] # 12, 1 QueryRetrieveLevel |
7581dc208323
Handling DICOM SCP requests using a Python plugin
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
696
diff
changeset
|
690 I: (0008,103e) LO [HELLO1- ] # 8, 1 SeriesDescription |
7581dc208323
Handling DICOM SCP requests using a Python plugin
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
696
diff
changeset
|
691 I: (0010,0010) PN [HELLO2-TEST ] # 12, 1 PatientName |
7581dc208323
Handling DICOM SCP requests using a Python plugin
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
696
diff
changeset
|
692 I: |
7581dc208323
Handling DICOM SCP requests using a Python plugin
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
696
diff
changeset
|
693 |
698 | 694 A more realistic Python script could for instance call the route |
695 ``/modalities/{...}/query`` in the :ref:`REST API <rest-find-scu>` of | |
696 Orthanc using ``orthanc.RestApiPost()``, in order to query the content | |
697 a remote modality through a second C-FIND SCU request (this time | |
698 issued by Orthanc as a SCU). | |
699 | |
697
7581dc208323
Handling DICOM SCP requests using a Python plugin
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
696
diff
changeset
|
700 The C-MOVE SCP can be invoked as follows:: |
7581dc208323
Handling DICOM SCP requests using a Python plugin
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
696
diff
changeset
|
701 |
699 | 702 $ movescu localhost 4242 -aem TARGET -aec SOURCE -aet MOVESCU -S -k QueryRetrieveLevel=IMAGE -k StudyInstanceUID=1.2.3.4 |
697
7581dc208323
Handling DICOM SCP requests using a Python plugin
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
696
diff
changeset
|
703 |
7581dc208323
Handling DICOM SCP requests using a Python plugin
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
696
diff
changeset
|
704 The C-MOVE request above would print the following information in the |
7581dc208323
Handling DICOM SCP requests using a Python plugin
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
696
diff
changeset
|
705 Orthanc logs:: |
7581dc208323
Handling DICOM SCP requests using a Python plugin
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
696
diff
changeset
|
706 |
7581dc208323
Handling DICOM SCP requests using a Python plugin
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
696
diff
changeset
|
707 W0610 18:30:36.840865 PluginsManager.cpp:168] C-MOVE request to be handled in Python: { |
7581dc208323
Handling DICOM SCP requests using a Python plugin
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
696
diff
changeset
|
708 "AccessionNumber": "", |
7581dc208323
Handling DICOM SCP requests using a Python plugin
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
696
diff
changeset
|
709 "Level": "INSTANCE", |
699 | 710 "OriginatorAET": "MOVESCU", |
697
7581dc208323
Handling DICOM SCP requests using a Python plugin
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
696
diff
changeset
|
711 "OriginatorID": 1, |
7581dc208323
Handling DICOM SCP requests using a Python plugin
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
696
diff
changeset
|
712 "PatientID": "", |
7581dc208323
Handling DICOM SCP requests using a Python plugin
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
696
diff
changeset
|
713 "SOPInstanceUID": "", |
7581dc208323
Handling DICOM SCP requests using a Python plugin
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
696
diff
changeset
|
714 "SeriesInstanceUID": "", |
699 | 715 "SourceAET": "SOURCE", |
697
7581dc208323
Handling DICOM SCP requests using a Python plugin
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
696
diff
changeset
|
716 "StudyInstanceUID": "1.2.3.4", |
7581dc208323
Handling DICOM SCP requests using a Python plugin
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
696
diff
changeset
|
717 "TargetAET": "TARGET" |
7581dc208323
Handling DICOM SCP requests using a Python plugin
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
696
diff
changeset
|
718 } |
7581dc208323
Handling DICOM SCP requests using a Python plugin
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
696
diff
changeset
|
719 |
710 | 720 It is now up to your Python callback to process the C-MOVE SCU request, |
697
7581dc208323
Handling DICOM SCP requests using a Python plugin
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
696
diff
changeset
|
721 for instance by calling the route ``/modalities/{...}/store`` in the |
7581dc208323
Handling DICOM SCP requests using a Python plugin
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
696
diff
changeset
|
722 :ref:`REST API <rest-store-scu>` of Orthanc using |
700
56a06ca9ec20
Handling worklist SCP requests in Python
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
699
diff
changeset
|
723 ``orthanc.RestApiPost()``. It is highly advised to create a Python |
56a06ca9ec20
Handling worklist SCP requests in Python
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
699
diff
changeset
|
724 thread to handle the request, in order to avoid blocking Orthanc as |
56a06ca9ec20
Handling worklist SCP requests in Python
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
699
diff
changeset
|
725 much as possible. |
56a06ca9ec20
Handling worklist SCP requests in Python
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
699
diff
changeset
|
726 |
56a06ca9ec20
Handling worklist SCP requests in Python
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
699
diff
changeset
|
727 |
1067 | 728 **Note:** In version 4.2, we have introduced a new version of the C-MOVE SCP |
729 handler that can be registered through ``orthanc.RegisterMoveCallback2(CreateMoveCallback, GetMoveSizeCallback, ApplyMoveCallback, FreeMoveCallback)``. | |
730 This `DICOM to DICOMWeb proxy sample project <https://github.com/orthanc-team/dicom-dicomweb-proxy/blob/main/proxy.py>`__ demonstrates how it can be used. | |
731 | |
732 | |
700
56a06ca9ec20
Handling worklist SCP requests in Python
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
699
diff
changeset
|
733 .. _python_worklists: |
56a06ca9ec20
Handling worklist SCP requests in Python
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
699
diff
changeset
|
734 |
56a06ca9ec20
Handling worklist SCP requests in Python
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
699
diff
changeset
|
735 Handling worklist SCP requests (new in 3.2) |
56a06ca9ec20
Handling worklist SCP requests in Python
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
699
diff
changeset
|
736 ........................................... |
56a06ca9ec20
Handling worklist SCP requests in Python
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
699
diff
changeset
|
737 |
56a06ca9ec20
Handling worklist SCP requests in Python
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
699
diff
changeset
|
738 Starting with release 3.2 of the Python plugin, it is possible to |
701
f093160dd7f4
cross-references regarding worklists
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
700
diff
changeset
|
739 answer :ref:`worklist queries <worklist>` using a Python script. This |
f093160dd7f4
cross-references regarding worklists
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
700
diff
changeset
|
740 is especially useful to easily create a bridge between Orthanc, |
f093160dd7f4
cross-references regarding worklists
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
700
diff
changeset
|
741 HL7/FHIR messages and RIS systems. Indeed, Python provides many tools |
f093160dd7f4
cross-references regarding worklists
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
700
diff
changeset
|
742 to handle HL7 such as `python-hl7 library |
f093160dd7f4
cross-references regarding worklists
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
700
diff
changeset
|
743 <https://python-hl7.readthedocs.io/en/latest/>`__. |
700
56a06ca9ec20
Handling worklist SCP requests in Python
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
699
diff
changeset
|
744 |
973 | 745 The following Python script reproduces features similar to the |
700
56a06ca9ec20
Handling worklist SCP requests in Python
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
699
diff
changeset
|
746 :ref:`sample modality worklists plugin <worklists-plugin>`: |
56a06ca9ec20
Handling worklist SCP requests in Python
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
699
diff
changeset
|
747 |
56a06ca9ec20
Handling worklist SCP requests in Python
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
699
diff
changeset
|
748 .. literalinclude:: python/worklist.py |
56a06ca9ec20
Handling worklist SCP requests in Python
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
699
diff
changeset
|
749 :language: python |
56a06ca9ec20
Handling worklist SCP requests in Python
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
699
diff
changeset
|
750 |
701
f093160dd7f4
cross-references regarding worklists
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
700
diff
changeset
|
751 .. highlight:: text |
f093160dd7f4
cross-references regarding worklists
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
700
diff
changeset
|
752 |
f093160dd7f4
cross-references regarding worklists
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
700
diff
changeset
|
753 Here is the result of this plugin on a sample call:: |
f093160dd7f4
cross-references regarding worklists
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
700
diff
changeset
|
754 |
f093160dd7f4
cross-references regarding worklists
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
700
diff
changeset
|
755 $ findscu -W -k "ScheduledProcedureStepSequence[0].Modality=MR" 127.0.0.1 4242 |
f093160dd7f4
cross-references regarding worklists
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
700
diff
changeset
|
756 I: --------------------------- |
f093160dd7f4
cross-references regarding worklists
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
700
diff
changeset
|
757 I: Find Response: 1 (Pending) |
f093160dd7f4
cross-references regarding worklists
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
700
diff
changeset
|
758 I: |
f093160dd7f4
cross-references regarding worklists
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
700
diff
changeset
|
759 I: # Dicom-Data-Set |
f093160dd7f4
cross-references regarding worklists
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
700
diff
changeset
|
760 I: # Used TransferSyntax: Little Endian Explicit |
f093160dd7f4
cross-references regarding worklists
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
700
diff
changeset
|
761 I: (0008,0005) CS [ISO_IR 100] # 10, 1 SpecificCharacterSet |
f093160dd7f4
cross-references regarding worklists
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
700
diff
changeset
|
762 I: (0040,0100) SQ (Sequence with explicit length #=1) # 18, 1 ScheduledProcedureStepSequence |
f093160dd7f4
cross-references regarding worklists
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
700
diff
changeset
|
763 I: (fffe,e000) na (Item with explicit length #=1) # 10, 1 Item |
f093160dd7f4
cross-references regarding worklists
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
700
diff
changeset
|
764 I: (0008,0060) CS [MR] # 2, 1 Modality |
f093160dd7f4
cross-references regarding worklists
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
700
diff
changeset
|
765 I: (fffe,e00d) na (ItemDelimitationItem for re-encoding) # 0, 0 ItemDelimitationItem |
f093160dd7f4
cross-references regarding worklists
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
700
diff
changeset
|
766 I: (fffe,e0dd) na (SequenceDelimitationItem for re-encod.) # 0, 0 SequenceDelimitationItem |
f093160dd7f4
cross-references regarding worklists
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
700
diff
changeset
|
767 I: |
f093160dd7f4
cross-references regarding worklists
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
700
diff
changeset
|
768 I: --------------------------- |
f093160dd7f4
cross-references regarding worklists
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
700
diff
changeset
|
769 I: Find Response: 2 (Pending) |
f093160dd7f4
cross-references regarding worklists
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
700
diff
changeset
|
770 I: |
f093160dd7f4
cross-references regarding worklists
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
700
diff
changeset
|
771 I: # Dicom-Data-Set |
f093160dd7f4
cross-references regarding worklists
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
700
diff
changeset
|
772 I: # Used TransferSyntax: Little Endian Explicit |
f093160dd7f4
cross-references regarding worklists
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
700
diff
changeset
|
773 I: (0008,0005) CS [ISO_IR 100] # 10, 1 SpecificCharacterSet |
f093160dd7f4
cross-references regarding worklists
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
700
diff
changeset
|
774 I: (0040,0100) SQ (Sequence with explicit length #=1) # 18, 1 ScheduledProcedureStepSequence |
f093160dd7f4
cross-references regarding worklists
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
700
diff
changeset
|
775 I: (fffe,e000) na (Item with explicit length #=1) # 10, 1 Item |
f093160dd7f4
cross-references regarding worklists
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
700
diff
changeset
|
776 I: (0008,0060) CS [MR] # 2, 1 Modality |
f093160dd7f4
cross-references regarding worklists
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
700
diff
changeset
|
777 I: (fffe,e00d) na (ItemDelimitationItem for re-encoding) # 0, 0 ItemDelimitationItem |
f093160dd7f4
cross-references regarding worklists
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
700
diff
changeset
|
778 I: (fffe,e0dd) na (SequenceDelimitationItem for re-encod.) # 0, 0 SequenceDelimitationItem |
f093160dd7f4
cross-references regarding worklists
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
700
diff
changeset
|
779 I: |
f093160dd7f4
cross-references regarding worklists
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
700
diff
changeset
|
780 |
727 | 781 |
782 .. _pynetdicom: | |
783 | |
784 Replacing DICOM SCP of Orthanc by pynetdicom | |
785 ............................................ | |
786 | |
787 .. highlight:: json | |
788 | |
789 Thanks to Python plugins, it is also possible to replace the built-in | |
790 DICOM SCP of Orthanc by `pynetdicom | |
791 <https://pydicom.github.io/pynetdicom/stable/examples/storage.html>`__ | |
792 so as to customize how the DICOM protocol is handled. Firstly, in the | |
793 configuration file, make sure to disable the Orthanc SCP by setting | |
794 ``DicomServerEnabled`` to ``false``:: | |
795 | |
796 { | |
797 "Plugins" : [ "." ], | |
798 "PythonScript" : "pynetdicom.py", | |
799 "DicomServerEnabled" : false | |
800 } | |
801 | |
802 Secondly, here a basic plugin illustrating how to start and stop the | |
803 pynetdicom server, and handle incoming C-STORE requests: | |
804 | |
805 .. literalinclude:: python/pynetdicom.py | |
806 :language: python | |
807 | |
808 As can be seen in this listing, whenever the pynetdicom receives an | |
809 incoming C-STORE request, it makes a POST call to the URI | |
810 ``/instances`` in the REST API of Orthanc in order to store the | |
811 embedded DICOM dataset into Orthanc. Obviously, one can build more | |
812 complex DICOM servers by handling more messages than C-STORE alone. | |
813 | |
747
56d48f6e52cc
catching exceptions in python plugins
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
741
diff
changeset
|
814 |
56d48f6e52cc
catching exceptions in python plugins
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
741
diff
changeset
|
815 .. _python_exception: |
56d48f6e52cc
catching exceptions in python plugins
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
741
diff
changeset
|
816 |
56d48f6e52cc
catching exceptions in python plugins
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
741
diff
changeset
|
817 Catching exceptions |
56d48f6e52cc
catching exceptions in python plugins
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
741
diff
changeset
|
818 ................... |
56d48f6e52cc
catching exceptions in python plugins
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
741
diff
changeset
|
819 |
56d48f6e52cc
catching exceptions in python plugins
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
741
diff
changeset
|
820 Starting with release 3.3 of the Python plugin, the plugin generates a |
56d48f6e52cc
catching exceptions in python plugins
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
741
diff
changeset
|
821 Python exception derived from class ``orthanc.OrthancException`` if an |
56d48f6e52cc
catching exceptions in python plugins
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
741
diff
changeset
|
822 error is encountered. This exception contains a tuple that provides |
56d48f6e52cc
catching exceptions in python plugins
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
741
diff
changeset
|
823 the error code and its textual description. |
56d48f6e52cc
catching exceptions in python plugins
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
741
diff
changeset
|
824 |
56d48f6e52cc
catching exceptions in python plugins
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
741
diff
changeset
|
825 In releases <= 3.2, the Python plugin raised the `built-in exception |
56d48f6e52cc
catching exceptions in python plugins
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
741
diff
changeset
|
826 <https://docs.python.org/3/library/exceptions.html>`__ ``ValueError``. |
56d48f6e52cc
catching exceptions in python plugins
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
741
diff
changeset
|
827 |
56d48f6e52cc
catching exceptions in python plugins
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
741
diff
changeset
|
828 Here is an example showing how to catch exceptions: |
56d48f6e52cc
catching exceptions in python plugins
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
741
diff
changeset
|
829 |
56d48f6e52cc
catching exceptions in python plugins
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
741
diff
changeset
|
830 .. literalinclude:: python/exception.py |
56d48f6e52cc
catching exceptions in python plugins
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
741
diff
changeset
|
831 :language: python |
56d48f6e52cc
catching exceptions in python plugins
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
741
diff
changeset
|
832 |
556
6a3d48510b0b
Python sample: "Forbid or allow access to REST resources (authorization)", deprecating advanced authorization plugin
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
555
diff
changeset
|
833 |
748
a296fe06fd86
Implementing a custom storage area in Python
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
747
diff
changeset
|
834 .. _python_storage_area: |
a296fe06fd86
Implementing a custom storage area in Python
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
747
diff
changeset
|
835 |
a296fe06fd86
Implementing a custom storage area in Python
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
747
diff
changeset
|
836 Implementing a custom storage area (new in 3.3) |
a296fe06fd86
Implementing a custom storage area in Python
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
747
diff
changeset
|
837 ............................................... |
a296fe06fd86
Implementing a custom storage area in Python
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
747
diff
changeset
|
838 |
a296fe06fd86
Implementing a custom storage area in Python
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
747
diff
changeset
|
839 Starting with release 3.3 of the Python plugin, it is possible to |
a296fe06fd86
Implementing a custom storage area in Python
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
747
diff
changeset
|
840 replace the built-in storage area of Orthanc (that writes |
a296fe06fd86
Implementing a custom storage area in Python
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
747
diff
changeset
|
841 :ref:`attachments <metadata>` onto the filesystem in the |
a296fe06fd86
Implementing a custom storage area in Python
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
747
diff
changeset
|
842 ``OrthancStorage`` folder by default), by providing 3 Python callbacks |
a296fe06fd86
Implementing a custom storage area in Python
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
747
diff
changeset
|
843 to the ``orthanc.RegisterStorageArea()`` function: |
a296fe06fd86
Implementing a custom storage area in Python
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
747
diff
changeset
|
844 |
a296fe06fd86
Implementing a custom storage area in Python
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
747
diff
changeset
|
845 * The first callback indicates how to **create** an attachment into |
a296fe06fd86
Implementing a custom storage area in Python
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
747
diff
changeset
|
846 the storage area. |
a296fe06fd86
Implementing a custom storage area in Python
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
747
diff
changeset
|
847 |
a296fe06fd86
Implementing a custom storage area in Python
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
747
diff
changeset
|
848 * The second callback indicates how to **read** an attachment from the |
a296fe06fd86
Implementing a custom storage area in Python
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
747
diff
changeset
|
849 storage area. |
a296fe06fd86
Implementing a custom storage area in Python
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
747
diff
changeset
|
850 |
a296fe06fd86
Implementing a custom storage area in Python
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
747
diff
changeset
|
851 * The third callback indicates how to **remove** an attachment out of |
a296fe06fd86
Implementing a custom storage area in Python
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
747
diff
changeset
|
852 the storage area. |
a296fe06fd86
Implementing a custom storage area in Python
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
747
diff
changeset
|
853 |
a296fe06fd86
Implementing a custom storage area in Python
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
747
diff
changeset
|
854 This feature can be used to quickly and easily interface Orthanc with |
a296fe06fd86
Implementing a custom storage area in Python
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
747
diff
changeset
|
855 any `object-based storage |
a296fe06fd86
Implementing a custom storage area in Python
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
747
diff
changeset
|
856 <https://en.wikipedia.org/wiki/Object_storage>`__ technology available |
a296fe06fd86
Implementing a custom storage area in Python
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
747
diff
changeset
|
857 in Python (such as `Ceph |
a296fe06fd86
Implementing a custom storage area in Python
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
747
diff
changeset
|
858 <https://en.wikipedia.org/wiki/Ceph_(software)>`__ or AWS S3-like |
a296fe06fd86
Implementing a custom storage area in Python
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
747
diff
changeset
|
859 tools). The performance will not be as good as a C/C++ native plugin |
a296fe06fd86
Implementing a custom storage area in Python
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
747
diff
changeset
|
860 (cf. the :ref:`cloud storage <object-storage>`, the :ref:`PostgreSQL |
a296fe06fd86
Implementing a custom storage area in Python
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
747
diff
changeset
|
861 <postgresql>` and the :ref:`MySQL <mysql>` plugins), but it can be |
a296fe06fd86
Implementing a custom storage area in Python
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
747
diff
changeset
|
862 used for prototyping or for basic setups. |
a296fe06fd86
Implementing a custom storage area in Python
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
747
diff
changeset
|
863 |
a296fe06fd86
Implementing a custom storage area in Python
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
747
diff
changeset
|
864 Here is a full, self-explaining sample: |
a296fe06fd86
Implementing a custom storage area in Python
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
747
diff
changeset
|
865 |
a296fe06fd86
Implementing a custom storage area in Python
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
747
diff
changeset
|
866 .. literalinclude:: python/storage-area.py |
a296fe06fd86
Implementing a custom storage area in Python
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
747
diff
changeset
|
867 :language: python |
a296fe06fd86
Implementing a custom storage area in Python
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
747
diff
changeset
|
868 |
a296fe06fd86
Implementing a custom storage area in Python
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
747
diff
changeset
|
869 The ``contentType`` can be used to apply a special treatment to some |
a296fe06fd86
Implementing a custom storage area in Python
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
747
diff
changeset
|
870 types of attachments (typically, DICOM instances). This parameter |
a296fe06fd86
Implementing a custom storage area in Python
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
747
diff
changeset
|
871 takes its values from the ``orthanc.ContentType`` enumeration. |
a296fe06fd86
Implementing a custom storage area in Python
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
747
diff
changeset
|
872 |
a296fe06fd86
Implementing a custom storage area in Python
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
747
diff
changeset
|
873 |
799
ecf431e1bd44
python sample for ReceivedInstanceCallback
Alain Mazy <am@osimis.io>
parents:
763
diff
changeset
|
874 .. _python_received_instance: |
ecf431e1bd44
python sample for ReceivedInstanceCallback
Alain Mazy <am@osimis.io>
parents:
763
diff
changeset
|
875 |
819
a67ceccebf02
releasing Python plugin 4.0
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
817
diff
changeset
|
876 Modifying received instances (new in 4.0) |
a67ceccebf02
releasing Python plugin 4.0
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
817
diff
changeset
|
877 ......................................... |
799
ecf431e1bd44
python sample for ReceivedInstanceCallback
Alain Mazy <am@osimis.io>
parents:
763
diff
changeset
|
878 |
819
a67ceccebf02
releasing Python plugin 4.0
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
817
diff
changeset
|
879 Starting with release 4.0 of the Python plugin, it is possible to |
799
ecf431e1bd44
python sample for ReceivedInstanceCallback
Alain Mazy <am@osimis.io>
parents:
763
diff
changeset
|
880 modify instances received by Orthanc before they are stored in |
ecf431e1bd44
python sample for ReceivedInstanceCallback
Alain Mazy <am@osimis.io>
parents:
763
diff
changeset
|
881 the storage. This is usually easier to perform modification at this |
ecf431e1bd44
python sample for ReceivedInstanceCallback
Alain Mazy <am@osimis.io>
parents:
763
diff
changeset
|
882 stage compared to using the ``/modify`` route once the instances |
ecf431e1bd44
python sample for ReceivedInstanceCallback
Alain Mazy <am@osimis.io>
parents:
763
diff
changeset
|
883 has been stored. |
ecf431e1bd44
python sample for ReceivedInstanceCallback
Alain Mazy <am@osimis.io>
parents:
763
diff
changeset
|
884 |
ecf431e1bd44
python sample for ReceivedInstanceCallback
Alain Mazy <am@osimis.io>
parents:
763
diff
changeset
|
885 .. literalinclude:: python/received-instance-callback.py |
ecf431e1bd44
python sample for ReceivedInstanceCallback
Alain Mazy <am@osimis.io>
parents:
763
diff
changeset
|
886 :language: python |
ecf431e1bd44
python sample for ReceivedInstanceCallback
Alain Mazy <am@osimis.io>
parents:
763
diff
changeset
|
887 |
ecf431e1bd44
python sample for ReceivedInstanceCallback
Alain Mazy <am@osimis.io>
parents:
763
diff
changeset
|
888 |
852
450f0efebe4f
FilterIncomingCStoreInstance python sample
Alain Mazy <am@osimis.io>
parents:
839
diff
changeset
|
889 Filtering incoming C-Store instances (new in 4.0) |
450f0efebe4f
FilterIncomingCStoreInstance python sample
Alain Mazy <am@osimis.io>
parents:
839
diff
changeset
|
890 ................................................. |
450f0efebe4f
FilterIncomingCStoreInstance python sample
Alain Mazy <am@osimis.io>
parents:
839
diff
changeset
|
891 |
450f0efebe4f
FilterIncomingCStoreInstance python sample
Alain Mazy <am@osimis.io>
parents:
839
diff
changeset
|
892 Starting with release 4.0 of the Python plugin, it is possible to |
450f0efebe4f
FilterIncomingCStoreInstance python sample
Alain Mazy <am@osimis.io>
parents:
839
diff
changeset
|
893 filter instances received from C-Store and return a specific error |
450f0efebe4f
FilterIncomingCStoreInstance python sample
Alain Mazy <am@osimis.io>
parents:
839
diff
changeset
|
894 code to the sending modality. |
450f0efebe4f
FilterIncomingCStoreInstance python sample
Alain Mazy <am@osimis.io>
parents:
839
diff
changeset
|
895 |
450f0efebe4f
FilterIncomingCStoreInstance python sample
Alain Mazy <am@osimis.io>
parents:
839
diff
changeset
|
896 This can be used, e.g, to implement a quota per modality or return |
450f0efebe4f
FilterIncomingCStoreInstance python sample
Alain Mazy <am@osimis.io>
parents:
839
diff
changeset
|
897 an ``out-of-resources`` status if the Orthanc storage is almost full. |
450f0efebe4f
FilterIncomingCStoreInstance python sample
Alain Mazy <am@osimis.io>
parents:
839
diff
changeset
|
898 |
450f0efebe4f
FilterIncomingCStoreInstance python sample
Alain Mazy <am@osimis.io>
parents:
839
diff
changeset
|
899 .. literalinclude:: python/incoming-cstore-filter.py |
450f0efebe4f
FilterIncomingCStoreInstance python sample
Alain Mazy <am@osimis.io>
parents:
839
diff
changeset
|
900 :language: python |
450f0efebe4f
FilterIncomingCStoreInstance python sample
Alain Mazy <am@osimis.io>
parents:
839
diff
changeset
|
901 |
799
ecf431e1bd44
python sample for ReceivedInstanceCallback
Alain Mazy <am@osimis.io>
parents:
763
diff
changeset
|
902 |
973 | 903 Storage Commitment SCP (new in 4.1) |
904 ................................... | |
905 | |
906 Starting with release 4.1 of the Python plugin, it is possible to | |
907 provide your own implementation of the :ref:`Storage Commitment <storage-commitment>`. | |
908 | |
909 This can be used, e.g, to check that you have backup the orthanc data in a | |
910 long term storage. | |
911 | |
912 .. literalinclude:: python/storage-commitment-default.py | |
913 :language: python | |
914 | |
915 | |
975
eb49a4ad8fbc
Python plugin: Extending the Orthanc Explorer interface
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
973
diff
changeset
|
916 .. _python_extend_orthanc_explorer: |
eb49a4ad8fbc
Python plugin: Extending the Orthanc Explorer interface
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
973
diff
changeset
|
917 |
eb49a4ad8fbc
Python plugin: Extending the Orthanc Explorer interface
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
973
diff
changeset
|
918 Extending the Orthanc Explorer interface |
eb49a4ad8fbc
Python plugin: Extending the Orthanc Explorer interface
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
973
diff
changeset
|
919 ........................................ |
eb49a4ad8fbc
Python plugin: Extending the Orthanc Explorer interface
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
973
diff
changeset
|
920 |
eb49a4ad8fbc
Python plugin: Extending the Orthanc Explorer interface
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
973
diff
changeset
|
921 Here is a sample plugin that adds a new button to Orthanc Explorer |
eb49a4ad8fbc
Python plugin: Extending the Orthanc Explorer interface
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
973
diff
changeset
|
922 that triggers a Python function: |
eb49a4ad8fbc
Python plugin: Extending the Orthanc Explorer interface
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
973
diff
changeset
|
923 |
eb49a4ad8fbc
Python plugin: Extending the Orthanc Explorer interface
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
973
diff
changeset
|
924 .. literalinclude:: python/sample-python-button.py |
eb49a4ad8fbc
Python plugin: Extending the Orthanc Explorer interface
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
973
diff
changeset
|
925 :language: python |
eb49a4ad8fbc
Python plugin: Extending the Orthanc Explorer interface
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
973
diff
changeset
|
926 |
eb49a4ad8fbc
Python plugin: Extending the Orthanc Explorer interface
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
973
diff
changeset
|
927 As can be seen in this sample: |
eb49a4ad8fbc
Python plugin: Extending the Orthanc Explorer interface
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
973
diff
changeset
|
928 |
eb49a4ad8fbc
Python plugin: Extending the Orthanc Explorer interface
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
973
diff
changeset
|
929 * The call to ``orthanc.ExtendOrthancExplorer()`` installs the button |
eb49a4ad8fbc
Python plugin: Extending the Orthanc Explorer interface
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
973
diff
changeset
|
930 with JavaScript code that uses the `jQuery Mobile framework |
1075 | 931 <https://demos.jquerymobile.com/1.1.0/>`__ (as of Orthanc 1.12.4, |
975
eb49a4ad8fbc
Python plugin: Extending the Orthanc Explorer interface
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
973
diff
changeset
|
932 version 1.1.0 of jQuery Mobile is used in Orthanc Explorer). |
eb49a4ad8fbc
Python plugin: Extending the Orthanc Explorer interface
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
973
diff
changeset
|
933 |
eb49a4ad8fbc
Python plugin: Extending the Orthanc Explorer interface
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
973
diff
changeset
|
934 * If clicking on the button, a GET call to the REST API is made to |
eb49a4ad8fbc
Python plugin: Extending the Orthanc Explorer interface
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
973
diff
changeset
|
935 ``../execute-python``. The prefix ``../`` stems from the fact that |
eb49a4ad8fbc
Python plugin: Extending the Orthanc Explorer interface
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
973
diff
changeset
|
936 Orthanc Explorer is branched inside the ``app/`` folder of the REST |
eb49a4ad8fbc
Python plugin: Extending the Orthanc Explorer interface
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
973
diff
changeset
|
937 API of Orthanc. |
eb49a4ad8fbc
Python plugin: Extending the Orthanc Explorer interface
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
973
diff
changeset
|
938 |
eb49a4ad8fbc
Python plugin: Extending the Orthanc Explorer interface
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
973
diff
changeset
|
939 * The GET call to ``../execute-python`` executes the |
eb49a4ad8fbc
Python plugin: Extending the Orthanc Explorer interface
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
973
diff
changeset
|
940 ``ExecutePython()`` callback function that is written in Python. |
eb49a4ad8fbc
Python plugin: Extending the Orthanc Explorer interface
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
973
diff
changeset
|
941 |
eb49a4ad8fbc
Python plugin: Extending the Orthanc Explorer interface
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
973
diff
changeset
|
942 Note that it is only possible to extend Orthanc Explorer 1, which is |
eb49a4ad8fbc
Python plugin: Extending the Orthanc Explorer interface
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
973
diff
changeset
|
943 the built-in Web interface of Orthanc. It is not possible to extend |
eb49a4ad8fbc
Python plugin: Extending the Orthanc Explorer interface
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
973
diff
changeset
|
944 the :ref:`Orthanc Explorer 2 <orthanc-explorer-2>` interface. |
eb49a4ad8fbc
Python plugin: Extending the Orthanc Explorer interface
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
973
diff
changeset
|
945 |
eb49a4ad8fbc
Python plugin: Extending the Orthanc Explorer interface
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
973
diff
changeset
|
946 |
1046 | 947 .. _python_mosaic: |
948 | |
949 Generating a mosaic for a DICOM series | |
950 ...................................... | |
951 | |
952 Thanks to the fact that Python plugins have access to :ref:`PIL/Pillow | |
953 <python-pil-thumbnail>`, it is quite easy to generate a mosaic from a | |
954 DICOM series: | |
955 | |
956 .. image:: python/mosaic.png | |
957 :align: center | |
958 :width: 512 | |
959 | |
960 Here is the source code: | |
961 | |
962 .. literalinclude:: python/mosaic.py | |
963 :language: python | |
964 | |
965 | |
351 | 966 Performance and concurrency |
967 --------------------------- | |
968 | |
471
a735476a0e6e
note about fork on windows
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
462
diff
changeset
|
969 **Important:** This section only applies to UNIX-like systems. The |
a735476a0e6e
note about fork on windows
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
462
diff
changeset
|
970 ``multiprocessing`` package will not work on Microsoft Windows as the |
a735476a0e6e
note about fork on windows
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
462
diff
changeset
|
971 latter OS has a different model for `forking processes |
a735476a0e6e
note about fork on windows
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
462
diff
changeset
|
972 <https://en.wikipedia.org/wiki/Fork_(system_call)>`__. |
a735476a0e6e
note about fork on windows
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
462
diff
changeset
|
973 |
555
6fb469a3c382
Python plugin: documentation of orthanc.GenerateRestApiAuthorizationToken()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
554
diff
changeset
|
974 Using slave processes |
6fb469a3c382
Python plugin: documentation of orthanc.GenerateRestApiAuthorizationToken()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
554
diff
changeset
|
975 ..................... |
6fb469a3c382
Python plugin: documentation of orthanc.GenerateRestApiAuthorizationToken()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
554
diff
changeset
|
976 |
351 | 977 Let us consider the following sample Python script that makes a |
702
6e02cd89eb6a
moving python samples in separate files
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
701
diff
changeset
|
978 CPU-intensive computation on a REST callback: |
351 | 979 |
702
6e02cd89eb6a
moving python samples in separate files
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
701
diff
changeset
|
980 .. literalinclude:: python/multiprocessing-1.py |
6e02cd89eb6a
moving python samples in separate files
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
701
diff
changeset
|
981 :language: python |
351 | 982 |
983 .. highlight:: text | |
984 | |
985 Calling this REST route from the command-line returns the time that is | |
986 needed to compute 30 million times a squared root on your CPU:: | |
987 | |
988 $ curl http://localhost:8042/computation | |
989 computation done in 4.208 seconds | |
990 | |
991 Now, let us call this route three times concurrently (we use bash):: | |
992 | |
993 $ (curl http://localhost:8042/computation & curl http://localhost:8042/computation & curl http://localhost:8042/computation ) | |
994 computation done in 11.262 seconds | |
995 computation done in 12.457 seconds | |
996 computation done in 13.360 seconds | |
997 | |
998 As can be seen, the computation time has tripled. This means that the | |
999 computations were not distributed across the available CPU cores. | |
1000 This might seem surprising, as Orthanc is a threaded server (in | |
1001 Orthanc, a pool of C++ threads serves concurrent requests). | |
1002 | |
1003 The explanation is that the Python interpreter (`CPython | |
1004 <https://en.wikipedia.org/wiki/CPython>`__ actually) is built on the | |
1005 top of a so-called `Global Interpreter Lock (GIL) | |
1006 <https://en.wikipedia.org/wiki/Global_interpreter_lock>`__. The GIL is | |
1007 basically a mutex that protects all the calls to the Python | |
1008 interpreter. If multiple C++ threads from Orthanc call a Python | |
353 | 1009 callback, only one can proceed at any given time. Note however that |
1010 the GIL only applies to the Python script: The baseline REST API of | |
1011 Orthanc is not affected by the GIL. | |
351 | 1012 |
1013 The solution is to use the `multiprocessing primitives | |
1014 <https://docs.python.org/3/library/multiprocessing.html>`__ of Python. | |
1015 The "master" Python interpreter that is initially started by the | |
1016 Orthanc plugin, can start several `children processes | |
1017 <https://en.wikipedia.org/wiki/Process_(computing)>`__, each of these | |
1018 processes running a separate Python interpreter. This allows to | |
1019 offload intensive computations from the "master" Python interpreter of | |
1020 Orthanc onto those "slave" interpreters. The ``multiprocessing`` | |
702
6e02cd89eb6a
moving python samples in separate files
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
701
diff
changeset
|
1021 library is actually quite straightforward to use: |
351 | 1022 |
702
6e02cd89eb6a
moving python samples in separate files
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
701
diff
changeset
|
1023 .. literalinclude:: python/multiprocessing-2.py |
6e02cd89eb6a
moving python samples in separate files
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
701
diff
changeset
|
1024 :language: python |
351 | 1025 |
1026 .. highlight:: text | |
1027 | |
1028 Here is now the result of calling this route three times concurrently:: | |
1029 | |
1030 $ (curl http://localhost:8042/computation & curl http://localhost:8042/computation & curl http://localhost:8042/computation ) | |
1031 computation done in 4.211 seconds | |
1032 computation done in 4.215 seconds | |
1033 computation done in 4.225 seconds | |
1034 | |
1035 As can be seen, the calls to the Python computation now fully run in | |
1036 parallel (the time is cut down from 12 seconds to 4 seconds, the same | |
1037 as for one isolated request). | |
1038 | |
1039 Note also how the ``multiprocessing`` library allows to make a fine | |
1040 control over the computational resources that are available to the | |
1041 Python script: The number of "slave" interpreters can be easily | |
1042 changed in the constructor of the ``multiprocessing.Pool`` object, and | |
1043 are fully independent of the threads used by the Orthanc server. | |
1044 | |
555
6fb469a3c382
Python plugin: documentation of orthanc.GenerateRestApiAuthorizationToken()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
554
diff
changeset
|
1045 Obviously, an in-depth discussion about the ``multiprocessing`` |
6fb469a3c382
Python plugin: documentation of orthanc.GenerateRestApiAuthorizationToken()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
554
diff
changeset
|
1046 library is out of the scope of this document. There are many |
6fb469a3c382
Python plugin: documentation of orthanc.GenerateRestApiAuthorizationToken()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
554
diff
changeset
|
1047 references available on Internet. Also, note that ``threading`` is not |
6fb469a3c382
Python plugin: documentation of orthanc.GenerateRestApiAuthorizationToken()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
554
diff
changeset
|
1048 useful here, as Python multithreading is also limited by the GIL, and |
6fb469a3c382
Python plugin: documentation of orthanc.GenerateRestApiAuthorizationToken()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
554
diff
changeset
|
1049 is more targeted at dealing with costly I/O operations or with the |
6fb469a3c382
Python plugin: documentation of orthanc.GenerateRestApiAuthorizationToken()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
554
diff
changeset
|
1050 :ref:`scheduling of commands <python-scheduler>`. |
6fb469a3c382
Python plugin: documentation of orthanc.GenerateRestApiAuthorizationToken()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
554
diff
changeset
|
1051 |
6fb469a3c382
Python plugin: documentation of orthanc.GenerateRestApiAuthorizationToken()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
554
diff
changeset
|
1052 |
6fb469a3c382
Python plugin: documentation of orthanc.GenerateRestApiAuthorizationToken()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
554
diff
changeset
|
1053 Slave processes and the "orthanc" module |
6fb469a3c382
Python plugin: documentation of orthanc.GenerateRestApiAuthorizationToken()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
554
diff
changeset
|
1054 ........................................ |
6fb469a3c382
Python plugin: documentation of orthanc.GenerateRestApiAuthorizationToken()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
554
diff
changeset
|
1055 |
6fb469a3c382
Python plugin: documentation of orthanc.GenerateRestApiAuthorizationToken()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
554
diff
changeset
|
1056 Very importantly, pay attention to the fact that **only the "master" |
6fb469a3c382
Python plugin: documentation of orthanc.GenerateRestApiAuthorizationToken()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
554
diff
changeset
|
1057 Python interpreter has access to the Orthanc SDK**. The "slave" |
6fb469a3c382
Python plugin: documentation of orthanc.GenerateRestApiAuthorizationToken()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
554
diff
changeset
|
1058 processes have no access to the ``orthanc`` module. |
6fb469a3c382
Python plugin: documentation of orthanc.GenerateRestApiAuthorizationToken()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
554
diff
changeset
|
1059 |
6fb469a3c382
Python plugin: documentation of orthanc.GenerateRestApiAuthorizationToken()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
554
diff
changeset
|
1060 You must write your Python plugin so as that all the calls to |
6fb469a3c382
Python plugin: documentation of orthanc.GenerateRestApiAuthorizationToken()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
554
diff
changeset
|
1061 ``orthanc`` are moved from the slaves process to the master |
6fb469a3c382
Python plugin: documentation of orthanc.GenerateRestApiAuthorizationToken()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
554
diff
changeset
|
1062 process. For instance, here is how you would parse a DICOM file in a |
702
6e02cd89eb6a
moving python samples in separate files
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
701
diff
changeset
|
1063 slave process: |
352 | 1064 |
702
6e02cd89eb6a
moving python samples in separate files
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
701
diff
changeset
|
1065 .. literalinclude:: python/multiprocessing-3.py |
6e02cd89eb6a
moving python samples in separate files
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
701
diff
changeset
|
1066 :language: python |
352 | 1067 |
1068 Communication primitives such as ``multiprocessing.Queue`` are | |
1069 available to exchange messages from the "slave" Python interpreters to | |
555
6fb469a3c382
Python plugin: documentation of orthanc.GenerateRestApiAuthorizationToken()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
554
diff
changeset
|
1070 the "master" Python interpreter for more advanced scenarios. |
6fb469a3c382
Python plugin: documentation of orthanc.GenerateRestApiAuthorizationToken()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
554
diff
changeset
|
1071 |
6fb469a3c382
Python plugin: documentation of orthanc.GenerateRestApiAuthorizationToken()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
554
diff
changeset
|
1072 NB: Starting with release 3.0 of the Python plugin, it is possible to |
6fb469a3c382
Python plugin: documentation of orthanc.GenerateRestApiAuthorizationToken()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
554
diff
changeset
|
1073 call the REST API of Orthanc from a slave process in a more direct |
6fb469a3c382
Python plugin: documentation of orthanc.GenerateRestApiAuthorizationToken()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
554
diff
changeset
|
1074 way. The function ``orthanc.GenerateRestApiAuthorizationToken()`` can |
6fb469a3c382
Python plugin: documentation of orthanc.GenerateRestApiAuthorizationToken()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
554
diff
changeset
|
1075 be used to create an authorization token that provides full access to |
6fb469a3c382
Python plugin: documentation of orthanc.GenerateRestApiAuthorizationToken()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
554
diff
changeset
|
1076 the REST API of Orthanc (without have to set credentials in your |
6fb469a3c382
Python plugin: documentation of orthanc.GenerateRestApiAuthorizationToken()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
554
diff
changeset
|
1077 plugin). Any HTTP client library for Python, such as `requests |
6fb469a3c382
Python plugin: documentation of orthanc.GenerateRestApiAuthorizationToken()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
554
diff
changeset
|
1078 <https://requests.readthedocs.io/en/master/>`__, can then be used to |
702
6e02cd89eb6a
moving python samples in separate files
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
701
diff
changeset
|
1079 access the REST API of Orthanc. Here is a minimal example: |
352 | 1080 |
702
6e02cd89eb6a
moving python samples in separate files
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
701
diff
changeset
|
1081 .. literalinclude:: python/multiprocessing-4.py |
6e02cd89eb6a
moving python samples in separate files
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
701
diff
changeset
|
1082 :language: python |
1018 | 1083 |
1084 Working with virtual environments | |
1085 --------------------------------- | |
1086 | |
1087 By default, Orthanc uses the system-wide Python installation and | |
1088 therefore has access to the python modules that have been installed | |
1089 system-wide. | |
1090 | |
1091 As of version 4.1 of the python plugin, there is no built-in support | |
1092 for working with a `virtual environment <https://docs.python.org/3/library/venv.html>`__. | |
1093 However, you may modify the python path at the very beginning of the script | |
1094 to instruct python to look for modules in your environment. | |
1095 | |
1096 **Example 1**: On a Linux system, consider that you have created a virtual environment in ``/tmp/.venv`` | |
1024 | 1097 and, you may just an environment variable to instruct the python interpreter to search for modules into |
1098 your virtual env. E.g, in a Docker container, you may implement it this way:: | |
1099 | |
1100 FROM orthancteam/orthanc-pre-release:bookworm | |
1101 | |
1025 | 1102 # This example is using a virtual env that is not mandatory when using Docker containers |
1103 # but recommended since python 3.11 and Debian bookworm based images where you get a warning | |
1104 # when installing system-wide packages. RUN apt-get update && apt install -y python3-venv | |
1024 | 1105 RUN python3 -m venv /.venv |
1106 | |
1107 RUN /.venv/bin/pip install pydicom | |
1108 ENV PYTHONPATH=/.venv/lib64/python3.11/site-packages/ | |
1109 | |
1110 RUN mkdir /python | |
1111 COPY * /python/ | |
1112 | |
1113 | |
1114 | |
1115 **Example 2**: On a Linux system, consider that you have created a virtual environment in ``/tmp/.venv`` | |
1018 | 1116 and you want to use only the modules that have been installed in this virtual environment. |
1117 In this case, you may simply rewrite ``sys.path``: | |
1118 | |
1119 .. literalinclude:: python/venv-linux.py | |
1120 :language: python | |
1121 | |
1122 | |
1041 | 1123 **Example 3**: On a Windows system, consider that you have created a virtual environment in ``C:/tmp/.venv/``. |
1018 | 1124 Instead of defining ``sys.path`` from scratch, it is possible to simply insert the venv-packages in |
1125 the ``sys.path``. By adding the ``venv`` to an early index (``0``), any package required by your code | |
1126 will be looked up in the ``venv`` first. And, as a consequence, if the package is not present, the system-wide | |
1127 installation of that package might be loaded: | |
1128 | |
1129 .. literalinclude:: python/venv-windows.py | |
1130 :language: python |