Skip to content

Commit

Permalink
Merge pull request #1171 from onaio/floip-output-results
Browse files Browse the repository at this point in the history
Convert JSON dict to FLOIP list
  • Loading branch information
ukanga authored Nov 7, 2017
2 parents 8996249 + d9d4773 commit 2dc9882
Show file tree
Hide file tree
Showing 6 changed files with 148 additions and 4 deletions.
57 changes: 57 additions & 0 deletions docs/data.rst
Original file line number Diff line number Diff line change
Expand Up @@ -171,6 +171,63 @@ Response
....
]

Get FLOIP flow results for a specific form
------------------------------------------
Provides a list of rows of submitted data for a specific form. Each row contains 6 values as specified in FLOIP resource data https://github.com/FLOIP/flow-results/blob/master/specification.md#resource-data-found-at-external-path.
The data is accessed from the data endpoint by specifiying `Accept: "application/vnd.org.flowinterop.results+json"` header.

The values are:
::
- ``Timestamp`` - form submission timestamp
- ``Row ID`` - Submission id
- ``Contact ID`` - Name of the person who made the submission or null if unavailable
- ``Question ID`` - The question field name
- ``Response`` - The question response
- ``Response metadata`` - The question options or null if none

.. raw:: html

<pre class="prettyprint">
<b>GET</b> /api/v1/data/<code>{pk}</code> -H "Accept:application/vnd.org.flowinterop.results+json"</pre>

Example
^^^^^^^^^
::
curl -X GET http://localhost:8000/api/v1/data/3 -H "Accept: application/vnd.org.flowinterop.results+json" -u username:password

Response
^^^^^^^^^
::

[
[ "2017-05-23T13:35:37.119-04:00", 20394823948, 923842093, "ae54d3", "female", {"option_order": ["male","female"]} ],
[ "2017-05-23T13:35:47.822-04:00", 20394823950, 923842093, "ae54d7", "chocolate", null ]
]

Get FLOIP flow results for a specific submission
------------------------------------------
Provides a list of rows of submitted data for a specific submission in a form in FLOIP resource data format as specified in the flow results specification https://github.com/FLOIP/flow-results/blob/master/specification.md#resource-data-found-at-external-path.

.. raw:: html

<pre class="prettyprint">
<b>GET</b> /api/v1/data/<code>{pk}</code>/<code>{dataid}</code> -H "Accept: application/vnd.org.flowinterop.results+json"</pre>

Example
^^^^^^^^^
::
curl -X GET http://localhost:8000/api/v1/data/210902/19158892 -H "Accept: application/vnd.org.flowinterop.results+json" -u username:password

Response
^^^^^^^^^
::

[
[ "2017-05-23T13:35:37.119-04:00", 20394823948, 923842093, "ae54d3", "female", {"option_order": ["male","female"]} ],
[ "2017-05-23T13:35:47.822-04:00", 20394823950, 923842093, "ae54d7", "chocolate", null ]
]


Paginate data of a specific form
-------------------------------------------
Returns a list of json submitted data for a specific form using page number and the number of items per page. Use the ``page`` parameter to specify page number and ``page_size`` parameter is used to set the custom page size.
Expand Down
16 changes: 16 additions & 0 deletions docs/forms.rst
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,22 @@ Response
"last_updated_at": "2013-07-25T14:14:22.892Z"
}

Publish FLOIP results data package
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

To publish a FLOIP form, upload the JSON flow results data package in the following format https://github.com/FLOIP/flow-results/blob/master/README.md#example.

.. raw:: html

<pre class="prettyprint">
<b>POST</b> /api/v1/forms</pre>

Example
^^^^^^^
::

curl -X POST -F floip_file=@/path/to/datapackage.json https://api.ona.io/api/v1/forms

Get list of forms
------------------
.. raw:: html
Expand Down
15 changes: 13 additions & 2 deletions docs/submissions.rst
Original file line number Diff line number Diff line change
Expand Up @@ -69,18 +69,29 @@ Here is some example JSON, it would replace `[the JSON]` above:

Submit a FLOIP XForm submission
-------------------------------
To make a FLOIP submission, specify the content type header as `"Content-Type: application/vnd.org.flowinterop.results+json"` and the `[FLOIP data]` in a list of rows format each row having 6 values.

The values in each row should be:
::
- ``Timestamp``
- ``Row ID``
- ``Contact ID``
- ``Question ID``
- ``Response``
- ``Response metadata``
.. raw:: html

<pre class="prettyprint">
<b>POST</b> /api/v1/submissions</pre>
<b>POST</b> /api/<code>{user}</code><code>{pk}</code>/submissions</pre>

Example
^^^^^^^
::

curl -X POST -d '{"id": "[id_string]", "submission": [the FLOIP data]} http://api.ona.io/api/v1/submissions -u user:pass
curl -X POST http://api.ona.io/[user]/[pk]/submission
-H "Content-Type: application/vnd.org.flowinterop.results+json"
-d '[FLOIP data]'

The FLOIP data format is specified |FLOIPSubmissionAPI|

Expand Down
25 changes: 24 additions & 1 deletion onadata/apps/api/tests/viewsets/test_data_viewset.py
Original file line number Diff line number Diff line change
Expand Up @@ -2096,9 +2096,32 @@ def test_filterset(self):
response = view(request, pk=formid, format='json')
self.assertEqual(len(response.data), 1)

def test_floip_format(self):
"""
Test FLOIP output results.
"""
self._make_submissions()
view = DataViewSet.as_view({'get': 'list'})
formid = self.xform.pk
request = self.factory.get(
'/',
HTTP_ACCEPT='application/vnd.org.flowinterop.results+json',
**self.extra)
response = view(request, pk=formid)
self.assertEqual(response.status_code, 200)
response.render()
floip_list = json.loads(response.content)
self.assertTrue(isinstance(floip_list, list))
data = [
response.data[0]['_submission_time'], response.data[0]['_id'],
u'bob',
u'transport/available_transportation_types_to_referral_facility',
u'none', None
]
self.assertEqual(floip_list[0], data)

class TestOSM(TestAbstractViewSet):

class TestOSM(TestAbstractViewSet):
def setUp(self):
super(self.__class__, self).setUp()
self._login_user_and_profile()
Expand Down
37 changes: 37 additions & 0 deletions onadata/libs/renderers/renderers.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,27 @@

from onadata.libs.utils.osm import get_combined_osm

IGNORE_FIELDS = ['meta/instanceID', 'formhub/uuid']


def floip_rows_list(data):
"""
Yields a row of FLOIP results data from dict data.
"""
for key in data:
if not (key.startswith('_') or key in IGNORE_FIELDS):
yield [data['_submission_time'], data['_id'],
data['_submitted_by'], key, data[key], None]


def floip_list(data):
"""
Yields FLOIP results data row from list data.
"""
for item in data:
for i in floip_rows_list(item):
yield i


class DecimalEncoder(JSONEncoder):
def default(self, obj):
Expand Down Expand Up @@ -268,6 +289,22 @@ class DecimalJSONRenderer(JSONRenderer):


class FLOIPRenderer(JSONRenderer):
"""
FLOIP Results data renderer.
"""
media_type = 'application/vnd.org.flowinterop.results+json'
format = 'json'
charset = 'utf-8'

def render(self, data, accepted_media_type=None, renderer_context=None):
request = renderer_context['request']
response = renderer_context['response']
results = data
if request.method == 'GET' and response.status_code == 200:
if isinstance(data, dict):
results = [i for i in floip_rows_list(data)]
else:
results = [i for i in floip_list(data)]

return super(FLOIPRenderer, self).render(results, accepted_media_type,
renderer_context)
2 changes: 1 addition & 1 deletion onadata/libs/serializers/data_serializer.py
Original file line number Diff line number Diff line change
Expand Up @@ -359,7 +359,7 @@ def to_internal_value(self, data):
"""
Overrides validating rows in list data.
"""
if isinstance(data, list):
if isinstance(data, list) and len(data) == 6:
data = {data[1]: data}

return data
Expand Down

0 comments on commit 2dc9882

Please sign in to comment.