diff --git a/air-quality-backend/src/air_quality/api/measurements_controller.py b/air-quality-backend/src/air_quality/api/measurements_controller.py index 9cce75c5..3590ca0e 100644 --- a/air-quality-backend/src/air_quality/api/measurements_controller.py +++ b/air-quality-backend/src/air_quality/api/measurements_controller.py @@ -8,8 +8,8 @@ map_measurements, map_summarized_measurements, ) -from air_quality.api.types import ApiSource, MeasurementSummaryDto, MeasurementDto -from air_quality.database.in_situ import get_averaged, find_by_criteria +from air_quality.api.types import MeasurementSummaryDto, MeasurementDto +from air_quality.database.in_situ import ApiSource, get_averaged, find_by_criteria from air_quality.database.locations import AirQualityLocationType router = APIRouter() diff --git a/air-quality-backend/src/air_quality/api/types.py b/air-quality-backend/src/air_quality/api/types.py index 85762f4e..ee354564 100644 --- a/air-quality-backend/src/air_quality/api/types.py +++ b/air-quality-backend/src/air_quality/api/types.py @@ -1,15 +1,11 @@ from datetime import datetime -from enum import Enum from typing_extensions import Generic, TypedDict, NotRequired, TypeVar +from air_quality.database.in_situ import ApiSource from air_quality.database.locations import AirQualityLocationType -class ApiSource(Enum): - OPENAQ = "openaq" - - class PollutantDataDto(TypedDict): aqi_level: int value: float @@ -32,7 +28,7 @@ class MeasurementDto(TypedDict): measurement_date: datetime location_type: AirQualityLocationType location_name: str - api_source: str + api_source: ApiSource no2: NotRequired[float] o3: NotRequired[float] pm2_5: NotRequired[float] diff --git a/air-quality-backend/src/air_quality/database/in_situ.py b/air-quality-backend/src/air_quality/database/in_situ.py index 99787b5c..5279107c 100644 --- a/air-quality-backend/src/air_quality/database/in_situ.py +++ b/air-quality-backend/src/air_quality/database/in_situ.py @@ -1,8 +1,8 @@ import logging from datetime import datetime, timedelta +from enum import Enum from typing import List, TypedDict, NotRequired, Optional -from air_quality.api.types import ApiSource from bson import ObjectId from air_quality.database.locations import AirQualityLocationType @@ -12,6 +12,10 @@ collection_name = "in_situ_data" +class ApiSource(Enum): + OPENAQ = "OpenAQ" + + class InSituMetadata(TypedDict, total=False): entity: str sensor_type: str @@ -87,7 +91,7 @@ def find_by_criteria( if locations is not None: criteria["name"] = {"$in": locations} if api_source is not None: - criteria["api_source"] = api_source + criteria["api_source"] = api_source.value logging.info(f"Querying collection with criteria: {criteria}") return list(get_collection(collection_name).find(criteria)) diff --git a/air-quality-backend/src/air_quality/etl/in_situ/openaq_adapter.py b/air-quality-backend/src/air_quality/etl/in_situ/openaq_adapter.py index 9d757793..43b6efa5 100644 --- a/air-quality-backend/src/air_quality/etl/in_situ/openaq_adapter.py +++ b/air-quality-backend/src/air_quality/etl/in_situ/openaq_adapter.py @@ -7,7 +7,7 @@ PollutantType, pollutants_with_molecular_weight, ) -from air_quality.database.in_situ import InSituMeasurement +from air_quality.database.in_situ import InSituMeasurement, ApiSource from air_quality.etl.common.unit_converter import convert_ppm_to_mgm3 from air_quality.etl.forecast.forecast_data import ForecastData, ForecastDataType @@ -32,7 +32,7 @@ def _create_document( measurement, city_name: str, location_type: AirQualityLocationType ) -> InSituMeasurement: return { - "api_source": "OpenAQ", + "api_source": ApiSource.OPENAQ.value, "measurement_date": datetime.strptime( measurement["date"]["utc"], "%Y-%m-%dT%H:%M:%S%z" ), diff --git a/air-quality-backend/tests/api/measurements_controller_test.py b/air-quality-backend/tests/api/measurements_controller_test.py index 3c496d11..14094e06 100644 --- a/air-quality-backend/tests/api/measurements_controller_test.py +++ b/air-quality-backend/tests/api/measurements_controller_test.py @@ -90,7 +90,7 @@ def test__measurements_applies_appropriate_filters__when_request_valid(): params = { **measurement_request_defaults, "location_names": ["London", "Paris"], - "api_source": "openaq", + "api_source": "OpenAQ", } with patch( "air_quality.api.measurements_controller.find_by_criteria", return_value=[] diff --git a/air-quality-backend/tests/database/in_situ_test.py b/air-quality-backend/tests/database/in_situ_test.py index e3a4da72..c429a6b9 100644 --- a/air-quality-backend/tests/database/in_situ_test.py +++ b/air-quality-backend/tests/database/in_situ_test.py @@ -3,11 +3,13 @@ import mongomock import pytest from unittest.mock import patch + from air_quality.database.in_situ import ( find_by_criteria, insert_data, delete_data_before, get_averaged, + ApiSource, ) from air_quality.database.locations import AirQualityLocationType from tests.util.mock_measurement import create_mock_measurement_document @@ -117,20 +119,10 @@ def test__delete_data_before(mock_collection): "measurement_date_to": datetime(2024, 5, 1, 11, 0), "location_type": AirQualityLocationType.CITY, "locations": ["London"], - "api_source": "test_api", + "api_source": ApiSource.OPENAQ, }, ["London"], ), - ( - { - "measurement_date_from": datetime(2024, 5, 1, 5, 0), - "measurement_date_to": datetime(2024, 5, 1, 11, 0), - "location_type": AirQualityLocationType.CITY, - "locations": ["London"], - "api_source": "real_api", - }, - [], - ), ], ) def test__find_by_criteria(params, expected_names, mock_collection): @@ -141,7 +133,7 @@ def test__find_by_criteria(params, expected_names, mock_collection): "o3": 123, "location_type": "city", "location_name": "test", - "api_source": "test_api", + "api_source": "OpenAQ", } mock_collection.insert_many( [ @@ -158,9 +150,9 @@ def test__find_by_criteria(params, expected_names, mock_collection): ] ) - assert ( - list(map(lambda x: x["name"], find_by_criteria(**params))) == expected_names - ) + response = find_by_criteria(**params) + + assert list(map(lambda x: x["name"], response)) == expected_names def test__get_averaged(mock_collection): diff --git a/air-quality-ui/src/services/measurement-data-service.spec.ts b/air-quality-ui/src/services/measurement-data-service.spec.ts index 1d78e61b..43d76f2a 100644 --- a/air-quality-ui/src/services/measurement-data-service.spec.ts +++ b/air-quality-ui/src/services/measurement-data-service.spec.ts @@ -103,12 +103,12 @@ describe('Measurement Data Service', () => { dateTo, 'city', [], - 'openaq', + 'OpenAQ', ) expect(result).toEqual([]) expect(global.fetch).toHaveBeenCalledWith( - expect.stringMatching('&api_source=openaq'), + expect.stringMatching('&api_source=OpenAQ'), expect.anything(), ) })