Skip to content

1.2 ChRIS FS plugin workflow: upload files to CUBE and create a new top level feed (pl pacscopy)

Jorge edited this page May 13, 2021 · 3 revisions

ChRIS FS plugin workflow: upload files to CUBE and create a new top-level feed (pl-dircopy)

THIS PAGE IS A WIP!!

Abstract

This page provides instructions that allow for the "upload" of data into the ChRIS Ultron Back End (CUBE) and also creating a new top-level feed containing this uploaded data.

The set of operations are:

  • instantiate CUBE;
  • clear the internal pman job-ID jid database;
  • pull a sample dataset from github;
  • push a directory in the host file system into CUBE storage -- this directory is stored in a special upload location separate from any feeds;
  • run a (FS) plugin called pl-pacscopy that copies data from this uploaded location to a new feed.

Executive summary

As a convenience, all calls on this page are first summarised:

Base directory

Make sure you are in the base directory of the ChRIS_ultron_backEnd (CUBE) repo:

git clone https://github.com/FNNDSC/ChRIS_ultron_backEnd
cd ChRIS_ultron_backEnd

Set convenience environment variables

export HOST_IP=$(ip route | grep -v docker | awk '{if(NF==11) print $9}')
export HOST_PORT=8000

Pull image data

Pull a sample data set that will be used in this example:

git clone https://github.com/FNNDSC/SAG-anon

Local data assumptions:

Set a convenience variable:

export DICOMDIR=$(pwd)/SAG-anon

Instantiate CUBE

*destroy* ; sudo rm -fr CHRIS_REMOTE_FS; rm -fr CHRIS_REMOTE_FS ; *make*

PUSH data into CUBE's upload storage

Once CUBE is up and in interactive mode, open a new terminal and cd to the CUBE repo dir (you might need to reset the convenience variables):

cd ChRIS_ultron_backEnd
export HOST_IP=$(ip route | grep -v docker | awk '{if(NF==11) print $9}')
export HOST_PORT=8000
export DICOMDIR=$(pwd)/SAG-anon

PUSH

The PUSH operation relies on the command line apps:

  • http to PUSH via the CUBE API;
  • swift to PUSH to a swift storage container directly;

Both apps are just a pip install away

pip install httpie
pip install swift

Now, register the DICOM files in swift storage. The registration can be performed through the CUBE API:

cd utils/scripts
./pushAllToCUBE.sh -E dcm -D $DICOMDIR -P DICOM/dataset1

Or by talking to the swift container directly:

cd utils/scripts
./swiftCtl.sh -A push -E dcm -D $DICOMDIR -P chris/uploads/DICOM/dataset1

In anecdotal testing, pushing via the CUBE API takes about twice as long as pushing to the swift container directly.

VERIFY

./swiftCtl.sh

Clear the internal pman jobid database

pfurl --verb POST --raw --http ${HOST_IP}:5010/api/v1/cmd \
      --jsonwrapper 'payload' --msg \
 '{  "action": "DBctl",
         "meta": {
                 "do":     "clear"
         }
 }' --quiet --jsonpprintindent 4

Run an instance of the pl-dircopy plugin

pfurl --auth chris:chris1234 --verb POST                         \
      --http ${HOST_IP}:${HOST_PORT}/api/v1/plugins/7/instances/ \
      --content-type application/vnd.collection+json             \
      --jsonwrapper 'template' --msg '
{"data":
    [{"name":"dir",
      "value":"/DICOM/dataset1"}
    ]
}' \
--quiet --jsonpprintindent 4

Query and register output files

pfurl --auth chris:chris1234                               \
      --verb GET                                           \
      --http ${HOST_IP}:${HOST_PORT}/api/v1/plugins/instances/1/   \
      --content-type application/vnd.collection+json       \
      --quiet --jsonpprintindent 4

Get a list of files produced by pl-dircopy and registered to CUBE

pfurl --auth chris:chris1234                               \
      --verb GET                                           \
      --http ${HOST_IP}:${HOST_PORT}/api/v1/1/files/       \
      --content-type application/vnd.collection+json       \
      --quiet --jsonpprintindent 4

Download a single file from CUBE

http -a chris:chris1234 --download \
  http://${HOST_IP}:${HOST_PORT}/api/v1/files/9/0009-1.3.12.2.1107.5.2.19.45152.2013030808110245009586023.dcm

Detail explanation of workflow

Preconditions

HOST_IP env variable

You should set an environment variable, HOST_IP to the IP of the actual host you are using. In Linux, this can be

export HOST_IP=$(ip route | grep -v docker | awk '{if(NF==11) print $9}')

For convenience, set a HOST_PORT variable appropriately:

export HOST_PORT=8000

Instantiated CUBE

Start CUBE from the repository source directory, running

*destroy* ; sudo rm -fr CHRIS_REMOTE_FS; rm -fr CHRIS_REMOTE_FS ; *make*

The *destroy* provides the option of removing all volume containers. Reply y here to each question. The FS directory contains subdirectories that are mapped into the pfioh and pman containers to simulate remote filesystems in the case of a fully local CUBE. These need to be deleted. The call to sudo is necessary since a prior run of CUBE might have created root owned directories and files.

Wait until the startup has completed and the main service is in interactive mode.

Clear the internal pman jobid database

Once all CUBE has been fully instantiated, it is imperative to clear the internal pman database of references to tests that might have jids that could collide with actual jobs.

pfurl --verb POST --raw --http ${HOST_IP}:5010/api/v1/cmd \
      --jsonwrapper 'payload' --msg \
 '{  "action": "DBctl",
         "meta": {
                 "do":     "clear"
         }
 }' --quiet --jsonpprintindent 4

If this is not done, then actual CUBE calls will fail if their instance IDs (which will start with 1) collide with a previous test instance ID.

Data to be uploaded into CUBE

We have provided a sample dataset of anonymous DICOM data to use several of the examples in this wiki. This can be pulled (preferably to the CUBE repo root directory):

cd ChRIS_ulton_backEnd
git clone https://github.com/FNNDSC/SAG-anon

and set this using a convenience variable:

export DICOMDIR=$(pwd)/SAG-anon

PUSH data into CUBE's upload storage

In the source repository, two utility scripts are provided: pushAllToCUBE.sh that pushes data to CUBE's swift storage using the CUBE API, and swiftCtl.sh which provides some simple actions directly on the swift storage.

You can use either pushAlltoCUBE.sh or swiftCtl.sh to push the data (please verify your CUBE port! The default port is 8000; if your CUBE is listening of a different <HOST>:<port> please set correctly using flags to the script):

cd utils/scripts
./pushAllToCUBE.sh -D $DICOMDIR -P DICOM/dataset1 -E dcm

or you can use swiftCtl.sh

cd utils/scripts
./swiftCtl.sh -A push -D $DICOMDIR -P cube/uploads/DICOM/dataset1 -E dcm

Either will push all the files in $DICOMDIR to CUBE in a bucket for the user cube here:

cube/uploads/DICOM/dataset1

This can be verified by calling

./swiftCtl.sh

which will show a listing of files currently in swift storage:

chris/uploads/DICOM/dataset1/0001-1.3.12.2.1107.5.2.19.45152.2013030808110258929186035.dcm
chris/uploads/DICOM/dataset1/0002-1.3.12.2.1107.5.2.19.45152.2013030808110261698786039.dcm
chris/uploads/DICOM/dataset1/0003-1.3.12.2.1107.5.2.19.45152.2013030808110259940386037.dcm
chris/uploads/DICOM/dataset1/0004-1.3.12.2.1107.5.2.19.45152.2013030808110256555586033.dcm
chris/uploads/DICOM/dataset1/0005-1.3.12.2.1107.5.2.19.45152.2013030808110251492986029.dcm
...
...
chris/uploads/DICOM/dataset1/0188-1.3.12.2.1107.5.2.19.45152.2013030808105567563785463.dcm
chris/uploads/DICOM/dataset1/0189-1.3.12.2.1107.5.2.19.45152.2013030808105517130085417.dcm
chris/uploads/DICOM/dataset1/0190-1.3.12.2.1107.5.2.19.45152.2013030808105512578785411.dcm
chris/uploads/DICOM/dataset1/0191-1.3.12.2.1107.5.2.19.45152.2013030808105486367685381.dcm
chris/uploads/DICOM/dataset1/0192-1.3.12.2.1107.5.2.19.45152.2013030808105485455785379.dcm

Note the existence of the test feeds from the integration tests:

...
data/foo/feed_8/simplefsapp_8/data/jobStatus.json
data/foo/feed_8/simplefsapp_8/data/jobStatusSummary.json
data/foo/feed_8/simplefsapp_8/data/out.txt
data/foo/feed_8/simplefsapp_8/data/output.meta.json
data/foo/feed_8/simplefsapp_8/data/squashHereDir.txt
...

Create a new top-level Feed

Now that data has been uploaded to CUBE, we can call the pl-dircopy plugin to create a new feed on this data.

GET list of plugins and check for pl-dircopy plugin

Call

pfurl --auth chris:chris1234                         \
      --http ${HOST_IP}:${HOST_PORT}/api/v1/plugins/ \
      --quiet --jsonpprintindent 4

Look through the list for pl-dircopy. For example, let's say that this is located at

     {
        "data": [
          { "name": "name", "value": "dircopy" }
        ],
        "href": "http://10.72.76.155:8000/api/v1/plugins/7/"
     }

we can call

pfurl --auth chris:chris1234                           \
      --http ${HOST_IP}:${HOST_PORT}/api/v1/plugins/7/ \
      --quiet --jsonpprintindent 4

Receive

{
  "collection": {
    "version": "1.0",
    "href": "http://10.72.76.155:8000/api/v1/plugins/7/",
    "items": [
      {
        "data": [
          { "name": "name", "value": "dircopy" },
          { "name": "dock_image", "value": "fnndsc/pl-dircopy" },
          { "name": "type", "value": "fs" },
          { "name": "authors", "value": "FNNDSC ([email protected])" },
          { "name": "title", "value": "A directory copy chris fs app" },
          { "name": "category", "value": "" },
          { "name": "description", "value": "A plugin fs app to copy an entire directory" },
          { "name": "documentation", "value": "http://wiki" },
          { "name": "license", "value": "Opensource (MIT)" },
          { "name": "version", "value": "0.1" },
          { "name": "execshell", "value": "python3" },
          { "name": "selfpath", "value": "/usr/src/dircopy" },
          { "name": "selfexec", "value": "dircopy.py" },
          { "name": "compute_resource_identifier", "value": "host" },
          { "name": "min_number_of_workers", "value": 1 },
          { "name": "max_number_of_workers", "value": 1 },
          { "name": "min_cpu_limit", "value": 1000 },
          { "name": "max_cpu_limit", "value": 2147483647 },
          { "name": "min_memory_limit", "value": 200 },
          { "name": "max_memory_limit", "value": 2147483647 },
          { "name": "min_gpu_limit", "value": 0 },
          { "name": "max_gpu_limit", "value": 0 }
        ],
        "href": "http://10.72.76.155:8000/api/v1/plugins/7/",
        "links": [
          {
            "rel": "parameters",
            "href": "http://10.72.76.155:8000/api/v1/plugins/7/parameters/"
          },
          {
            "rel": "instances",
            "href": "http://10.72.76.155:8000/api/v1/plugins/7/instances/"
          }
        ]
      }
    ],
    "links": [ ]
  }
}

GET parameter info for plugin

Follow the links provided to get information on the parameters for the plugin

Call

pfurl --auth chris:chris1234                                      \
      --http ${HOST_IP}:${HOST_PORT}/api/v1/plugins/7/parameters/ \
      --quiet --jsonpprintindent 4

Receive

{
  "collection": {
    "version": "1.0",
    "href": "http://10.72.76.155:8000/api/v1/plugins/7/parameters/",
    "items": [
      {
        "data": [
          { "name": "name", "value": "dir" },
          { "name": "type", "value": "path" },
          { "name": "optional", "value": true },
          { "name": "default", "value": "./" },
          { "name": "flag", "value": "--dir" },
          { "name": "action", "value": "store" },
          { "name": "help", "value": "directory to be copied" }
        ],
        "href": "http://10.72.76.155:8000/api/v1/plugins/parameters/42/",
        "links": [{ "rel": "plugin", "href": "http://10.72.76.155:8000/api/v1/plugins/7/" }]
      }
    ],
    "links": [{ "rel": "plugin", "href": "http://10.72.76.155:8000/api/v1/plugins/7/" }]
  }
}

Run an instance of the plugin

Call

Using httpie

http -a chris:chris1234 POST                                    \
     http://${HOST_IP}:${HOST_PORT}/api/v1/plugins/7/instances/ \
     Content-Type:application/vnd.collection+json               \
     Accept:application/vnd.collection+json                     \
     template:='{"data":[{"name":"dir","value":"/DICOM/dataset1"}]}'

Using pfurl

pfurl --auth chris:chris1234 --verb POST                         \
      --http ${HOST_IP}:${HOST_PORT}/api/v1/plugins/7/instances/ \
      --content-type application/vnd.collection+json             \
      --jsonwrapper 'template' --msg '
{"data":
    [{"name":"dir",
      "value":"/DICOM/dataset1"}
    ]
}' \
--quiet --jsonpprintindent 4

Receive

{
  "stdout": {
    "collection": {
      "version": "1.0",
      "href": "http://10.72.76.155:8000/api/v1/plugins/7/instances/",
      "items": [
        {
          "data": [
            { "name": "id", "value": 1 },
            { "name": "plugin_name", "value": "dircopy" },
            { "name": "start_date", "value": "2018-09-14T12:35:33.000486-04:00" },
            { "name": "end_date", "value": "2018-09-14T12:35:33.000541-04:00" },
            { "name": "status", "value": "started" },
            { "name": "owner", "value": "chris" },
            { "name": "compute_resource_identifier", "value": "host" },
            { "name": "cpu_limit", "value": 1000 },
            { "name": "memory_limit", "value": 200 },
            { "name": "number_of_workers", "value": 1 },
            { "name": "gpu_limit", "value": 0 }
          ],
          "href": "http://10.72.76.155:8000/api/v1/plugins/instances/1/",
          "links": [
            { "rel": "feed", "href": "http://10.72.76.155:8000/api/v1/1/" },
            { "rel": "plugin", "href": "http://10.72.76.155:8000/api/v1/plugins/7/" },
            {
              "rel": "path_param",
              "href": "http://10.72.76.155:8000/api/v1/plugins/path-parameter/1/"
            }
          ]
        }
      ],
      "links": [ ]
    }
  },
  "msg": "push OK."
}

Query job state (and also trigger a file registration in CUBE)

Examine the return JSON for the instance ID returned. In the above, we note that this is

{
  "stdout": {
    "collection": {
      "version": "1.0",
      "href": "http://10.72.76.155:8000/api/v1/plugins/7/instances/",
      "items": [
        {
          "data": [
            { "name": "id", "value": 1 },
            { "name": "plugin_name", "value": "dircopy" },
            { "name": "start_date", "value": "2018-09-14T12:35:33.000486-04:00" },
            { "name": "end_date", "value": "2018-09-14T12:35:33.000541-04:00" },
            { "name": "status", "value": "started" },
            { "name": "owner", "value": "chris" },
            { "name": "compute_resource_identifier", "value": "host" },
            { "name": "cpu_limit", "value": 1000 },
            { "name": "memory_limit", "value": 200 },
            { "name": "number_of_workers", "value": 1 },
            { "name": "gpu_limit", "value": 0 }
          ],
          "href": "http://10.72.76.155:8000/api/v1/plugins/instances/1/"

In other words, instance 1.

Call

Using pfurl

pfurl --auth chris:chris1234                               \
      --verb GET                                           \
      --http ${HOST_IP}:${HOST_PORT}/api/v1/plugins/instances/1/   \
      --content-type application/vnd.collection+json       \
      --quiet --jsonpprintindent 4

which if the job was successful will return

{
  "collection": {
    "version": "1.0",
    "href": "http://10.72.76.155:8000/api/v1/plugins/instances/1/",
    "items": [
      {
        "data": [
          { "name": "id", "value": 1 },
          { "name": "plugin_name", "value": "dircopy" },
          { "name": "start_date", "value": "2018-09-14T12:35:33.000486-04:00" },
          { "name": "end_date", "value": "2018-09-14T12:38:02.814504-04:00" },
          { "name": "status", "value": "finishedSuccessfully" },
          { "name": "owner", "value": "chris" },
          { "name": "compute_resource_identifier", "value": "host" },
          { "name": "cpu_limit", "value": 1000 },
          { "name": "memory_limit", "value": 200 },
          { "name": "number_of_workers", "value": 1 },
          { "name": "gpu_limit", "value": 0 }
        ],
        "href": "http://10.72.76.155:8000/api/v1/plugins/instances/1/",
        "links": [
          { "rel": "feed", "href": "http://10.72.76.155:8000/api/v1/1/" },
          { "rel": "plugin", "href": "http://10.72.76.155:8000/api/v1/plugins/7/" },
          {
            "rel": "path_param",
            "href": "http://10.72.76.155:8000/api/v1/plugins/path-parameter/1/"
          }
        ]
      }
    ],
    "links": [ ]
  }
}

In which we see that the status is finishedSuccessfully. On first attempt at asking the status of a successfully completed job, CUBE might block for a second or two as it actually registers the files in its data base.

Access files from a client

To access files from a client, determine the feed ID that is the root of this plugin. In this example case, this will be feed 1 assuming that the first action we ran was the pl-dircopy. In that status return call, we noted

          { "rel": "feed", "href": "http://10.72.76.155:8000/api/v1/1/" },

Access the references to registered files by calling http://10.72.76.155:8000/api/v1/1/ -- note that will return ALL the files down a plugin tree, paginated as indicated by the next relationship:

pfurl --auth chris:chris1234                               \
      --verb GET                                           \
      --http ${HOST_IP}:${HOST_PORT}/api/v1/1/files/       \
      --content-type application/vnd.collection+json       \
      --quiet --jsonpprintindent 4

which should return

{
  "collection": {
    "version": "1.0",
    "href": "http://10.72.76.155:8000/api/v1/1/files/",
    "items": [
      {
        "data": [
          {
            "name": "fname",
            "value": "chris/feed_1/dircopy_1/data/0001-1.3.12.2.1107.5.2.19.45152.2013030808110258929186035.dcm"
          },
          { "name": "feed_id", "value": 1 },
          { "name": "plugin_inst_id", "value": 1 }
        ],
        "href": "http://10.72.76.155:8000/api/v1/files/1/",
        "links": [
          {
            "rel": "file_resource",
            "href": "http://10.72.76.155:8000/api/v1/files/1/0001-1.3.12.2.1107.5.2.19.45152.2013030808110258929186035.dcm"
          },
          { "rel": "feed", "href": "http://10.72.76.155:8000/api/v1/1/" },
          {
            "rel": "plugin_inst",
            "href": "http://10.72.76.155:8000/api/v1/plugins/instances/1/"
          }
        ]
      },
      {
        "data": [
          {
            "name": "fname",
            "value": "chris/feed_1/dircopy_1/data/0002-1.3.12.2.1107.5.2.19.45152.2013030808110261698786039.dcm"
          },
          { "name": "feed_id", "value": 1 },
          { "name": "plugin_inst_id", "value": 1 }
        ],
        "href": "http://10.72.76.155:8000/api/v1/files/2/",
        "links": [
          {
            "rel": "file_resource",
            "href": "http://10.72.76.155:8000/api/v1/files/2/0002-1.3.12.2.1107.5.2.19.45152.2013030808110261698786039.dcm"
          },
          { "rel": "feed", "href": "http://10.72.76.155:8000/api/v1/1/" },
          {
            "rel": "plugin_inst",
            "href": "http://10.72.76.155:8000/api/v1/plugins/instances/1/"
          }
        ]
      },
      {
        "data": [
          {
            "name": "fname",
            "value": "chris/feed_1/dircopy_1/data/0003-1.3.12.2.1107.5.2.19.45152.2013030808110259940386037.dcm"
          },
          { "name": "feed_id", "value": 1 },
          { "name": "plugin_inst_id", "value": 1 }
        ],
        "href": "http://10.72.76.155:8000/api/v1/files/3/",
        "links": [
          {
            "rel": "file_resource",
            "href": "http://10.72.76.155:8000/api/v1/files/3/0003-1.3.12.2.1107.5.2.19.45152.2013030808110259940386037.dcm"
          },
          { "rel": "feed", "href": "http://10.72.76.155:8000/api/v1/1/" },
          {
            "rel": "plugin_inst",
            "href": "http://10.72.76.155:8000/api/v1/plugins/instances/1/"
          }
        ]
      },
      {
        "data": [
          {
            "name": "fname",
            "value": "chris/feed_1/dircopy_1/data/0004-1.3.12.2.1107.5.2.19.45152.2013030808110256555586033.dcm"
          },
          { "name": "feed_id", "value": 1 },
          { "name": "plugin_inst_id", "value": 1 }
        ],
        "href": "http://10.72.76.155:8000/api/v1/files/4/",
        "links": [
          {
            "rel": "file_resource",
            "href": "http://10.72.76.155:8000/api/v1/files/4/0004-1.3.12.2.1107.5.2.19.45152.2013030808110256555586033.dcm"
          },
          { "rel": "feed", "href": "http://10.72.76.155:8000/api/v1/1/" },
          {
            "rel": "plugin_inst",
            "href": "http://10.72.76.155:8000/api/v1/plugins/instances/1/"
          }
        ]
      },
      {
        "data": [
          {
            "name": "fname",
            "value": "chris/feed_1/dircopy_1/data/0005-1.3.12.2.1107.5.2.19.45152.2013030808110251492986029.dcm"
          },
          { "name": "feed_id", "value": 1 },
          { "name": "plugin_inst_id", "value": 1 }
        ],
        "href": "http://10.72.76.155:8000/api/v1/files/5/",
        "links": [
          {
            "rel": "file_resource",
            "href": "http://10.72.76.155:8000/api/v1/files/5/0005-1.3.12.2.1107.5.2.19.45152.2013030808110251492986029.dcm"
          },
          { "rel": "feed", "href": "http://10.72.76.155:8000/api/v1/1/" },
          {
            "rel": "plugin_inst",
            "href": "http://10.72.76.155:8000/api/v1/plugins/instances/1/"
          }
        ]
      },
      {
        "data": [
          {
            "name": "fname",
            "value": "chris/feed_1/dircopy_1/data/0006-1.3.12.2.1107.5.2.19.45152.2013030808110255864486031.dcm"
          },
          { "name": "feed_id", "value": 1 },
          { "name": "plugin_inst_id", "value": 1 }
        ],
        "href": "http://10.72.76.155:8000/api/v1/files/6/",
        "links": [
          {
            "rel": "file_resource",
            "href": "http://10.72.76.155:8000/api/v1/files/6/0006-1.3.12.2.1107.5.2.19.45152.2013030808110255864486031.dcm"
          },
          { "rel": "feed", "href": "http://10.72.76.155:8000/api/v1/1/" },
          {
            "rel": "plugin_inst",
            "href": "http://10.72.76.155:8000/api/v1/plugins/instances/1/"
          }
        ]
      },
      {
        "data": [
          {
            "name": "fname",
            "value": "chris/feed_1/dircopy_1/data/0007-1.3.12.2.1107.5.2.19.45152.2013030808110245643686025.dcm"
          },
          { "name": "feed_id", "value": 1 },
          { "name": "plugin_inst_id", "value": 1 }
        ],
        "href": "http://10.72.76.155:8000/api/v1/files/7/",
        "links": [
          {
            "rel": "file_resource",
            "href": "http://10.72.76.155:8000/api/v1/files/7/0007-1.3.12.2.1107.5.2.19.45152.2013030808110245643686025.dcm"
          },
          { "rel": "feed", "href": "http://10.72.76.155:8000/api/v1/1/" },
          {
            "rel": "plugin_inst",
            "href": "http://10.72.76.155:8000/api/v1/plugins/instances/1/"
          }
        ]
      },
      {
        "data": [
          {
            "name": "fname",
            "value": "chris/feed_1/dircopy_1/data/0008-1.3.12.2.1107.5.2.19.45152.2013030808110250837286027.dcm"
          },
          { "name": "feed_id", "value": 1 },
          { "name": "plugin_inst_id", "value": 1 }
        ],
        "href": "http://10.72.76.155:8000/api/v1/files/8/",
        "links": [
          {
            "rel": "file_resource",
            "href": "http://10.72.76.155:8000/api/v1/files/8/0008-1.3.12.2.1107.5.2.19.45152.2013030808110250837286027.dcm"
          },
          { "rel": "feed", "href": "http://10.72.76.155:8000/api/v1/1/" },
          {
            "rel": "plugin_inst",
            "href": "http://10.72.76.155:8000/api/v1/plugins/instances/1/"
          }
        ]
      },
      {
        "data": [
          {
            "name": "fname",
            "value": "chris/feed_1/dircopy_1/data/0009-1.3.12.2.1107.5.2.19.45152.2013030808110245009586023.dcm"
          },
          { "name": "feed_id", "value": 1 },
          { "name": "plugin_inst_id", "value": 1 }
        ],
        "href": "http://10.72.76.155:8000/api/v1/files/9/",
        "links": [
          {
            "rel": "file_resource",
            "href": "http://10.72.76.155:8000/api/v1/files/9/0009-1.3.12.2.1107.5.2.19.45152.2013030808110245009586023.dcm"
          },
          { "rel": "feed", "href": "http://10.72.76.155:8000/api/v1/1/" },
          {
            "rel": "plugin_inst",
            "href": "http://10.72.76.155:8000/api/v1/plugins/instances/1/"
          }
        ]
      },
      {
        "data": [
          {
            "name": "fname",
            "value": "chris/feed_1/dircopy_1/data/0010-1.3.12.2.1107.5.2.19.45152.2013030808110244209386021.dcm"
          },
          { "name": "feed_id", "value": 1 },
          { "name": "plugin_inst_id", "value": 1 }
        ],
        "href": "http://10.72.76.155:8000/api/v1/files/10/",
        "links": [
          {
            "rel": "file_resource",
            "href": "http://10.72.76.155:8000/api/v1/files/10/0010-1.3.12.2.1107.5.2.19.45152.2013030808110244209386021.dcm"
          },
          { "rel": "feed", "href": "http://10.72.76.155:8000/api/v1/1/" },
          {
            "rel": "plugin_inst",
            "href": "http://10.72.76.155:8000/api/v1/plugins/instances/1/"
          }
        ]
      }
    ],
    "links": [
      { "rel": "feed", "href": "http://10.72.76.155:8000/api/v1/1/" },
      {
        "rel": "next",
        "href": "http://10.72.76.155:8000/api/v1/1/files/?limit=10&offset=10"
      }
    ]
  }
}

Download an actual file

Use httpie to pull an actual file, using an href from the above return:

http -a chris:chris1234 --download \
    http://10.72.76.155:8000/api/v1/files/10/0010-1.3.12.2.1107.5.2.19.45152.2013030808110244209386021.dcm
Clone this wiki locally