From c18bee995b820df156ee50b7d01df7db18148b85 Mon Sep 17 00:00:00 2001 From: Alex Morling Date: Tue, 17 Dec 2024 20:15:12 +0200 Subject: [PATCH] ensure we handle empty data --- ecoscope/io/earthranger.py | 58 +++++++++++++++++++++--------------- tests/test_earthranger_io.py | 18 +++++++++++ 2 files changed, 52 insertions(+), 24 deletions(-) diff --git a/ecoscope/io/earthranger.py b/ecoscope/io/earthranger.py index 1b09e45c..e282ccdb 100644 --- a/ecoscope/io/earthranger.py +++ b/ecoscope/io/earthranger.py @@ -513,6 +513,9 @@ def get_subjectgroup_observations( else: subjects = self.get_subjects(subject_group_name=subject_group_name, include_inactive=include_inactive) + if subjects.empty: + return subjects + return self.get_subject_observations(subjects, **kwargs) def get_event_types(self, include_inactive=False, **addl_kwargs): @@ -641,7 +644,9 @@ def get_events( def get_patrol_types(self): df = pd.DataFrame(self._get("activity/patrols/types")) - return df.set_index("id") + if not df.empty: + df = df.set_index("id") + return df def get_patrols(self, since=None, until=None, patrol_type=None, patrol_type_value=None, status=None, **addl_kwargs): """ @@ -872,31 +877,33 @@ def get_patrol_observations(self, patrols_df, include_patrol_details=False, **kw until=patrol_end_time, **kwargs, ) - if include_patrol_details: - observation["patrol_id"] = patrol["id"] - observation["patrol_title"] = patrol["title"] - observation["patrol_serial_number"] = patrol["serial_number"] - observation["patrol_start_time"] = patrol_start_time - observation["patrol_end_time"] = patrol_end_time - observation["patrol_type"] = patrol_type - observation = ( - observation.reset_index() - .merge( - pd.DataFrame(df_pt).add_prefix("patrol_type__"), - left_on="patrol_type", - right_on="id", - ) - .drop( - columns=[ - "patrol_type__ordernum", - "patrol_type__icon_id", - "patrol_type__default_priority", - "patrol_type__is_active", - ] - ) - ) if len(observation) > 0: observation["groupby_col"] = patrol["id"] + + if include_patrol_details: + observation["patrol_id"] = patrol["id"] + observation["patrol_title"] = patrol["title"] + observation["patrol_serial_number"] = patrol["serial_number"] + observation["patrol_start_time"] = patrol_start_time + observation["patrol_end_time"] = patrol_end_time + observation["patrol_type"] = patrol_type + observation = ( + observation.reset_index() + .merge( + pd.DataFrame(df_pt).add_prefix("patrol_type__"), + left_on="patrol_type", + right_on="id", + ) + .drop( + columns=[ + "patrol_type__ordernum", + "patrol_type__icon_id", + "patrol_type__default_priority", + "patrol_type__is_active", + ] + ) + ) + observations.append(observation) except Exception as e: print( @@ -904,6 +911,9 @@ def get_patrol_observations(self, patrols_df, include_patrol_details=False, **kw f"end_time={patrol_end_time} failed for: {e}" ) + if not observations: + return pd.DataFrame() + df = pd.concat(observations) df = clean_time_cols(df) df = ecoscope.base.Relocations(df) diff --git a/tests/test_earthranger_io.py b/tests/test_earthranger_io.py index b0740a30..cc519d4c 100644 --- a/tests/test_earthranger_io.py +++ b/tests/test_earthranger_io.py @@ -11,6 +11,7 @@ import ecoscope from erclient import ERClientException +from ecoscope.io.earthranger import EarthRangerIO from ecoscope.io.earthranger_utils import TIME_COLS pytestmark = pytest.mark.io @@ -427,3 +428,20 @@ def test_get_patrol_events_bad_geojson(get_objects_mock, sample_bad_patrol_event assert not patrol_events.empty # We're rejecting any geojson that's missing geometry or a timestamp assert patrol_events.id.to_list() == ["ebf812f5-e616-40e4-8fcf-ebb3ef6a6364"] + + +@pytest.mark.parametrize( + "er_callable, er_kwargs", + [ + (EarthRangerIO.get_patrols, {}), + (EarthRangerIO.get_subjectgroup_observations, {"subject_group_id": "12345"}), + (EarthRangerIO.get_patrol_observations_with_patrol_filter, {}), + (EarthRangerIO.get_patrol_events, {}), + (EarthRangerIO.get_events, {}), + ], +) +@patch("erclient.client.ERClient._get") +def test_empty_responses(_get_mock, er_io, er_callable, er_kwargs): + _get_mock.return_value = {} + df = er_callable(er_io, **er_kwargs) + assert df.empty