Mercurial > hg > orthanc-book
view Sphinx/source/users/rest.rst @ 1:1b6f12b8a54b
license in footer
author | Sebastien Jodogne <s.jodogne@gmail.com> |
---|---|
date | Fri, 22 Apr 2016 14:18:42 +0200 |
parents | 901e8961f46e |
children | 669ea65ba7fb |
line wrap: on
line source
.. _rest: REST API of Orthanc =================== .. contents:: :depth: 3 One of the major strengths of Orthanc lies in its built-in `RESTful API <https://en.wikipedia.org/wiki/Representational_state_transfer>`__, that can be used to drive Orthanc from external applications, independently of the programming language that is used to develop these applications. The REST API of Orthanc gives a full programmatic access to all the core features of Orthanc. Importantly, Orthanc Explorer (the embedded administrative interface of Orthanc) entirely resorts to this REST API for all its features. This implies that anything that can be done through Orthanc Explorer, can also be done through REST queries. *Note:* All the examples are illustrated with the `cURL command-line tool <http://curl.haxx.se/>`__, but equivalent calls can be readily transposed to any programming language that supports both HTTP and JSON. Sending DICOM images -------------------- .. highlight:: bash The upload of DICOM files is possible by querying the REST API using the following syntax:: $ curl -X POST http://localhost:8042/instances --data-binary @CT.X.1.2.276.0.7230010.dcm .. highlight:: json Orthanc will respond with a JSON file that contain information about the location of the stored instance, such as:: { "ID" : "e87da270-c52b-4f2a-b8c6-bae25928d0b0", "Path" : "/instances/e87da270-c52b-4f2a-b8c6-bae25928d0b0", "Status" : "Success" } .. highlight:: bash Note that in the case of curl, setting the ``Expect`` HTTP Header will significantly `reduce the execution time of POST requests <http://stackoverflow.com/a/463277/881731>`__:: $ curl -X POST -H "Expect:" http://localhost:8042/instances --data-binary @CT.X.1.2.276.0.7230010.dcm The code distribution of Orthanc contains a `sample Python script <https://bitbucket.org/sjodogne/orthanc/src/default/Resources/Samples/ImportDicomFiles/ImportDicomFiles.py>`__ that recursively upload the content of some folder into Orthanc using the REST API:: $ python ImportDicomFiles.py localhost 8042 ~/DICOM/ .. _rest-access: Accessing the content of Orthanc -------------------------------- Orthanc structures the stored DICOM resources using the "Patient, Study, Series, Instance" model of the DICOM standard. Each DICOM resource is associated with an :ref:`unique identifier <orthanc-ids>`. List all the DICOM resources ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Here is how you would list all the DICOM resources that are stored in your local Orthanc instance:: $ curl http://localhost:8042/patients $ curl http://localhost:8042/studies $ curl http://localhost:8042/series $ curl http://localhost:8042/instances Note that the result of this command is a `JSON file <http://en.wikipedia.org/wiki/Json>`__ that contains an array of resource identifiers. The JSON file format is lightweight and can be parsed from almost any computer language. Accessing a patient ^^^^^^^^^^^^^^^^^^^ .. highlight:: bash To access a single resource, add its identifier to the `URI <http://en.wikipedia.org/wiki/Uniform_resource_identifier>`__. You would for instance retrieve the main information about one patient as follows:: $ curl http://localhost:8042/patients/dc65762c-f476e8b9-898834f4-2f8a5014-2599bc94 .. highlight:: json Here is a possible answer from Orthanc:: { "ID" : "07a6ec1c-1be5920b-18ef5358-d24441f3-10e926ea", "MainDicomTags" : { "OtherPatientIDs" : "(null)", "PatientBirthDate" : "0", "PatientID" : "000000185", "PatientName" : "Anonymous^Unknown", "PatientSex" : "O" }, "Studies" : [ "9ad2b0da-a406c43c-6e0df76d-1204b86f-78d12c15" ], "Type" : "Patient" } This is once again a JSON file. Note how Orthanc gives you a summary of the main DICOM tags that correspond to the patient level. Browsing from the patient down to the instance ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ .. highlight:: bash The field ``Studies`` list all the DICOM studies that are associated with the patient. So, considering the patient above, we would go down in her DICOM hierarchy as follows:: $ curl http://localhost:8042/studies/9ad2b0da-a406c43c-6e0df76d-1204b86f-78d12c15 .. highlight:: json And Orthanc could answer:: { "ID" : "9ad2b0da-a406c43c-6e0df76d-1204b86f-78d12c15", "MainDicomTags" : { "AccessionNumber" : "(null)", "StudyDate" : "20120716", "StudyDescription" : "TestSUVce-TF", "StudyID" : "23848", "StudyInstanceUID" : "1.2.840.113704.1.111.7016.1342451220.40", "StudyTime" : "170728" }, "ParentPatient" : "07a6ec1c-1be5920b-18ef5358-d24441f3-10e926ea", "Series" : [ "6821d761-31fb55a9-031ebecb-ba7f9aae-ffe4ddc0", "2cc6336f-2d4ae733-537b3ca3-e98184b1-ba494b35", "7384c47e-6398f2a8-901846ef-da1e2e0b-6c50d598" ], "Type" : "Study" } .. highlight:: bash The main DICOM tags are now those that are related to the study level. It is possible to retrieve the identifier of the patient in the ``ParentPatient`` field, which can be used to go upward the DICOM hierarchy. But let us rather go down to the series level by using the ``Series`` array. The next command would return information about one of the three series that have just been reported:: $ curl http://localhost:8042/series/2cc6336f-2d4ae733-537b3ca3-e98184b1-ba494b35 .. highlight:: json Here is a possible answer:: { "ExpectedNumberOfInstances" : 45, "ID" : "2cc6336f-2d4ae733-537b3ca3-e98184b1-ba494b35", "Instances" : [ "41bc3f74-360f9d10-6ae9ffa4-01ea2045-cbd457dd", "1d3de868-6c4f0494-709fd140-7ccc4c94-a6daa3a8", <...> "1010f80b-161b71c0-897ec01b-c85cd206-e669a3ea", "e668dcbf-8829a100-c0bd203b-41e404d9-c533f3d4" ], "MainDicomTags" : { "Manufacturer" : "Philips Medical Systems", "Modality" : "PT", "NumberOfSlices" : "45", "ProtocolName" : "CHU/Body_PET/CT___50", "SeriesDate" : "20120716", "SeriesDescription" : "[WB_CTAC] Body", "SeriesInstanceUID" : "1.3.46.670589.28.2.12.30.26407.37145.2.2516.0.1342458737", "SeriesNumber" : "587370", "SeriesTime" : "171121", "StationName" : "r054-svr" }, "ParentStudy" : "9ad2b0da-a406c43c-6e0df76d-1204b86f-78d12c15", "Status" : "Complete", "Type" : "Series" } It can be seen that this series comes from a PET modality. Orthanc has computed that this series should contain 45 instances. .. highlight:: bash So far, we have navigated from the patient level, to the study level, and finally to the series level. There only remains the instance level. Let us dump the content of one of the instances:: $ curl http://localhost:8042/instances/e668dcbf-8829a100-c0bd203b-41e404d9-c533f3d4 .. highlight:: json The instance contains the following information:: { "FileSize" : 70356, "FileUuid" : "3fd265f0-c2b6-41a2-ace8-ae332db63e06", "ID" : "e668dcbf-8829a100-c0bd203b-41e404d9-c533f3d4", "IndexInSeries" : 6, "MainDicomTags" : { "ImageIndex" : "6", "InstanceCreationDate" : "20120716", "InstanceCreationTime" : "171344", "InstanceNumber" : "6", "SOPInstanceUID" : "1.3.46.670589.28.2.15.30.26407.37145.3.2116.39.1342458737" }, "ParentSeries" : "2cc6336f-2d4ae733-537b3ca3-e98184b1-ba494b35", "Type" : "Instance" } .. highlight:: bash The instance has the index 6 in the parent series. The instance is stored as a raw DICOM file of 70356 bytes. You would download this DICOM file using the following command:: $ curl http://localhost:8042/instances/e668dcbf-8829a100-c0bd203b-41e404d9-c533f3d4/file > Instance.dcm Accessing the DICOM fields of an instance as a JSON file ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ .. highlight:: bash When one gets to the instance level, you can retrieve the hierarchy of all the DICOM tags of this instance as a JSON file:: $ curl http://localhost:8042/instances/e668dcbf-8829a100-c0bd203b-41e404d9-c533f3d4/simplified-tags .. highlight:: json Here is a excerpt of the Orthanc answer:: { "ACR_NEMA_2C_VariablePixelDataGroupLength" : "57130", "AccessionNumber" : null, "AcquisitionDate" : "20120716", "AcquisitionDateTime" : "20120716171219", "AcquisitionTime" : "171219", "ActualFrameDuration" : "3597793", "AttenuationCorrectionMethod" : "CTAC-SG", <...> "PatientID" : "000000185", "PatientName" : "Anonymous^Unknown", "PatientOrientationCodeSequence" : [ { "CodeMeaning" : "recumbent", "CodeValue" : "F-10450", "CodingSchemeDesignator" : "99SDM", "PatientOrientationModifierCodeSequence" : [ { "CodeMeaning" : "supine", "CodeValue" : "F-10340", "CodingSchemeDesignator" : "99SDM" } ] } ], <...> "StudyDescription" : "TestSUVce-TF", "StudyID" : "23848", "StudyInstanceUID" : "1.2.840.113704.1.111.7016.1342451220.40", "StudyTime" : "171117", "TypeOfDetectorMotion" : "NONE", "Units" : "BQML", "Unknown" : null, "WindowCenter" : "1.496995e+04", "WindowWidth" : "2.993990e+04" } .. highlight:: bash If you need more detailed information about the type of the variables or if you wish to use the hexadecimal indexes of DICOM tags, you are free to use the following URL:: $ curl http://localhost:8042/instances/e668dcbf-8829a100-c0bd203b-41e404d9-c533f3d4/tags Accessing the raw DICOM fields of an instance ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ .. highlight:: bash You also have the opportunity to access the raw value of the DICOM tags of an instance, without going through a JSON file. Here is how you would find the Patient Name of the instance:: $ curl http://localhost:8042/instances/e668dcbf-8829a100-c0bd203b-41e404d9-c533f3d4/content/0010-0010 Anonymous^Unknown The list of all the available tags for this instance can also be retrieved easily:: $ curl http://localhost:8042/instances/e668dcbf-8829a100-c0bd203b-41e404d9-c533f3d4/content It is also possible to recursively explore the sequences of tags:: $ curl http://localhost:8042/instances/e668dcbf-8829a100-c0bd203b-41e404d9-c533f3d4/content/0008-1250/0/0040-a170/0/0008-0104 For Attenuation Correction The command above has opened the "0008-1250" tag that is a DICOM sequence, taken its first child, opened its "0040-a170" tag that is also a sequence, taken the first child of this child, and returned the "0008-0104" DICOM tag. Downloading images ^^^^^^^^^^^^^^^^^^ .. highlight:: bash It is also possible to download a preview PNG image that corresponds to some DICOM instance:: $ curl http://localhost:8042/instances/e668dcbf-8829a100-c0bd203b-41e404d9-c533f3d4/preview > Preview.png The resulting image will be a standard graylevel PNG image that can be opened by any painting software. .. _changes: Sending resources to remote modalities -------------------------------------- Orthanc can send its DICOM instances to remote DICOM modalities (C-Store SCU). This process can be triggered by the REST API. Configuration ^^^^^^^^^^^^^ .. highlight:: json You first have to declare the AET, the IP address and the port number of the remote modality inside the :ref:`configuration file <configuration>`. For instance, here is how to declare a remote modality:: ... "DicomModalities" : { "sample" : [ "STORESCP", "127.0.0.1", 2000 ] }, ... .. highlight:: bash Such a configuration would enable Orthanc to connect to another DICOM store (for instance, another Orthanc instance) that listens on the localhost on the port 2000. The modalities that are known to Orthanc can be queried:: $ curl http://localhost:8042/modalities Sending One Resource ^^^^^^^^^^^^^^^^^^^^ .. highlight:: bash Once you have identified the Orthanc identifier of the DICOM resource that would like to send :ref:`as explained above <rest-access>`, you would use the following command to send it:: $ curl -X POST http://localhost:8042/modalities/sample/store -d c4ec7f68-9b162055-2c8c5888-5bf5752f-155ab19f The ``/sample/`` component of the URI corresponds to the identifier of the remote modality, as specified above in the configuration file. Note that you can send isolated DICOM instances with this command, but also entire patients, studies or series. Bulk Store SCU ^^^^^^^^^^^^^^ .. highlight:: bash Each time a POST request is made to ``/modalities/.../store``, a new DICOM connection is possibly established. This may lead to a large communication overhead if sending multiple isolated instances. To circumvent this problem, you have 2 possibilities: 1. Set the ``DicomAssociationCloseDelay`` option in the :ref:`configuration file <configuration>` to a non-zero value. This will keep the DICOM connection open for a certain amount of time, waiting for new instances to be routed. 2. If you do not want to keep the connection open but inactive, it is possible to send multiple instances with a single POST request (so-called "Bulk Store SCU", available from Orthanc 0.5.2):: $ curl -X POST http://localhost:8042/modalities/sample/store -d '["d4b46c8e-74b16992-b0f5ca11-f04a60fa-8eb13a88","d5604121-7d613ce6-c315a5-a77b3cf3-9c253b23","cb855110-5f4da420-ec9dc9cb-2af6a9bb-dcbd180e"]' The list of the resources to be sent are given as a JSON array. In this case, a single DICOM connection is used. `Sample code is available <https://bitbucket.org/sjodogne/orthanc/src/default/Resources/Samples/Python/HighPerformanceAutoRouting.py>`__. Tracking changes ---------------- .. highlight:: bash Whenever Orthanc receives a new DICOM instance, this event is recorded in the so-called "Changes Log". This enables remote scripts to react to the arrival of new DICOM resources. A typical application is **auto-routing**, where an external script waits for a new DICOM instance to arrive into Orthanc, then forward this instance to another modality. The Changes Log can be accessed by the following command:: $ curl http://localhost:8042/changes .. highlight:: json Here is a typical output:: { "Changes" : [ { "ChangeType" : "NewInstance", "Date" : "20130507T143902", "ID" : "8e289db9-0e1437e1-3ecf395f-d8aae463-f4bb49fe", "Path" : "/instances/8e289db9-0e1437e1-3ecf395f-d8aae463-f4bb49fe", "ResourceType" : "Instance", "Seq" : 921 }, { "ChangeType" : "NewSeries", "Date" : "20130507T143902", "ID" : "cceb768f-e0f8df71-511b0277-07e55743-9ef8890d", "Path" : "/series/cceb768f-e0f8df71-511b0277-07e55743-9ef8890d", "ResourceType" : "Series", "Seq" : 922 }, { "ChangeType" : "NewStudy", "Date" : "20130507T143902", "ID" : "c4ec7f68-9b162055-2c8c5888-5bf5752f-155ab19f", "Path" : "/studies/c4ec7f68-9b162055-2c8c5888-5bf5752f-155ab19f", "ResourceType" : "Study", "Seq" : 923 }, { "ChangeType" : "NewPatient", "Date" : "20130507T143902", "ID" : "dc65762c-f476e8b9-898834f4-2f8a5014-2599bc94", "Path" : "/patients/dc65762c-f476e8b9-898834f4-2f8a5014-2599bc94", "ResourceType" : "Patient", "Seq" : 924 } ], "Done" : true, "Last" : 924 } This output corresponds to the receiving of one single DICOM instance by Orthanc. It records that a new instance, a new series, a new study and a new patient has been created inside Orthanc. Note that each changes is labeled by a ``ChangeType``, a ``Date`` (in the `ISO format <http://en.wikipedia.org/wiki/ISO_8601>`__), the location of the resource inside Orthanc, and a sequence number (``Seq``). Note that this call is non-blocking. It is up to the calling program to wait for the occurrence of a new event (by implementing a polling loop). .. highlight:: bash This call only returns a fixed number of events, that can be changed by using the ``limit`` option:: $ curl http://localhost:8042/changes?limit=100 The flag ``Last`` records the sequence number of the lastly returned event. The flag ``Done`` is set to ``true`` if no further event has occurred after this lastly returned event. If ``Done`` is set to ``false``, further events are available and can be retrieved. This is done by setting the ``since`` option that specifies from which sequence number the changes must be returned:: $ curl 'http://localhost:8042/changes?limit=100&since=922' A `sample code in the source distribution <https://bitbucket.org/sjodogne/orthanc/src/default/Resources/Samples/Python/ChangesLoop.py>`__ shows how to use this Changes API to implement a polling loop. Deleting resources from Orthanc ------------------------------- .. highlight:: bash Deleting patients, studies, series or instances ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Deleting DICOM resources (i.e. patients, studies, series or instances) from Orthanc is as simple as using a HTTP DELETE on the URI of this resource. Concretely, you would first explore the resources that are stored in Orthanc :ref:`as explained above <rest-access>`:: $ curl http://localhost:8042/patients $ curl http://localhost:8042/studies $ curl http://localhost:8042/series $ curl http://localhost:8042/instances Secondly, once you have spotted the resources to be removed, you would use the following command-line syntax to delete them:: $ curl -X DELETE http://localhost:8042/patients/dc65762c-f476e8b9-898834f4-2f8a5014-2599bc94 $ curl -X DELETE http://localhost:8042/studies/c4ec7f68-9b162055-2c8c5888-5bf5752f-155ab19f $ curl -X DELETE http://localhost:8042/series/cceb768f-e0f8df71-511b0277-07e55743-9ef8890d $ curl -X DELETE http://localhost:8042/instances/8e289db9-0e1437e1-3ecf395f-d8aae463-f4bb49fe Clearing log of changes ^^^^^^^^^^^^^^^^^^^^^^^ :ref:`As described above <changes>`, Orthanc keeps track of all the changes that occur in the DICOM store. This so-called "Changes Log" is accessible at the following URI:: $ curl http://localhost:8042/changes To clear the content of the Changes Log, simply DELETE this URI:: $ curl -X DELETE http://localhost:8042/changes Clearing log of exported resources ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ For medical traceability, Orthanc stores a log of all the resources that have been exported to remote modalities:: $ curl http://localhost:8042/exports In auto-routing scenarios, it is important to prevent this log to grow indefinitely as incoming instances are routed. You can either disable this logging by setting the option ``LogExportedResources`` to ``false`` in the :ref:`configuration file <configuration>`, or periodically clear this log by DELETE-ing this URI:: $ curl -X DELETE http://localhost:8042/exports Anonymization and modification ------------------------------ The process of anonymizing and modifying DICOM resources is :ref:`documented in a separate page <anonymization>`. Further reading --------------- The examples above have shown you the basic principles for driving an instance of Orthanc through its REST API. All the possibilities of the API have not been described. A :ref:`FAQ entry <rest-samples>` lists where you can find more advanced samples of the REST API of Orthanc.