Mercurial > hg > orthanc-book
annotate Sphinx/source/users/lua.rst @ 1113:a588960a72e5 default tip
spelling
author | Alain Mazy <am@orthanc.team> |
---|---|
date | Mon, 28 Oct 2024 09:23:08 +0100 |
parents | fbd064a812eb |
children |
rev | line source |
---|---|
0 | 1 .. _lua: |
2 | |
3 Server-side scripting with Lua | |
4 ============================== | |
5 | |
6 .. contents:: | |
7 | |
8 Since release 0.5.2, Orthanc supports server-side scripting through | |
25 | 9 the `Lua <https://en.wikipedia.org/wiki/Lua_(programming_language)>`__ |
0 | 10 scripting language. Thanks to this major feature, Orthanc can be tuned |
11 to specific medical workflows without being driven by an external | |
12 script. This page summarizes the possibilities of Orthanc server-side | |
13 scripting. | |
14 | |
15 Many other examples are `available in the source distribution | |
991
1316bc62b5d5
migration to UCLouvain servers
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
913
diff
changeset
|
16 <https://orthanc.uclouvain.be/hg/orthanc/file/default/OrthancServer/Resources/Samples/Lua/>`__. |
0 | 17 |
606
2f000ee9b20d
removal of Lua callbacks for transfer syntaxes
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
449
diff
changeset
|
18 A more expressive alternative to Lua scripts is provided by |
999 | 19 :ref:`Python plugins <python-plugin>` and :ref:`Java plugins |
20 <java-plugin>`. | |
606
2f000ee9b20d
removal of Lua callbacks for transfer syntaxes
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
449
diff
changeset
|
21 |
0 | 22 |
75 | 23 Installing a Lua script |
0 | 24 ----------------------- |
25 | |
26 .. highlight:: bash | |
27 | |
28 A custom Lua script can be installed either by the :ref:`configuration | |
29 file <configuration>`, or by uploading it | |
30 through the :ref:`REST API <rest-samples>`. | |
31 | |
32 To install it by the **configuration file** method, you just have to | |
33 specify the path to the file containing the Lua script in the | |
357 | 34 ``LuaScripts`` variable. A comma-separated list of paths can be |
35 specified to install multiple scripts. | |
0 | 36 |
37 To upload a script stored in the file "``script.lua``" through the | |
38 **REST API**, use the following command:: | |
39 | |
40 $ curl -X POST http://localhost:8042/tools/execute-script --data-binary @script.lua | |
41 | |
42 Pay attention to the fact that, contrarily to the scripts installed | |
43 from the configuration file, the scripts installed through the REST | |
44 API are non-persistent: They are discarded after a restart of Orthanc, | |
45 which makes them useful for script prototyping. You can also interpret | |
46 a single Lua command through the REST API:: | |
47 | |
48 $ curl -X POST http://localhost:8042/tools/execute-script --data-binary "print(42)" | |
49 | |
50 *Note:* The ``--data-binary`` cURL option is used instead of | |
51 ``--data`` to prevent the interpretation of newlines by cURL, which is | |
52 `mandatory for the proper evaluation | |
358
011b01ccf52d
fixing external hyperlinks
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
357
diff
changeset
|
53 <https://stackoverflow.com/questions/3872427/how-to-send-line-break-with-curl>`__ |
011b01ccf52d
fixing external hyperlinks
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
357
diff
changeset
|
54 of the possible comments inside the Lua script. |
0 | 55 |
56 Lua API | |
57 ------- | |
58 | |
59 | |
60 .. _lua-callbacks: | |
61 | |
62 Callbacks to react to events | |
63 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | |
64 | |
355
e4e9cca89c64
clarified mutual exclusion of Lua scripts callbacks.
David Wikler <david.wikler@ulb.ac.be>
parents:
319
diff
changeset
|
65 The Lua engine of Orthanc invokes the following callbacks that |
0 | 66 are triggered on various events. Here are the **generic events**: |
67 | |
68 * ``function Initialize()``: Invoked as soon as the Orthanc server is started. | |
69 * ``function Finalize()``: Invoked just before the Orthanc server is stopped. | |
70 | |
71 Some **permission-related events** allow to filter incoming requests: | |
72 | |
387
1974913fd28a
documenting "info" argument in Lua ReceivedInstanceFilter()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
360
diff
changeset
|
73 * ``function ReceivedInstanceFilter(dicom, origin, info)``: Invoked to |
1974913fd28a
documenting "info" argument in Lua ReceivedInstanceFilter()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
360
diff
changeset
|
74 known whether an incoming DICOM instance should be |
0 | 75 accepted. :ref:`See this section <lua-filter-dicom>`. The ``origin`` |
387
1974913fd28a
documenting "info" argument in Lua ReceivedInstanceFilter()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
360
diff
changeset
|
76 parameter is :ref:`documented separately <lua-origin>`. The ``info`` |
1974913fd28a
documenting "info" argument in Lua ReceivedInstanceFilter()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
360
diff
changeset
|
77 parameter contains additional information and was added in Orthanc |
1974913fd28a
documenting "info" argument in Lua ReceivedInstanceFilter()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
360
diff
changeset
|
78 1.6.1. |
0 | 79 * ``function IncomingHttpRequestFilter(method, uri, ip, username, |
80 httpHeaders)``: Invoked to known whether a REST request should be | |
81 accepted. :ref:`See this section <lua-filter-rest>`. | |
82 | |
232 | 83 Some **job-related events** allow to react to :ref:`job <jobs>` completion/failure: |
84 | |
85 * ``function OnJobSubmitted(jobId)``: | |
86 Invoked when a new job has been submitted. Note that this does not | |
87 mean the the job execution has started. | |
88 * ``function OnJobFailure(jobId)``: | |
89 Invoked when a job has failed. | |
90 * ``function OnJobSuccess(jobId)``: | |
91 Invoked when a job has completed successfully. | |
92 | |
0 | 93 Some **DICOM-related events** allow to react to the reception of |
94 new medical images: | |
95 | |
96 * ``function OnStoredInstance(instanceId, tags, metadata, origin)``: | |
97 Invoked whenever a new instance has been stored into Orthanc. | |
98 This is especially useful for :ref:`lua-auto-routing`. The ``origin`` | |
99 parameter is :ref:`documented separately <lua-origin>`. | |
100 * ``function OnStablePatient(patientId, tags, metadata)``: Invoked | |
101 whenever a patient has not received any new instance for a certain | |
836 | 102 amount of time (cf. :ref:`stable resources <stable-resources>` |
103 and the option ``StableAge`` in the | |
0 | 104 :ref:`configuration file <configuration>`). The :ref:`identifier |
105 <orthanc-ids>` of the patient is provided, together with her DICOM | |
78 | 106 tags and her :ref:`metadata <metadata>`. |
0 | 107 * ``function OnStableSeries(seriesId, tags, metadata)``: Invoked |
108 whenever a series has not received any new instance for a certain | |
836 | 109 amount of time (cf. :ref:`stable resources <stable-resources>` |
110 and the option ``StableAge`` in the | |
111 :ref:`configuration file <configuration>`). | |
0 | 112 * ``function OnStableStudy(studyId, tags, metadata)``: Invoked |
113 whenever a study has not received any new instance for a certain | |
836 | 114 amount of time (cf. :ref:`stable resources <stable-resources>` |
115 and the option ``StableAge`` in the | |
116 :ref:`configuration file <configuration>`). | |
0 | 117 * ``function IncomingFindRequestFilter(source, origin)``: Invoked |
118 whenever Orthanc receives an incoming C-Find query through the DICOM | |
119 protocol. This allows to inspect the content of the C-Find query, | |
120 and possibly modify it if a patch is needed for some manufacturer. A | |
121 `sample script is available | |
991
1316bc62b5d5
migration to UCLouvain servers
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
913
diff
changeset
|
122 <https://orthanc.uclouvain.be/hg/orthanc/file/default/OrthancServer/Resources/Samples/Lua/IncomingFindRequestFilter.lua>`__. |
0 | 123 |
319
be69f8c86f56
Lua events for deleted/updated resources
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
283
diff
changeset
|
124 Some other **resource-related events** are available: |
be69f8c86f56
Lua events for deleted/updated resources
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
283
diff
changeset
|
125 |
be69f8c86f56
Lua events for deleted/updated resources
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
283
diff
changeset
|
126 * ``function OnDeletedPatient(patientId)``: Invoked when a patient has |
be69f8c86f56
Lua events for deleted/updated resources
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
283
diff
changeset
|
127 been removed from the Orthanc database (new in Orthanc 1.6.0). |
be69f8c86f56
Lua events for deleted/updated resources
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
283
diff
changeset
|
128 * ``function OnDeletedStudy(studyId)``: Invoked when a study has been |
be69f8c86f56
Lua events for deleted/updated resources
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
283
diff
changeset
|
129 removed from the Orthanc database (new in Orthanc 1.6.0). |
be69f8c86f56
Lua events for deleted/updated resources
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
283
diff
changeset
|
130 * ``function OnDeletedSeries(seriesId)``: Invoked when a series has |
be69f8c86f56
Lua events for deleted/updated resources
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
283
diff
changeset
|
131 been removed from the Orthanc database (new in Orthanc 1.6.0). |
be69f8c86f56
Lua events for deleted/updated resources
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
283
diff
changeset
|
132 * ``function OnDeletedInstance(instanceId)``: Invoked when a instance |
be69f8c86f56
Lua events for deleted/updated resources
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
283
diff
changeset
|
133 has been removed from the Orthanc database (new in Orthanc 1.6.0). |
be69f8c86f56
Lua events for deleted/updated resources
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
283
diff
changeset
|
134 * ``function OnUpdatedPatient(patientId)``: Invoked when some metadata |
be69f8c86f56
Lua events for deleted/updated resources
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
283
diff
changeset
|
135 or some attachment associated with the given patient has been |
be69f8c86f56
Lua events for deleted/updated resources
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
283
diff
changeset
|
136 updated (new in Orthanc 1.6.0). |
be69f8c86f56
Lua events for deleted/updated resources
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
283
diff
changeset
|
137 * ``function OnUpdatedStudy(studyId)``: Invoked when some metadata or |
be69f8c86f56
Lua events for deleted/updated resources
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
283
diff
changeset
|
138 some attachment associated with the given study has been updated |
be69f8c86f56
Lua events for deleted/updated resources
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
283
diff
changeset
|
139 (new in Orthanc 1.6.0). |
be69f8c86f56
Lua events for deleted/updated resources
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
283
diff
changeset
|
140 * ``function OnUpdatedSeries(seriesId)``: Invoked when some metadata |
be69f8c86f56
Lua events for deleted/updated resources
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
283
diff
changeset
|
141 or some attachment associated with the given series has been updated |
be69f8c86f56
Lua events for deleted/updated resources
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
283
diff
changeset
|
142 (new in Orthanc 1.6.0). |
be69f8c86f56
Lua events for deleted/updated resources
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
283
diff
changeset
|
143 * ``function OnUpdatedInstance(instanceId)``: Invoked when some |
be69f8c86f56
Lua events for deleted/updated resources
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
283
diff
changeset
|
144 metadata or some attachment associated with the given instance has |
be69f8c86f56
Lua events for deleted/updated resources
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
283
diff
changeset
|
145 been updated (new in Orthanc 1.6.0). |
606
2f000ee9b20d
removal of Lua callbacks for transfer syntaxes
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
449
diff
changeset
|
146 |
2f000ee9b20d
removal of Lua callbacks for transfer syntaxes
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
449
diff
changeset
|
147 Furthermore, in versions of Orthanc <= 1.8.2, whenever a DICOM |
2f000ee9b20d
removal of Lua callbacks for transfer syntaxes
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
449
diff
changeset
|
148 association is negotiated for C-Store SCP, several callbacks are |
2f000ee9b20d
removal of Lua callbacks for transfer syntaxes
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
449
diff
changeset
|
149 successively invoked to specify which **transfer syntaxes** are |
2f000ee9b20d
removal of Lua callbacks for transfer syntaxes
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
449
diff
changeset
|
150 accepted for the association. These callbacks are listed in `this |
2f000ee9b20d
removal of Lua callbacks for transfer syntaxes
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
449
diff
changeset
|
151 sample script |
991
1316bc62b5d5
migration to UCLouvain servers
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
913
diff
changeset
|
152 <https://orthanc.uclouvain.be/hg/orthanc/file/Orthanc-1.8.2/OrthancServer/Resources/Samples/Lua/TransferSyntaxEnable.lua>`__. |
606
2f000ee9b20d
removal of Lua callbacks for transfer syntaxes
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
449
diff
changeset
|
153 These callbacks were removed in Orthanc 1.9.0. |
0 | 154 |
357 | 155 If a callback is specified multiple times in separate scripts, the |
156 event handler of the latest loaded script is used. | |
0 | 157 |
912 | 158 Concurrency and deadlocks |
159 ^^^^^^^^^^^^^^^^^^^^^^^^^ | |
160 | |
161 Orthanc only implements a single Lua context. Therefore, all these | |
162 callbacks are guaranteed to be **invoked in mutual exclusion**. | |
163 This implies that Lua scripting in Orthanc does not support any | |
164 kind of concurrency but may also lead to some deadlocks. | |
165 | |
166 If a lua function (e.g. ``OnHeartBeat``) performs an HTTP call to an | |
167 external Rest API (e.g. ``http://myserver.com/orthanc_is_alive.php``) | |
168 which, in turn, calls the Orthanc Rest API (e.g. call ``http://orthanc:8042/system``), | |
169 odds are high that you meet a deadlock because Orthanc, when handling a | |
170 Rest API calls, may try to execute some Lua callbacks (e.g. ``IncomingHttpRequestFilter``) | |
171 while the Lua context is still blocked inside the ``OnHeartBeat`` function. | |
172 | |
173 To avoid deadlocks, always make sure to avoid such back-and-forth communications | |
174 or make sure they happen asynchronously: your webservice should call the | |
175 Orthanc Rest API after it has returned from the endpoint called by | |
176 ``OnHeartBeat``. | |
177 | |
913 | 178 Note that these deadlocks won't happen when a lua function calls its own |
179 Orthanc Rest API using the ``RestApiGet``, ``RestApiPost``, ... functions. | |
180 | |
0 | 181 |
182 .. _lua-rest: | |
183 | |
184 Calling the REST API of Orthanc | |
185 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | |
186 | |
187 Lua scripts have :ref:`full access to the REST API <rest>` of Orthanc | |
188 through the following functions: | |
189 | |
252
eaad8233e474
HTTP headers available for the RestApiXXX Lua function
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
237
diff
changeset
|
190 * ``RestApiGet(uri, builtin, headers)`` |
eaad8233e474
HTTP headers available for the RestApiXXX Lua function
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
237
diff
changeset
|
191 * ``RestApiPost(uri, body, builtin, headers)`` |
eaad8233e474
HTTP headers available for the RestApiXXX Lua function
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
237
diff
changeset
|
192 * ``RestApiPut(uri, body, builtin, headers)`` |
eaad8233e474
HTTP headers available for the RestApiXXX Lua function
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
237
diff
changeset
|
193 * ``RestApiDelete(uri, builtin, headers)`` |
0 | 194 |
237 | 195 Here is a description of the parameters: |
235
17f8eda5fccb
Documented some parameter types, expected string formatting and added samples.
Tomas Zubiri <me@tomaszubiri.com>
parents:
191
diff
changeset
|
196 |
237 | 197 * ``uri`` specifies the resource being accessed |
198 (e.g. ``/instances``). It must not include the URL schema | |
199 (protocol), hostname or port. | |
0 | 200 |
237 | 201 * In the context of a POST or PUT request, ``body`` is a string |
202 containing the body of the request | |
203 (e.g. ``{"Keep":"StudyDate"}``). This string will often correspond | |
204 to a JSON-formatted version of a `Lua table | |
205 <http://lua-users.org/wiki/TablesTutorial>`__. The ``DumpJson()`` | |
206 function (see below) is very useful to achieve this conversion from | |
207 a Lua table to a plain string. | |
235
17f8eda5fccb
Documented some parameter types, expected string formatting and added samples.
Tomas Zubiri <me@tomaszubiri.com>
parents:
191
diff
changeset
|
208 |
237 | 209 * ``builtin`` is an optional Boolean that specifies whether the |
210 request targets only the built-in REST API of Orthanc (if set to | |
211 ``true``), or the full the REST API after being tainted by plugins | |
212 (if set to ``false``). | |
235
17f8eda5fccb
Documented some parameter types, expected string formatting and added samples.
Tomas Zubiri <me@tomaszubiri.com>
parents:
191
diff
changeset
|
213 |
252
eaad8233e474
HTTP headers available for the RestApiXXX Lua function
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
237
diff
changeset
|
214 * ``headers`` is an optional argument and was added in release |
eaad8233e474
HTTP headers available for the RestApiXXX Lua function
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
237
diff
changeset
|
215 1.5.7. It allows to provide the REST API endpoint with HTTP headers. |
eaad8233e474
HTTP headers available for the RestApiXXX Lua function
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
237
diff
changeset
|
216 |
237 | 217 .. highlight:: bash |
218 | |
219 For instance:: | |
220 | |
221 RestApiPost('/instances/5af318ac-78fb-47ff-b0b0-0df18b0588e0/anonymize', '{}') | |
222 | |
0 | 223 |
783 | 224 Instance modification/routing |
225 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | |
226 | |
804
e7de02760b59
fix revision 783, to solve bug #203
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
783
diff
changeset
|
227 The Lua engine offers the following special functions to modify and |
e7de02760b59
fix revision 783, to solve bug #203
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
783
diff
changeset
|
228 route DICOM instances: |
783 | 229 |
230 * ``ModifyInstance(instanceId, replacements, removals, removePrivateTags)`` | |
804
e7de02760b59
fix revision 783, to solve bug #203
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
783
diff
changeset
|
231 modifies an instance. |
1111 | 232 * ``SendToModality(instanceId, modality)`` performs a synchronous C-Store to the |
804
e7de02760b59
fix revision 783, to solve bug #203
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
783
diff
changeset
|
233 target modality. |
1111 | 234 * ``SendToPeer(instanceId, peer)`` sends the instance to a remote Orthanc peer synchronously. |
783 | 235 * ``Delete(instanceId)`` deletes the instance. |
236 | |
804
e7de02760b59
fix revision 783, to solve bug #203
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
783
diff
changeset
|
237 :ref:`See this section <lua-auto-routing>` for examples. As can be |
e7de02760b59
fix revision 783, to solve bug #203
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
783
diff
changeset
|
238 seen in those examples, these special functions can be chained |
e7de02760b59
fix revision 783, to solve bug #203
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
783
diff
changeset
|
239 together, although they return no explicit value. |
e7de02760b59
fix revision 783, to solve bug #203
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
783
diff
changeset
|
240 |
e7de02760b59
fix revision 783, to solve bug #203
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
783
diff
changeset
|
241 Note that these special functions should only be used for basic use |
e7de02760b59
fix revision 783, to solve bug #203
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
783
diff
changeset
|
242 cases: Calls to the REST API :ref:`should always be favored for |
e7de02760b59
fix revision 783, to solve bug #203
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
783
diff
changeset
|
243 auto-routing <lua-auto-routing-better>`. |
e7de02760b59
fix revision 783, to solve bug #203
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
783
diff
changeset
|
244 |
783 | 245 |
0 | 246 General-purpose functions |
247 ^^^^^^^^^^^^^^^^^^^^^^^^^ | |
248 | |
249 The Lua engine of Orthanc contain several general-purpose ancillary | |
250 functions: | |
251 | |
252 * ``PrintRecursive(v)`` recursively prints the content of a `Lua table | |
253 <http://www.lua.org/pil/2.5.html>`__ to the log file of Orthanc. | |
254 * ``ParseJson(s)`` converts a string encoded in the `JSON format | |
255 <https://en.wikipedia.org/wiki/JSON>`__ to a Lua table. | |
256 * ``DumpJson(v, keepStrings)`` encodes a Lua table as a JSON string. | |
257 Setting the optional argument ``keepStrings`` (available from | |
258 release 0.9.5) to ``true`` prevents the automatic conversion of | |
259 strings to integers. | |
260 * ``GetOrthancConfiguration()`` returns a Lua table containing the | |
261 content of the :ref:`configuration files <configuration>` of | |
262 Orthanc. | |
263 | |
264 | |
265 Similarly to the functions to :ref:`call the REST API of Orthanc | |
266 <lua-rest>`, several functions are available to make generic HTTP | |
267 requests to Web services: | |
268 | |
90 | 269 * ``HttpGet(url, headers)`` |
270 * ``HttpPost(url, body, headers)`` | |
271 * ``HttpPut(url, body, headers)`` | |
272 * ``HttpDelete(url, headers)`` | |
0 | 273 * ``SetHttpCredentials(username, password)`` can be used to setup the |
274 HTTP credentials. | |
864 | 275 * ``SetHttpTimeout(timeout)`` can be used to configure a timeout (in seconds). |
276 When contacting an external webservice, it is recommended to configure a very | |
277 short timeout not to lock the Lua context for too long. No other Lua callbacks | |
278 may be run at the same time which may have a significant impact on Orthanc | |
1042 | 279 responsivness in general. This function has been introduced in version 1.11.1. |
864 | 280 |
0 | 281 |
252
eaad8233e474
HTTP headers available for the RestApiXXX Lua function
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
237
diff
changeset
|
282 The ``headers`` argument is optional and was added in release |
91 | 283 1.2.1. It allows to set the HTTP headers for the HTTP client request. |
0 | 284 |
283 | 285 Example:: |
286 | |
287 local preview = RestApiGet('/instances/' .. instanceId .. '/preview') | |
288 local headers = { | |
289 ["content-type"] = "image/png", | |
290 } | |
864 | 291 |
292 SetHttpCredentials('user', 'pwd') | |
293 SetHttpTimeout(1) | |
283 | 294 HttpPost("http://localhost/my-web-service/instance-preview", preview, headers) |
295 | |
0 | 296 .. _lua-origin: |
297 | |
298 Origin of the instances | |
299 ^^^^^^^^^^^^^^^^^^^^^^^ | |
300 | |
301 Whenever Orthanc decides whether it should should store a new instance | |
302 (cf. the ``ReceivedInstanceFilter()`` callback), or whenever it has | |
303 actually stored a new instance (cf. the ``OnStoredInstance`` | |
304 callback), an ``origin`` parameter is provided. This parameter is a | |
305 `Lua table <http://www.lua.org/pil/2.5.html>`__ that describes from | |
306 which Orthanc subsystem the new instance comes from. | |
307 | |
308 There are 4 possible subsystems, that can be distinguished according | |
309 to the value of ``origin["RequestOrigin"]``: | |
310 | |
311 * ``RestApi``: The instance originates from some HTTP request to the REST | |
312 API. In this case, the ``RemoteIp`` and ``Username`` fields are | |
313 available in ``origin``. They respectively describe the IP address | |
314 of the HTTP client, and the username that was used for HTTP | |
315 authentication (as defined in the ``RegisteredUsers`` | |
316 :ref:`configuration variable <configuration>`). | |
317 * ``DicomProtocol``: The instance originates from a DICOM C-Store. | |
318 The fields ``RemoteIp``, ``RemoteAet`` and ``CalledAet`` | |
319 respectively provide the IP address of the DICOM SCU (client), the | |
320 application entity title of the DICOM SCU client, and the | |
321 application entity title of the Orthanc SCP server. The | |
322 ``CalledAet`` can be used for :ref:`advanced auto-routing scenarios | |
323 <lua-auto-routing>`, when a single instance of Orthanc acts as a | |
324 proxy for several DICOM SCU clients. | |
325 * ``Lua``: The instance originates from a Lua script. | |
326 * ``Plugins``: The instance originates from a plugin. | |
327 | |
328 | |
329 .. _lua-filter-dicom: | |
330 | |
75 | 331 Filtering incoming DICOM instances |
0 | 332 ---------------------------------- |
333 | |
334 .. highlight:: lua | |
335 | |
336 Each time a DICOM instance is received by Orthanc (either through the | |
337 DICOM protocol or through the REST API), the | |
338 ``ReceivedInstanceFilter()`` Lua function is invoked. If this callback | |
339 returns ``true``, the instance is accepted for storage. If it returns | |
340 ``false``, the instance is discarded. This mechanism can be used to | |
341 filter the incoming DICOM instances. Here is an example of a Lua | |
342 filter that only allows incoming instances of MR modality:: | |
343 | |
387
1974913fd28a
documenting "info" argument in Lua ReceivedInstanceFilter()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
360
diff
changeset
|
344 function ReceivedInstanceFilter(dicom, origin, info) |
0 | 345 -- Only allow incoming MR images |
346 if dicom.Modality == 'MR' then | |
347 return true | |
348 else | |
349 return false | |
350 end | |
351 end | |
352 | |
387
1974913fd28a
documenting "info" argument in Lua ReceivedInstanceFilter()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
360
diff
changeset
|
353 The argument ``dicom`` corresponds to a `Lua table |
0 | 354 <http://www.lua.org/pil/2.5.html>`__ (i.e. an associative array) that |
355 contains the DICOM tags of the incoming instance. For debugging | |
356 purpose, you can print this structure as follows:: | |
357 | |
387
1974913fd28a
documenting "info" argument in Lua ReceivedInstanceFilter()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
360
diff
changeset
|
358 function ReceivedInstanceFilter(dicom, origin, info) |
0 | 359 PrintRecursive(dicom) |
360 -- Accept all incoming instances (default behavior) | |
361 return true | |
362 end | |
363 | |
364 The argument ``origin`` is :ref:`documented separately <lua-origin>`. | |
365 | |
387
1974913fd28a
documenting "info" argument in Lua ReceivedInstanceFilter()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
360
diff
changeset
|
366 The argument ``info`` was introduced in Orthanc 1.6.1. It contains |
1974913fd28a
documenting "info" argument in Lua ReceivedInstanceFilter()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
360
diff
changeset
|
367 some additional information about the received DICOM instance, |
1974913fd28a
documenting "info" argument in Lua ReceivedInstanceFilter()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
360
diff
changeset
|
368 notably: |
1974913fd28a
documenting "info" argument in Lua ReceivedInstanceFilter()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
360
diff
changeset
|
369 |
1974913fd28a
documenting "info" argument in Lua ReceivedInstanceFilter()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
360
diff
changeset
|
370 * ``HasPixelData`` is ``true`` iff. the Pixel Data (7FE0,0010) tag is |
1974913fd28a
documenting "info" argument in Lua ReceivedInstanceFilter()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
360
diff
changeset
|
371 present. |
1974913fd28a
documenting "info" argument in Lua ReceivedInstanceFilter()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
360
diff
changeset
|
372 * ``TransferSyntaxUID`` contains the transfer syntax UID of the |
1974913fd28a
documenting "info" argument in Lua ReceivedInstanceFilter()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
360
diff
changeset
|
373 dataset of the instance (if applicable). |
1974913fd28a
documenting "info" argument in Lua ReceivedInstanceFilter()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
360
diff
changeset
|
374 |
0 | 375 |
376 .. _lua-filter-rest: | |
377 | |
75 | 378 Filtering incoming REST requests |
0 | 379 -------------------------------- |
380 | |
381 .. highlight:: lua | |
382 | |
383 Lua scripting can be used to control the access to the various URI of | |
384 the REST API. Each time an incoming HTTP request is received, the | |
385 ``IncomingHttpRequestFilter()`` Lua function is called. The access to | |
386 the resource is granted if and only if this callback script returns | |
387 ``true``. | |
388 | |
389 This mechanism can be used to implement fine-grained `access control | |
25 | 390 lists <https://en.wikipedia.org/wiki/Access_control_list>`__. Here is |
0 | 391 an example of a Lua script that limits POST, PUT and DELETE requests |
392 to an user that is called "admin":: | |
393 | |
394 function IncomingHttpRequestFilter(method, uri, ip, username, httpHeaders) | |
395 -- Only allow GET requests for non-admin users | |
396 | |
397 if method == 'GET' then | |
398 return true | |
399 elseif username == 'admin' then | |
400 return true | |
401 else | |
402 return false | |
403 end | |
404 end | |
405 | |
406 Here is a description of the arguments of this Lua callback: | |
407 | |
408 * ``method``: The HTTP method (GET, POST, PUT or DELETE). | |
409 * ``uri``: The path to the resource (e.g. ``/tools/generate-uid``). | |
410 * ``ip``: The IP address of the host that has issued the HTTP request (e.g. ``127.0.0.1``). | |
411 * ``username``: If HTTP Basic Authentication is enabled in the | |
412 :ref:`configuration file <configuration>`, the name of the user that | |
413 has issued the HTTP request (as defined in the ``RegisteredUsers`` | |
414 configuration variable). If the authentication is disabled, this | |
415 argument is set to the empty string. | |
416 * ``httpHeaders``: The HTTP headers of the incoming request. This | |
417 argument is available since Orthanc 1.0.1. It is useful if the | |
418 authentication should be achieved through tokens, for instance | |
419 against a `LDAP | |
420 <https://en.wikipedia.org/wiki/Lightweight_Directory_Access_Protocol>`__ | |
421 or `OAuth2 <https://en.wikipedia.org/wiki/OAuth>`__ server. | |
422 | |
423 | |
424 .. _lua-auto-routing: | |
425 | |
75 | 426 Auto-routing of DICOM images |
0 | 427 ---------------------------- |
428 | |
429 .. highlight:: lua | |
430 | |
431 Since release 0.8.0, the routing of DICOM flows can be very easily | |
432 automated with Orthanc. All you have to do is to declare your | |
433 destination modality in the :ref:`configuration file <configuration>` | |
434 (section ``DicomModalities``), then to create and install a Lua | |
435 script. For instance, here is a sample script:: | |
436 | |
437 function OnStoredInstance(instanceId, tags, metadata) | |
438 Delete(SendToModality(instanceId, 'sample')) | |
439 end | |
440 | |
441 If this script is loaded into Orthanc, whenever a new DICOM instance | |
442 is received by Orthanc, it will be routed to the modality whose | |
443 symbolic name is ``sample`` (through a Store-SCU command), then it | |
444 will be removed from Orthanc. In other words, this is a **one-liner | |
445 script to implement DICOM auto-routing**. | |
446 | |
447 Very importantly, thanks to this feature, you do not have to use the | |
448 REST API or to create external scripts in order to automate simple | |
449 imaging flows. The scripting engine is entirely contained inside the | |
450 Orthanc core system. | |
451 | |
452 Thanks to Lua expressiveness, you can also implement conditional | |
453 auto-routing. For instance, if you wish to route only patients whose | |
454 name contains "David", you would simply write:: | |
455 | |
456 function OnStoredInstance(instanceId, tags, metadata) | |
457 -- Extract the value of the "PatientName" DICOM tag | |
458 local patientName = string.lower(tags['PatientName']) | |
459 | |
460 if string.find(patientName, 'david') ~= nil then | |
461 -- Only route patients whose name contains "David" | |
462 Delete(SendToModality(instanceId, 'sample')) | |
463 | |
464 else | |
465 -- Delete the patients that are not called "David" | |
466 Delete(instanceId) | |
467 end | |
468 end | |
469 | |
470 Besides ``SendToModality()``, a mostly identical function with the | |
471 same arguments called ``SendToPeer()`` can be used to route instances | |
472 to :ref:`Orthanc peers <peers>`. It is also possible to modify the | |
473 received instances before routing them. For instance, here is how you | |
474 would replace the ``StationName`` DICOM tag:: | |
475 | |
476 function OnStoredInstance(instanceId, tags, metadata) | |
477 -- Ignore the instances that result from a modification to avoid | |
478 -- infinite loops | |
479 if (metadata['ModifiedFrom'] == nil and | |
480 metadata['AnonymizedFrom'] == nil) then | |
481 | |
482 -- The tags to be replaced | |
483 local replace = {} | |
484 replace['StationName'] = 'My Medical Device' | |
485 | |
486 -- The tags to be removed | |
487 local remove = { 'MilitaryRank' } | |
488 | |
489 -- Modify the instance, send it, then delete the modified instance | |
490 Delete(SendToModality(ModifyInstance(instanceId, replace, remove, true), 'sample')) | |
491 | |
492 -- Delete the original instance | |
493 Delete(instanceId) | |
494 end | |
495 end | |
496 | |
497 | |
804
e7de02760b59
fix revision 783, to solve bug #203
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
783
diff
changeset
|
498 .. _lua-auto-routing-better: |
e7de02760b59
fix revision 783, to solve bug #203
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
783
diff
changeset
|
499 |
75 | 500 Important remarks about auto-routing |
501 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | |
19
c98317fedf87
note about autorouting
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
0
diff
changeset
|
502 |
c98317fedf87
note about autorouting
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
0
diff
changeset
|
503 The ``SendToModality()``, ``SendToPeer()``, ``ModifyInstance()`` and |
c98317fedf87
note about autorouting
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
0
diff
changeset
|
504 ``Delete()`` functions are for the most basic cases of auto-routing |
c98317fedf87
note about autorouting
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
0
diff
changeset
|
505 (implying a single DICOM instance, and possibly a basic modification |
c98317fedf87
note about autorouting
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
0
diff
changeset
|
506 of this instance). The ``ModifyInstance()`` function `could also lead |
c98317fedf87
note about autorouting
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
0
diff
changeset
|
507 to problems |
c98317fedf87
note about autorouting
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
0
diff
changeset
|
508 <https://groups.google.com/d/msg/orthanc-users/hmv2y-LgKm8/oMAuGJWMBgAJ>`__ |
c98317fedf87
note about autorouting
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
0
diff
changeset
|
509 if it deals with tags wrongly interpreted as numbers by Lua. |
c98317fedf87
note about autorouting
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
0
diff
changeset
|
510 |
c98317fedf87
note about autorouting
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
0
diff
changeset
|
511 For more evolved auto-routing scenarios, remember that Lua scripts |
191 | 512 :ref:`have full access to the REST API of Orthanc <lua-rest>`. This is |
19
c98317fedf87
note about autorouting
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
0
diff
changeset
|
513 illustrated by the ``AutoroutingModification.lua`` sample available in |
c98317fedf87
note about autorouting
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
0
diff
changeset
|
514 the source distribution of Orthanc:: |
c98317fedf87
note about autorouting
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
0
diff
changeset
|
515 |
c98317fedf87
note about autorouting
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
0
diff
changeset
|
516 function OnStoredInstance(instanceId, tags, metadata, origin) |
c98317fedf87
note about autorouting
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
0
diff
changeset
|
517 -- Ignore the instances that result from the present Lua script to |
c98317fedf87
note about autorouting
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
0
diff
changeset
|
518 -- avoid infinite loops |
c98317fedf87
note about autorouting
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
0
diff
changeset
|
519 if origin['RequestOrigin'] ~= 'Lua' then |
c98317fedf87
note about autorouting
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
0
diff
changeset
|
520 |
c98317fedf87
note about autorouting
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
0
diff
changeset
|
521 -- The tags to be replaced |
c98317fedf87
note about autorouting
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
0
diff
changeset
|
522 local replace = {} |
c98317fedf87
note about autorouting
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
0
diff
changeset
|
523 replace['StationName'] = 'My Medical Device' |
c98317fedf87
note about autorouting
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
0
diff
changeset
|
524 replace['0031-1020'] = 'Some private tag' |
c98317fedf87
note about autorouting
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
0
diff
changeset
|
525 |
c98317fedf87
note about autorouting
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
0
diff
changeset
|
526 -- The tags to be removed |
c98317fedf87
note about autorouting
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
0
diff
changeset
|
527 local remove = { 'MilitaryRank' } |
c98317fedf87
note about autorouting
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
0
diff
changeset
|
528 |
c98317fedf87
note about autorouting
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
0
diff
changeset
|
529 -- Modify the instance |
c98317fedf87
note about autorouting
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
0
diff
changeset
|
530 local command = {} |
c98317fedf87
note about autorouting
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
0
diff
changeset
|
531 command['Replace'] = replace |
c98317fedf87
note about autorouting
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
0
diff
changeset
|
532 command['Remove'] = remove |
c98317fedf87
note about autorouting
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
0
diff
changeset
|
533 local modifiedFile = RestApiPost('/instances/' .. instanceId .. '/modify', DumpJson(command, true)) |
c98317fedf87
note about autorouting
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
0
diff
changeset
|
534 |
c98317fedf87
note about autorouting
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
0
diff
changeset
|
535 -- Upload the modified instance to the Orthanc database so that |
c98317fedf87
note about autorouting
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
0
diff
changeset
|
536 -- it can be sent by Orthanc to other modalities |
c98317fedf87
note about autorouting
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
0
diff
changeset
|
537 local modifiedId = ParseJson(RestApiPost('/instances/', modifiedFile)) ['ID'] |
c98317fedf87
note about autorouting
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
0
diff
changeset
|
538 |
c98317fedf87
note about autorouting
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
0
diff
changeset
|
539 -- Send the modified instance to another modality |
c98317fedf87
note about autorouting
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
0
diff
changeset
|
540 RestApiPost('/modalities/sample/store', modifiedId) |
c98317fedf87
note about autorouting
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
0
diff
changeset
|
541 |
c98317fedf87
note about autorouting
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
0
diff
changeset
|
542 -- Delete the original and the modified instances |
c98317fedf87
note about autorouting
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
0
diff
changeset
|
543 RestApiDelete('/instances/' .. instanceId) |
c98317fedf87
note about autorouting
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
0
diff
changeset
|
544 RestApiDelete('/instances/' .. modifiedId) |
c98317fedf87
note about autorouting
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
0
diff
changeset
|
545 end |
c98317fedf87
note about autorouting
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
0
diff
changeset
|
546 end |
c98317fedf87
note about autorouting
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
0
diff
changeset
|
547 |
c98317fedf87
note about autorouting
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
0
diff
changeset
|
548 Also note that :ref:`other callbacks are available <lua-callbacks>` |
c98317fedf87
note about autorouting
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
0
diff
changeset
|
549 (``OnStablePatient()``, ``OnStableStudy()`` and ``OnStableSeries()``) |
c98317fedf87
note about autorouting
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
0
diff
changeset
|
550 to react to other events than the reception of a single instance |
c98317fedf87
note about autorouting
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
0
diff
changeset
|
551 with ``OnStoredInstance()``. |
75 | 552 |
99
e83da2f99e45
added 'troubleshooting C-Find queries' in the worklist section
amazy
parents:
91
diff
changeset
|
553 .. _lua-fix-cfind: |
75 | 554 |
77
48c7d2eb98da
Fixing C-Find requests
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
75
diff
changeset
|
555 Fixing C-Find requests |
48c7d2eb98da
Fixing C-Find requests
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
75
diff
changeset
|
556 ---------------------- |
75 | 557 |
558 :ref:`C-Find requests <dicom-find>` are sometimes interpreted | |
77
48c7d2eb98da
Fixing C-Find requests
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
75
diff
changeset
|
559 differently by different DICOM servers (e.g. the ``*`` wildcard, as |
48c7d2eb98da
Fixing C-Find requests
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
75
diff
changeset
|
560 `reported by users |
48c7d2eb98da
Fixing C-Find requests
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
75
diff
changeset
|
561 <https://groups.google.com/d/msg/orthanc-users/3g7V7kqr3g0/IREL88RWAwAJ>`__), |
48c7d2eb98da
Fixing C-Find requests
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
75
diff
changeset
|
562 and sometimes a querying modality might set unexpected DICOM tags |
48c7d2eb98da
Fixing C-Find requests
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
75
diff
changeset
|
563 (cf. `this real-world example |
48c7d2eb98da
Fixing C-Find requests
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
75
diff
changeset
|
564 <https://groups.google.com/d/msg/orthanc-users/PLWKqVVaXLs/n_0x4vKhAgAJ>`__). In |
48c7d2eb98da
Fixing C-Find requests
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
75
diff
changeset
|
565 such situations, it is possible to dynamically fix incoming or |
48c7d2eb98da
Fixing C-Find requests
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
75
diff
changeset
|
566 outgoing C-Find queries using a Lua script. |
48c7d2eb98da
Fixing C-Find requests
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
75
diff
changeset
|
567 |
165
b879a6274065
IncomingWorklistRequestFilter
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
105
diff
changeset
|
568 Sanitizing incoming C-Find requests can be done by implementing the |
77
48c7d2eb98da
Fixing C-Find requests
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
75
diff
changeset
|
569 ``IncomingFindRequestFilter(query, origin)`` callback that is called |
48c7d2eb98da
Fixing C-Find requests
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
75
diff
changeset
|
570 whenever the Orthanc C-Find SCP is queried by a remote modality. For |
48c7d2eb98da
Fixing C-Find requests
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
75
diff
changeset
|
571 instance, here is Lua script to remove a private tag that is specified |
48c7d2eb98da
Fixing C-Find requests
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
75
diff
changeset
|
572 by some manufacturer:: |
48c7d2eb98da
Fixing C-Find requests
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
75
diff
changeset
|
573 |
48c7d2eb98da
Fixing C-Find requests
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
75
diff
changeset
|
574 function IncomingFindRequestFilter(query, origin) |
48c7d2eb98da
Fixing C-Find requests
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
75
diff
changeset
|
575 -- First display the content of the C-Find query |
48c7d2eb98da
Fixing C-Find requests
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
75
diff
changeset
|
576 PrintRecursive(query) |
48c7d2eb98da
Fixing C-Find requests
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
75
diff
changeset
|
577 PrintRecursive(origin) |
48c7d2eb98da
Fixing C-Find requests
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
75
diff
changeset
|
578 |
48c7d2eb98da
Fixing C-Find requests
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
75
diff
changeset
|
579 -- Remove the "PrivateCreator" tag from the query |
48c7d2eb98da
Fixing C-Find requests
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
75
diff
changeset
|
580 local v = query |
48c7d2eb98da
Fixing C-Find requests
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
75
diff
changeset
|
581 v['5555,0010'] = nil |
48c7d2eb98da
Fixing C-Find requests
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
75
diff
changeset
|
582 |
48c7d2eb98da
Fixing C-Find requests
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
75
diff
changeset
|
583 return v |
48c7d2eb98da
Fixing C-Find requests
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
75
diff
changeset
|
584 end |
48c7d2eb98da
Fixing C-Find requests
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
75
diff
changeset
|
585 |
48c7d2eb98da
Fixing C-Find requests
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
75
diff
changeset
|
586 The ``origin`` argument contains information about which modality has |
48c7d2eb98da
Fixing C-Find requests
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
75
diff
changeset
|
587 issued the request. |
48c7d2eb98da
Fixing C-Find requests
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
75
diff
changeset
|
588 |
443
c66d8b7b1a13
more info about IncomingFindRequestFilter
Alain Mazy <alain@mazy.be>
parents:
387
diff
changeset
|
589 Note that this callback allows you to modify the incoming request |
c66d8b7b1a13
more info about IncomingFindRequestFilter
Alain Mazy <alain@mazy.be>
parents:
387
diff
changeset
|
590 but will not modify the list of tags that Orthanc will return. |
c66d8b7b1a13
more info about IncomingFindRequestFilter
Alain Mazy <alain@mazy.be>
parents:
387
diff
changeset
|
591 |
c66d8b7b1a13
more info about IncomingFindRequestFilter
Alain Mazy <alain@mazy.be>
parents:
387
diff
changeset
|
592 Also note that the ``IncomingFindRequestFilter`` callback is not applied to |
165
b879a6274065
IncomingWorklistRequestFilter
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
105
diff
changeset
|
593 C-Find requests targeting :ref:`modality worklists |
b879a6274065
IncomingWorklistRequestFilter
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
105
diff
changeset
|
594 <worklists-plugin>`. Since Orthanc 1.4.2, the corresponding |
b879a6274065
IncomingWorklistRequestFilter
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
105
diff
changeset
|
595 ``IncomingWorklistRequestFilter`` callback can be used to sanitize |
b879a6274065
IncomingWorklistRequestFilter
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
105
diff
changeset
|
596 C-FIND requests against worklists:: |
b879a6274065
IncomingWorklistRequestFilter
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
105
diff
changeset
|
597 |
b879a6274065
IncomingWorklistRequestFilter
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
105
diff
changeset
|
598 function IncomingWorklistRequestFilter(query, origin) |
b879a6274065
IncomingWorklistRequestFilter
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
105
diff
changeset
|
599 PrintRecursive(query) |
b879a6274065
IncomingWorklistRequestFilter
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
105
diff
changeset
|
600 PrintRecursive(origin) |
b879a6274065
IncomingWorklistRequestFilter
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
105
diff
changeset
|
601 |
b879a6274065
IncomingWorklistRequestFilter
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
105
diff
changeset
|
602 -- Implements the same behavior as the "FilterIssuerAet" |
b879a6274065
IncomingWorklistRequestFilter
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
105
diff
changeset
|
603 -- option of the sample worklist plugin |
b879a6274065
IncomingWorklistRequestFilter
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
105
diff
changeset
|
604 query['0040,0100'][1]['0040,0001'] = origin['RemoteAet'] |
b879a6274065
IncomingWorklistRequestFilter
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
105
diff
changeset
|
605 |
b879a6274065
IncomingWorklistRequestFilter
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
105
diff
changeset
|
606 return query |
b879a6274065
IncomingWorklistRequestFilter
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
105
diff
changeset
|
607 end |
105
268ec482f051
IncomingFindRequestFilter not applied to worklist plugin
amazy
parents:
99
diff
changeset
|
608 |
443
c66d8b7b1a13
more info about IncomingFindRequestFilter
Alain Mazy <alain@mazy.be>
parents:
387
diff
changeset
|
609 |
77
48c7d2eb98da
Fixing C-Find requests
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
75
diff
changeset
|
610 Similarly, the callback ``OutgoingFindRequestFilter(query, modality)`` |
48c7d2eb98da
Fixing C-Find requests
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
75
diff
changeset
|
611 is invoked whenever Orthanc acts as a C-Find SCU, which gives the |
48c7d2eb98da
Fixing C-Find requests
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
75
diff
changeset
|
612 opportunity to dynamically fix outgoing C-Find requests before they |
48c7d2eb98da
Fixing C-Find requests
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
75
diff
changeset
|
613 are actually sent to the queried modality. For instance, here is a |
48c7d2eb98da
Fixing C-Find requests
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
75
diff
changeset
|
614 sample Lua callback that would replace asterisk wildcards (i.e. ``*``) |
48c7d2eb98da
Fixing C-Find requests
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
75
diff
changeset
|
615 by an empty string for any query/retrieve issued by Orthanc (including |
48c7d2eb98da
Fixing C-Find requests
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
75
diff
changeset
|
616 from Orthanc Explorer):: |
48c7d2eb98da
Fixing C-Find requests
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
75
diff
changeset
|
617 |
48c7d2eb98da
Fixing C-Find requests
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
75
diff
changeset
|
618 function OutgoingFindRequestFilter(query, modality) |
48c7d2eb98da
Fixing C-Find requests
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
75
diff
changeset
|
619 for key, value in pairs(query) do |
48c7d2eb98da
Fixing C-Find requests
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
75
diff
changeset
|
620 if value == '*' then |
48c7d2eb98da
Fixing C-Find requests
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
75
diff
changeset
|
621 query[key] = '' |
48c7d2eb98da
Fixing C-Find requests
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
75
diff
changeset
|
622 end |
48c7d2eb98da
Fixing C-Find requests
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
75
diff
changeset
|
623 end |
48c7d2eb98da
Fixing C-Find requests
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
75
diff
changeset
|
624 |
48c7d2eb98da
Fixing C-Find requests
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
75
diff
changeset
|
625 return query |
48c7d2eb98da
Fixing C-Find requests
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
75
diff
changeset
|
626 end |
668 | 627 |
628 | |
864 | 629 HeartBeat |
630 --------- | |
631 | |
632 .. highlight:: lua | |
633 | |
634 Starting from Orthanc 1.11.1, one can run a Lua callback at regular | |
635 interval. This interval is defined in the ``LuaHeartBeatPeriod`` | |
636 configuration:: | |
637 | |
638 function OnHeartBeat() | |
639 | |
640 -- ping a webservice to notify that Orthanc is still alive | |
641 SetHttpCredentials('user', 'pwd') | |
642 SetHttpTimeout(1) | |
643 HttpPost("http://localhost/my-web-service/still-alive", "my-id", {}) | |
644 | |
645 end | |
646 | |
668 | 647 .. _lua-external-modules: |
648 | |
649 Using external modules | |
650 ---------------------- | |
651 | |
652 Starting with Orthanc 1.3.2, it is possible to use external Lua | |
653 modules if Orthanc was compiled with the ``-DENABLE_LUA_MODULES=ON`` | |
654 while invoking CMake. | |
655 | |
656 Importantly, the modules and the Orthanc server must use the same | |
657 version of Lua for external modules to be properly loaded. | |
658 | |
659 Check out the Orthanc Users forum for old discussions about this | |
660 topic: `reference 1 | |
661 <https://groups.google.com/g/orthanc-users/c/BXfmwU786B0/m/M47slt5GFwAJ>`__, | |
662 `reference 2 | |
663 <https://groups.google.com/g/orthanc-users/c/BXfmwU786B0/m/qpVe8UvGAwAJ>`__, | |
664 `reference 3 | |
665 <https://groups.google.com/g/orthanc-users/c/LDAN5jA0X8M/m/4zrk0_AaBAAJ>`__. |