diff --git a/integrations/server/test_covidcast_endpoints.py b/integrations/server/test_covidcast_endpoints.py index 206ed3c54..c04dc318a 100644 --- a/integrations/server/test_covidcast_endpoints.py +++ b/integrations/server/test_covidcast_endpoints.py @@ -11,6 +11,8 @@ from delphi.epidata.maintenance.covidcast_meta_cache_updater import main as update_cache from delphi.epidata.acquisition.covidcast.test_utils import CovidcastBase, CovidcastTestRow +from delphi.epidata.maintenance.coverage_crossref_updater import main as update_crossref + # use the local instance of the Epidata API BASE_URL = "http://delphi_web_epidata/epidata/covidcast" @@ -385,3 +387,25 @@ def test_coverage(self): with self.subTest("invalid geo_type"): out = self._fetch("/coverage", signal=first.signal_pair(), geo_type="doesnt_exist", format="json") self.assertEqual(len(out), 0) + + def test_indicator_geo_coverage(self): + """Request a geo_type:geo_value from the /indicator_geo_coverage endpoint.""" + + self._insert_rows([ + CovidcastTestRow.make_default_row(geo_type="state", geo_value="pa"), + CovidcastTestRow.make_default_row(geo_type="state", geo_value="ny"), + CovidcastTestRow.make_default_row(geo_type="state", geo_value="ny", signal="sig2"), + ]) + + update_crossref() + + response = requests.get( + f"{BASE_URL}/indicator_geo_coverage", + params=dict(data_source="src", signals="sig"), + ) + response.raise_for_status() + out = response.json() + + self.assertEqual(len(out["epidata"]), 2) + self.assertEqual(out["epidata"], ['state:ny', 'state:pa']) + diff --git a/src/server/endpoints/covidcast.py b/src/server/endpoints/covidcast.py index f4875fb6d..fe47f0fd7 100644 --- a/src/server/endpoints/covidcast.py +++ b/src/server/endpoints/covidcast.py @@ -561,6 +561,26 @@ def handle_geo_coverage(): return execute_query(q.query, q.params, fields_string, [], []) +@bp.route("/indicator_geo_coverage", methods=("GET", "POST")) +def handle_indicator_geo_coverage(): + source_signal_sets = parse_source_signal_sets() + source_signal_sets = restrict_by_roles(source_signal_sets) + source_signal_sets, _ = create_source_signal_alias_mapper(source_signal_sets) + + q = QueryBuilder("coverage_crossref_v", "c") + fields_string = ["geo_type", "geo_value"] + + q.set_fields(fields_string) + + q.apply_source_signal_filters("source", "signal", source_signal_sets) + q.set_sort_order("geo_type", "geo_value") + q.group_by = ["c." + field for field in fields_string] # this condenses duplicate results, similar to `SELECT DISTINCT` + + def transform_row(row, proxy): + return f"{row['geo_type']}:{row['geo_value']}" + + return execute_query(q.query, q.params, fields_string, [], [], transform=transform_row) + @bp.route("/anomalies", methods=("GET", "POST")) def handle_anomalies(): """