# -*- coding: utf-8 -*-
from setuptools import setup

packages = \
['pykobo']

package_data = \
{'': ['*']}

install_requires = \
['pandas>=1.5.1,<2.0.0', 'requests>=2.28.1,<3.0.0']

setup_kwargs = {
    'name': 'pykobo',
    'version': '0.1.2',
    'description': 'A Python module to fetch data from the Kobo API',
    'long_description': '![PyPI](https://img.shields.io/pypi/v/pykobo)\n\n# pykobo\n\nPykobo is a Python module that fetches data from [Kobo](https://www.kobotoolbox.org/) forms via the [Kobo API](https://support.kobotoolbox.org/api.html).\n\nThe data is returned as a [pandas](https://pandas.pydata.org/) DataFrame making it easy to integrate in your workflow for further cleaning, filtering, aggregatation, etc...  \n\n## Functionalities\nPykobo can:\n* Get the list of forms a user has access to \n* Fetch the data of a form (with names or labels for the columns and choices) as a pandas DataFrame\n* Download a form in XLS or XML format\n\n## Install\n\n```bash\n$ pip install pykobo\n```\n\n## Examples\n\n### How to start\n\nNB: The example below uses [kf.kobotoolbox.org](https://kf.kobotoolbox.org/) but pykobo also works with [kobo.humanitarianresponse.info](https://kobo.humanitarianresponse.info/) and any other Kobo server.\n\nTo get your API token, see [here](https://support.kobotoolbox.org/api.html#getting-your-api-token).\n\n```python\nimport pykobo\n\n\nURL_KOBO_API = "https://kf.kobotoolbox.org/api/v2"\nMYTOKEN = "2bc8e0201d23dac4ec1c334107698147b81513a2"\n\n# Initialize the Manager object\nkm = pykobo.Manager(url_api=URL_KOBO_API, token=MYTOKEN)\n```\n\n### Get the list of forms you have access to\n\n```python\nmy_forms = km.get_forms()\n\n```\nThis returns a Python list of KoboForm objetcs\n\n```python\nprint(my_forms)\n\n[   KoboForm(\'tpz2buHAdXxcN0JVrZaSdk\'),\n    KoboForm(\'vyARFbyE8Gv3RUvXNfdTRj\'),\n    KoboForm(\'wogyYJzUu2ZFVnzqGg8K7q\'),\n    KoboForm(\'bQLZapErE3UqqG9Avntkhd\')]\n\n# Each form contains metadata\nfor f in my_forms:\n      print(f.metadata)\n\n{   \'date_created\': \'2022-07-14T20:44:11.929901Z\',\n    \'date_modified\': \'2022-10-02T07:49:19.714891Z\',\n    \'geo\': True,\n    \'has_deployment\': True,\n    \'name\': \'Household survey\',\n    \'owner\': \'pvernier\',\n    \'version_id\': \'aqUMoSqANiEgH3j4Nn3Cr7\'}\n{   \'date_created\': \'2022-07-14T12:41:14.665314Z\',\n    \'date_modified\': \'2022-09-28T11:55:15.408542Z\',\n    \'geo\': True,\n    \'has_deployment\': True,\n    \'name\': \'Health facilities monitoring\',\n    \'owner\': \'pvernier\',\n    \'version_id\': \'abLugnJGURSyyZ8RZxC0wQ\'}\n{   \'date_created\': \'2022-07-14T13:40:32.033446Z\',\n    \'date_modified\': \'2022-09-28T09:19:20.691620Z\',\n    \'geo\': False,\n    \'has_deployment\': True,\n    \'name\': \'Post emergency evaluation\',\n    \'owner\': \'pvernier\',\n    \'version_id\': \'aQQUmPns7xLUL4Ro0amqwS\'}\n{   \'date_created\': \'2022-09-14T16:54:06.990672Z\',\n    \'date_modified\': \'2022-09-20T13:27:52.410261Z\',\n    \'geo\': True,\n    \'has_deployment\': True,\n    \'name\': \'Identification of burnt areas\',\n    \'owner\': \'pvernier\',\n    \'version_id\': \'xes8JkQRpbDcbct9sqmCYZ\'}  \n```\n\n### Fetch a single form with its uid.\n\n```python\nuid = \'tpz2buHAdXxcN0JVrZaSdk\'\n\nmy_form = km.get_form(uid)\n\nprint(my_form.metadata)\n\n{   \'date_created\': \'2022-07-14T20:44:11.929901Z\',\n    \'date_modified\': \'2022-10-02T07:49:19.714891Z\',\n    \'geo\': True,\n    \'has_deployment\': True,\n    \'name\': \'Household survey\',\n    \'owner\': \'pvernier\',\n    \'version_id\': \'aqUMoSqANiEgH3j4Nn3Cr7\'}\n\n```\n\n\n### Fetch the data of a form\n\n```python\nmy_form.fetch_data()\n\n# The data is accessible via the `data` attribute as a pandas DataFrame\n\nprint(my_form.data)\n                             start                            end       today         username                  deviceid            phonenumber  ...     _submission_time _tags _notes _validation_status    _submitted_by _index\n0    2022-09-01T15:47:55.797+02:00  2022-09-01T15:51:48.302+02:00  2022-09-01  surveyer_1  collect:4vUec4gLVJx3GP1D                    NaN  ...  2022-09-01T13:52:04    []     []                 {}  surveyer_1      1\n1    2022-09-01T15:58:08.251+02:00  2022-09-01T16:08:14.548+02:00  2022-09-01  surveyer_1  collect:Xk9Z5f1VTW5nig68                    NaN  ...  2022-09-01T14:08:46    []     []                 {}  surveyer_1      2\n2    2022-09-01T14:05:08.484+02:00  2022-09-01T16:17:59.305+02:00  2022-09-01  surveyer_1  collect:0Y8Cozz5fzI8jczs                    NaN  ...  2022-09-01T14:18:36    []     []                 {}  surveyer_1      3\n3    2022-09-01T16:20:39.699+02:00  2022-09-01T16:32:03.393+02:00  2022-09-01  surveyer_1  collect:MPi52tvGiPY6AuK3                    NaN  ...  2022-09-01T14:32:27    []     []                 {}  surveyer_1      4\n...\n...\n[595 rows x 38 columns]\n\nprint(type(my_form.data))\n\n<class \'pandas.core.frame.DataFrame\'>\n\n# The method `fetch_data` returns the data using the Kobo columns and choices names\n\nprint(my_form.data.columns)\n\nIndex([\'start\', \'end\', \'today\', \'username\', \'deviceid\', \'phonenumber\', \'date\',\n       \'health_area\', \'village_name\', \'team_number\', \'cluster_number\',\n       \'household_number\', \'gps\', \'_gps_latitude\', \'_gps_longitude\',\n       \'_gps_altitude\', \'_gps_precision\', \'hhh_present\',\n       \'age_hhh\', \'consent\', \'number_children\',\n       \'__version__\', \'_id\', \'_uuid\', \'_status\', \'_submission_time\',\n       \'_tags\', \'_notes\', \'_validation_status\', \'_submitted_by\', \'_index\'],\n      dtype=\'object\')\n```\n\n### Display the data using Kobo labels for columns and/or choices\n\n\n```python\nmy_form.display(columns_as=\'label\', choices_as=\'label\')\n\nprint(my_form.data.columns)\n\nIndex([\'start\', \'end\', \'today\', \'username\', \'deviceid\', \'phonenumber\',\n       \'Date of the survey\', \'Health zone\', \'Name of the village\', \'team number\',\n       \'Cluster number\', \'Household number\', \'GPS Coordinates\',\n       \'_GPS Coordinates_latitude\', \'_GPS Coordinates_longitude\',\n       \'_GPS Coordinates_altitude\', \'_GPS Coordinates_precision\',\n       \'Head of the household present?\',\n       \'Age of the head of the household \',\n       \'Consent obtained\',\n       \'Number of children in the household\',\n       \'__version__\', \'_id\', \'_uuid\', \'_status\', \'_submission_time\', \'_tags\',\n       \'_notes\', \'_validation_status\', \'_submitted_by\', \'_index\'],\n      dtype=\'object\')\n\n\n# You can go back and forth between names and labels as much as you want \nmy_form.display(columns_as=\'label\', choices_as=\'name\')\nmy_form.display(columns_as=\'name\', choices_as=\'label\')\nmy_form.display(columns_as=\'name\', choices_as=\'name\')\nmy_form.display(columns_as=\'label\', choices_as=\'label\')\n\n```\n#### Note\n* For questions of type `select_multiple` the different answers are separated by a \'|\'.\n\n* If a form contains `n` columns with the same label, a suffix `(1)` to `(n)` will be added to each of the columns.\n\n### Repeats\n\n[Repeats](https://xlsform.org/en/#repeats) are supported (only one level, not repeats inside repeats).\nIn this case data of the repeat groups are separated from the \'main\' data and accessible via the \'repeats\' attribute\nwhich returns a Python dictionary\n\n```python\n\nprint(my_form.has_repeats)\n\nTrue\n# This means that the form has at least 1 repeat group\n\nprint(my_form.repeats.keys())\n\ndict_keys([\'children_questions\'])\n# The form has 1 repeat group called \'children_questions\'\n\n\nprint(my_form.repeats[\'children_questions\'])\n\n\n     index_repeat Sex of the child Age of the child  ... Going to school?  _parent_index\n0               1                           Male              No                    2\n1               2                           Female            No                    2\n2               1                           Female            No                    4\n3               1                           Female            Yes                   5\n4               2                           Female            No                    5\n...\n...\n[1040 rows x 27 columns]\n\n```\nThe column `_index` in the main DataFrame (my_form.data) and the column `_parent_index` in the DatFrame of the repeat\ngroup can be used to join the 2 DataFrames.\n\n```python\n\ndf_join = pd.merge(\n    my_form.data,\n    my_form.repeats[\'groupe_questions_enfants\'],\n    how="left",\n    left_on=\'_index\',\n    right_on=\'_parent_index\'\n)\n\n```\n### Save the data to file\n\nBecause the data is a pandas DataFrame, we can take advantage of the [many](https://pandas.pydata.org/docs/user_guide/io.html) pandas methods to export it to a file.\n\n```python\n# CSV\ndf_join.to_csv(\'household_survey.csv\', index=False)\n\n# Excel\ndf_join.to_excel(\'household_survey.xlsx\', index=False)\n```\n\n### Download a form in XLS or XML format\n\n```python\nmy_form.download_form(\'xls\')\n```\nThis downloads the XLSForm `tpz2buHAdXxcN0JVrZaSdk.xls` in the current working directory\n\n## Also\nPykobo has a bunch of utility methods that make easy to clean you data (not documented yet).\n\n## Note\nPykobo only reads and fetches data from Kobo forms. It doesn\'t update or delete the forms and their data on the Kobo server.\n\n## Dependencies\n* requests\n* pandas\n* numpy\n\n## TO DO\n* Add possibility to display group name as a prefix\n* Add method to download media files\n* Clean and document utility functions\n* Be more consistent and robust in case of errors\n* Calculate stats on forms time duration',
    'author': 'pvernier',
    'author_email': 'pvernier82@gmail.com',
    'maintainer': 'None',
    'maintainer_email': 'None',
    'url': 'None',
    'packages': packages,
    'package_data': package_data,
    'install_requires': install_requires,
    'python_requires': '>=3.8,<4.0',
}


setup(**setup_kwargs)
