view Sphinx/source/users/rest.rst @ 114:736d30badda0

large POST body
author Sebastien Jodogne <s.jodogne@gmail.com>
date Thu, 20 Jul 2017 17:22:13 +0200
parents 5737f51ff94e
children 55a2ee3c462d
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 <https://curl.haxx.se/>`__, but equivalent calls can be readily
transposed to any programming language that supports both HTTP and
JSON.


.. _sending-dicom-images:

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/questions/463144/php-http-post-fails-when-curl-data-1024/463277#463277>`__::

    $ 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
<https://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
<https://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
<https://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.
* The full documentation of the REST API is maintained as an online
  spreadsheet accessible from the `documentation part of the official
  Web site
  <http://www.orthanc-server.com/static.php?page=documentation>`__
  (click on the *Reference of the REST API* button).