Mercurial > hg > orthanc-book
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) |