comparison Sphinx/source/plugins/python.rst @ 555:6fb469a3c382

Python plugin: documentation of orthanc.GenerateRestApiAuthorizationToken()
author Sebastien Jodogne <s.jodogne@gmail.com>
date Tue, 08 Dec 2020 16:46:50 +0100
parents 4f3a6145ae34
children 6a3d48510b0b
comparison
equal deleted inserted replaced
554:4f3a6145ae34 555:6fb469a3c382
716 **Important:** This section only applies to UNIX-like systems. The 716 **Important:** This section only applies to UNIX-like systems. The
717 ``multiprocessing`` package will not work on Microsoft Windows as the 717 ``multiprocessing`` package will not work on Microsoft Windows as the
718 latter OS has a different model for `forking processes 718 latter OS has a different model for `forking processes
719 <https://en.wikipedia.org/wiki/Fork_(system_call)>`__. 719 <https://en.wikipedia.org/wiki/Fork_(system_call)>`__.
720 720
721 Using slave processes
722 .....................
723
721 .. highlight:: python 724 .. highlight:: python
722 725
723 Let us consider the following sample Python script that makes a 726 Let us consider the following sample Python script that makes a
724 CPU-intensive computation on a REST callback:: 727 CPU-intensive computation on a REST callback::
725 728
835 control over the computational resources that are available to the 838 control over the computational resources that are available to the
836 Python script: The number of "slave" interpreters can be easily 839 Python script: The number of "slave" interpreters can be easily
837 changed in the constructor of the ``multiprocessing.Pool`` object, and 840 changed in the constructor of the ``multiprocessing.Pool`` object, and
838 are fully independent of the threads used by the Orthanc server. 841 are fully independent of the threads used by the Orthanc server.
839 842
840 .. highlight:: python 843 Obviously, an in-depth discussion about the ``multiprocessing``
841 844 library is out of the scope of this document. There are many
842 Very importantly, pay attention to the fact that only the "master" 845 references available on Internet. Also, note that ``threading`` is not
843 Python interpreter has access to the Orthanc SDK. For instance, here 846 useful here, as Python multithreading is also limited by the GIL, and
844 is how you would parse a DICOM file in a slave process:: 847 is more targeted at dealing with costly I/O operations or with the
848 :ref:`scheduling of commands <python-scheduler>`.
849
850
851 Slave processes and the "orthanc" module
852 ........................................
853
854 .. highlight:: python
855
856 Very importantly, pay attention to the fact that **only the "master"
857 Python interpreter has access to the Orthanc SDK**. The "slave"
858 processes have no access to the ``orthanc`` module.
859
860 You must write your Python plugin so as that all the calls to
861 ``orthanc`` are moved from the slaves process to the master
862 process. For instance, here is how you would parse a DICOM file in a
863 slave process::
845 864
846 import pydicom 865 import pydicom
847 import io 866 import io
848 867
849 def OffloadedDicomParsing(dicom): 868 def OffloadedDicomParsing(dicom):
857 answer = POOL.apply(OffloadedDicomParsing, args = (dicom, )) 876 answer = POOL.apply(OffloadedDicomParsing, args = (dicom, ))
858 output.AnswerBuffer(answer, 'text/plain') 877 output.AnswerBuffer(answer, 'text/plain')
859 878
860 Communication primitives such as ``multiprocessing.Queue`` are 879 Communication primitives such as ``multiprocessing.Queue`` are
861 available to exchange messages from the "slave" Python interpreters to 880 available to exchange messages from the "slave" Python interpreters to
862 the "master" Python interpreter if further calls to the Orthanc SDK 881 the "master" Python interpreter for more advanced scenarios.
863 are required. 882
864 883 NB: Starting with release 3.0 of the Python plugin, it is possible to
865 Obviously, an in-depth discussion about the ``multiprocessing`` 884 call the REST API of Orthanc from a slave process in a more direct
866 library is out of the scope of this document. There are many 885 way. The function ``orthanc.GenerateRestApiAuthorizationToken()`` can
867 references available on Internet. Also, note that ``threading`` is not 886 be used to create an authorization token that provides full access to
868 useful here, as Python multithreading is also limited by the GIL, and 887 the REST API of Orthanc (without have to set credentials in your
869 is more targeted at dealing with costly I/O operations or with the 888 plugin). Any HTTP client library for Python, such as `requests
870 :ref:`scheduling of commands <python-scheduler>`. 889 <https://requests.readthedocs.io/en/master/>`__, can then be used to
890 access the REST API of Orthanc. Here is a minimal example::
891
892 import json
893 import multiprocessing
894 import orthanc
895 import requests
896 import signal
897
898 TOKEN = orthanc.GenerateRestApiAuthorizationToken()
899
900 def SlaveProcess():
901 r = requests.get('http://localhost:8042/instances',
902 headers = { 'Authorization' : TOKEN })
903 return json.dumps(r.json())
904
905 def Initializer():
906 signal.signal(signal.SIGINT, signal.SIG_IGN)
907
908 POOL = multiprocessing.Pool(4, initializer = Initializer)
909
910 def OnRest(output, uri, **request):
911 answer = POOL.apply(SlaveProcess)
912 output.AnswerBuffer(answer, 'text/plain')
913
914 orthanc.RegisterRestCallback('/computation', OnRest)