From 7a039948935a414adf9a2ace43daec6e4b11af8e Mon Sep 17 00:00:00 2001 From: Megan Henning <meganhenning@flywheel.io> Date: Mon, 6 Jun 2016 15:22:15 -0500 Subject: [PATCH] Add documentation to analysis endpoints --- api/handlers/listhandler.py | 159 +++++++++++++++++++++++++++++++++++- 1 file changed, 157 insertions(+), 2 deletions(-) diff --git a/api/handlers/listhandler.py b/api/handlers/listhandler.py index a0137f72..63c7db10 100644 --- a/api/handlers/listhandler.py +++ b/api/handlers/listhandler.py @@ -619,6 +619,64 @@ class AnalysesHandler(ListHandler): return analysis_obj def post(self, cont_name, list_name, **kwargs): + """ + .. http:post:: /api/(cont_name)/(cid)/analyses + + Default behavior: + Creates an analysis object and uploads supplied input + and output files. + When param ``job`` is true: + Creates an analysis object and job object that reference + each other via ``job`` and ``destination`` fields. Job based + analyses are only allowed at the session level. + + :param cont_name: one of ``projects``, ``sessions``, ``collections`` + :type cont_name: string + + :param cid: Container ID + :type cid: string + + :query boolean job: a flag specifying the type of analysis + + :statuscode 200: no error + :statuscode 400: Job-based analyses must be at the session level + :statuscode 400: Job-based analyses must have ``job`` and ``analysis`` maps in JSON body + + **Example request**: + + .. sourcecode:: http + + POST /api/sessions/57081d06b386a6dc79ca383c/analyses HTTP/1.1 + + { + "analysis": { + "label": "Test Analysis 1" + }, + "job" : { + "gear": "dcm_convert", + "inputs": { + "dicom": { + "type": "acquisition", + "id": "57081d06b386a6dc79ca386b", + "name" : "test_acquisition_dicom.zip" + } + }, + "tags": ["example"] + } + } + + **Example response**: + + .. sourcecode:: http + + HTTP/1.1 200 OK + Vary: Accept-Encoding + Content-Type: application/json; charset=utf-8 + { + "_id": "573cb66b135d87002660597c" + } + + """ _id = kwargs.pop('cid') container, permchecker, storage, mongo_validator, _, keycheck = self._initialize_request(cont_name, list_name, _id) permchecker(noop)('POST', _id=_id) @@ -643,7 +701,7 @@ class AnalysesHandler(ListHandler): analysis = payload.get('analysis') job = payload.get('job') if job is None or analysis is None: - self.abort(400, 'POST json body must contain map for "analysis" and "job"') + self.abort(400, 'JSON body must contain map for "analysis" and "job"') default = self._default_analysis() analysis = default.update(analysis) @@ -657,7 +715,9 @@ class AnalysesHandler(ListHandler): for x in job['inputs'].keys(): input_map = job['inputs'][x] inputs[x] = create_filereference_from_dictionary(input_map) - tags = job.get('tags', None) + tags = job.get('tags', []) + if 'analysis' not in tags: + tags.append('analysis') destination = create_containerreference_from_dictionary({'type': 'analysis', 'id': analysis['_id']}) job = Job(gear_name, inputs, destination=destination, tags=tags) @@ -670,6 +730,101 @@ class AnalysesHandler(ListHandler): def download(self, cont_name, list_name, **kwargs): + """ + .. http:get:: /api/(cont_name)/(cid)/analyses/(analysis_id)/files/(file_name) + + Download a file from an analysis or download a tar of all files + + When no filename is provided, a tar of all input and output files is created. + The first request to this endpoint without a ticket ID generates a download ticket. + A request to this endpoint with a ticket ID downloads the file(s). + If the analysis object is tied to a job, the input file(s) are inlfated from + the job's ``input`` array. + + :param cont_name: one of ``projects``, ``sessions``, ``collections`` + :type cont_name: string + + :param cid: Container ID + :type cid: string + + :param analysis_id: Analysis ID + :type analysis_id: string + + :param filename: (Optional) Filename of specific file to download + :type cid: string + + :query string ticket: Download ticket ID + + :statuscode 200: no error + :statuscode 404: No files on analysis ``analysis_id`` + :statuscode 404: Could not find file ``filename`` on analysis ``analysis_id`` + + **Example request without ticket ID**: + + .. sourcecode:: http + + GET /api/sessions/57081d06b386a6dc79ca383c/analyses/5751cd3781460100a66405c8/files HTTP/1.1 + Host: demo.flywheel.io + Accept: */* + + + **Response**: + + .. sourcecode:: http + + HTTP/1.1 200 OK + Vary: Accept-Encoding + Content-Type: application/json; charset=utf-8 + { + "ticket": "57f2af23-a94c-426d-8521-11b2e8782020", + "filename": "analysis_5751cd3781460100a66405c8.tar", + "file_cnt": 3, + "size": 4525137 + } + + **Example request with ticket ID**: + + .. sourcecode:: http + + GET /api/sessions/57081d06b386a6dc79ca383c/analyses/5751cd3781460100a66405c8/files?ticket=57f2af23-a94c-426d-8521-11b2e8782020 HTTP/1.1 + Host: demo.flywheel.io + Accept: */* + + + **Response**: + + .. sourcecode:: http + + HTTP/1.1 200 OK + Vary: Accept-Encoding + Content-Type: application/octet-stream + Content-Disposition: attachment; filename=analysis_5751cd3781460100a66405c8.tar; + + **Example Request with filename**: + + .. sourcecode:: http + + GET /api/sessions/57081d06b386a6dc79ca383c/analyses/5751cd3781460100a66405c8/files/exampledicom.zip?ticket= HTTP/1.1 + Host: demo.flywheel.io + Accept: */* + + + **Response**: + + .. sourcecode:: http + + HTTP/1.1 200 OK + Vary: Accept-Encoding + Content-Type: application/json; charset=utf-8 + { + "ticket": "57f2af23-a94c-426d-8521-11b2e8782020", + "filename": "exampledicom.zip", + "file_cnt": 1, + "size": 4525137 + } + + + """ _id = kwargs.pop('cid') container, permchecker, storage, _, _, _ = self._initialize_request(cont_name, list_name, _id) filename = kwargs.get('name') -- GitLab