From 73f276c5dbe33cd619d9f55ca05d14affa3aab8f Mon Sep 17 00:00:00 2001 From: Martin Burchell Date: Fri, 15 May 2020 15:22:14 +0100 Subject: [PATCH] Handle EmptyData error from pandas read_csv --- redcap/project.py | 25 +++++++++++++++++-------- test/test_project.py | 18 ++++++++++++++++++ 2 files changed, 35 insertions(+), 8 deletions(-) diff --git a/redcap/project.py b/redcap/project.py index c0ba925..977ede2 100755 --- a/redcap/project.py +++ b/redcap/project.py @@ -176,7 +176,6 @@ def export_fem(self, arms=None, format='json', df_kwargs=None): """ ret_format = format if format == 'df': - from pandas import read_csv ret_format = 'csv' pl = self.__basepl('formEventMapping', format=ret_format) @@ -189,9 +188,9 @@ def export_fem(self, arms=None, format='json', df_kwargs=None): return response elif format == 'df': if not df_kwargs: - return read_csv(StringIO(response)) - else: - return read_csv(StringIO(response), **df_kwargs) + df_kwargs = {} + + return self.read_csv(StringIO(response), **df_kwargs) def export_metadata(self, fields=None, forms=None, format='json', df_kwargs=None): @@ -219,7 +218,6 @@ def export_metadata(self, fields=None, forms=None, format='json', """ ret_format = format if format == 'df': - from pandas import read_csv ret_format = 'csv' pl = self.__basepl('metadata', format=ret_format) to_add = [fields, forms] @@ -235,7 +233,7 @@ def export_metadata(self, fields=None, forms=None, format='json', elif format == 'df': if not df_kwargs: df_kwargs = {'index_col': 'field_name'} - return read_csv(StringIO(response), **df_kwargs) + return self.read_csv(StringIO(response), **df_kwargs) def delete_records(self, records): """ @@ -329,7 +327,6 @@ def export_records(self, records=None, fields=None, forms=None, """ ret_format = format if format == 'df': - from pandas import read_csv ret_format = 'csv' pl = self.__basepl('record', format=ret_format) fields = self.backfill_fields(fields, forms) @@ -360,10 +357,22 @@ def export_records(self, records=None, fields=None, forms=None, else: df_kwargs = {'index_col': self.def_field} buf = StringIO(response) - df = read_csv(buf, **df_kwargs) + df = self.read_csv(buf, **df_kwargs) buf.close() return df + def read_csv(self, buf, **df_kwargs): + """Wrapper around pandas read_csv that handles EmptyDataError""" + from pandas import DataFrame, read_csv + from pandas.errors import EmptyDataError + + try: + df = read_csv(buf, **df_kwargs) + except EmptyDataError: + df = DataFrame() + + return df + def metadata_type(self, field_name): """If the given field_name is validated by REDCap, return it's type""" return self.__meta_metadata(field_name, diff --git a/test/test_project.py b/test/test_project.py index 83f7c2e..94ddf8a 100644 --- a/test/test_project.py +++ b/test/test_project.py @@ -615,6 +615,24 @@ def test_import_dataframe(self): self.assertIn('count', response) self.assertNotIn('error', response) + def test_export_records_handles_empty_data_error(self): + self.reg_proj._call_api = mock.Mock() + self.reg_proj._call_api.return_value = "\n", {} + df = self.reg_proj.export_records(format='df') + self.assertTrue(df.empty) + + def test_export_fem_handles_empty_data_error(self): + self.reg_proj._call_api = mock.Mock() + self.reg_proj._call_api.return_value = "\n", {} + df = self.reg_proj.export_fem(format='df') + self.assertTrue(df.empty) + + def test_export_metadata_handles_empty_data_error(self): + self.reg_proj._call_api = mock.Mock() + self.reg_proj._call_api.return_value = "\n", {} + df = self.reg_proj.export_metadata(format='df') + self.assertTrue(df.empty) + @responses.activate def test_date_formatting(self): """Test date_format parameter"""