From eba2ee39e0043f337ba1af45ffaa16c02fc5f1a4 Mon Sep 17 00:00:00 2001 From: Mattia Almansi Date: Thu, 19 Dec 2024 16:02:44 +0100 Subject: [PATCH] Arco list handling (#252) * ARCO: handle lists * add available options --- cads_adaptors/adaptors/arco.py | 25 ++++++++++++------- tests/test_50_arco_adaptor.py | 44 ++++++++++++++++++++++++---------- 2 files changed, 47 insertions(+), 22 deletions(-) diff --git a/cads_adaptors/adaptors/arco.py b/cads_adaptors/adaptors/arco.py index b8310172..3e2e0f9f 100644 --- a/cads_adaptors/adaptors/arco.py +++ b/cads_adaptors/adaptors/arco.py @@ -24,17 +24,17 @@ def _normalise_variable(self, request: Request) -> None: request["variable"] = variable def _normalise_location(self, request: Request) -> None: - location = request.get("location") - if not location: - raise InvalidRequest( - "Please specify a valid location using the format {'latitude': 0, 'longitude': 0}" - ) + locations = ensure_list(request.get("location")) + msg = "Please specify a single valid location using the format {'latitude': 0, 'longitude': 0}" + if len(locations) != 1: + raise InvalidRequest(msg) + (location,) = locations if not isinstance(location, dict) or not set(location) == SPATIAL_COORDINATES: - raise InvalidRequest(f"Invalid {location=}.") + raise InvalidRequest(f"Invalid {location=}. {msg}") try: request["location"] = {k: float(v) for k, v in sorted(location.items())} except (ValueError, TypeError): - raise InvalidRequest(f"Invalid {location=}.") + raise InvalidRequest(f"Invalid {location=}. {msg}") def _normalise_date(self, request: Request) -> None: date = ensure_list(request.get("date")) @@ -50,12 +50,19 @@ def _normalise_date(self, request: Request) -> None: request["date"] = ["/".join([split[0], split[-1]])] def _normalise_data_format(self, request: Request) -> None: - data_format = request.get("data_format", DEFAULT_DATA_FORMAT) + data_formats = ensure_list(request.get("data_format", DEFAULT_DATA_FORMAT)) + if len(data_formats) != 1: + raise InvalidRequest("Please specify a single data_format.") + (data_format,) = data_formats + available_options = set() for key, value in DATA_FORMATS.items(): + available_options.update(value) if isinstance(data_format, str) and data_format.lower() in value: request["data_format"] = key return - raise InvalidRequest(f"Invalid {data_format=}.") + raise InvalidRequest( + f"Invalid {data_format=}. Available options: {available_options}" + ) def normalise_request(self, request: Request) -> Request: if self.normalised: diff --git a/tests/test_50_arco_adaptor.py b/tests/test_50_arco_adaptor.py index 9f560567..56a9de28 100644 --- a/tests/test_50_arco_adaptor.py +++ b/tests/test_50_arco_adaptor.py @@ -48,7 +48,7 @@ def mock_add_user_visible_error( "original,expected", [ ( - {"variable": "foo", "location": {"latitude": 0.0, "longitude": 0.0}}, + {"variable": "foo", "location": {"latitude": 0, "longitude": 0}}, { "data_format": "netcdf", "location": {"latitude": 0.0, "longitude": 0.0}, @@ -58,7 +58,7 @@ def mock_add_user_visible_error( ), ( { - "data_format": "nc", + "data_format": ["nc"], "location": { "longitude": 1, "latitude": "2", @@ -91,10 +91,20 @@ def test_arco_normalise_request( "invalid_request, match", [ ( - {"location": {"latitude": 0.0, "longitude": 0.0}}, + {"location": {"latitude": 0, "longitude": 0}}, "specify at least one variable", ), - ({"variable": "FOO"}, "specify a valid location"), + ({"variable": "FOO"}, "specify a single valid location"), + ( + { + "variable": "FOO", + "location": [ + {"latitude": 0, "longitude": 0}, + {"latitude": 1, "longitude": 1}, + ], + }, + "specify a single valid location", + ), ({"variable": "FOO", "location": "foo"}, "Invalid location"), ({"variable": "FOO", "location": {"foo": "1"}}, "Invalid location"), ( @@ -104,7 +114,7 @@ def test_arco_normalise_request( ( { "variable": "FOO", - "location": {"latitude": 0.0, "longitude": 0.0}, + "location": {"latitude": 0, "longitude": 0}, "date": [1, 2, 3], }, "specify a single date range", @@ -112,7 +122,15 @@ def test_arco_normalise_request( ( { "variable": "FOO", - "location": {"latitude": 0.0, "longitude": 0.0}, + "location": {"latitude": 0, "longitude": 0}, + "data_format": ["foo", "bar"], + }, + "specify a single data_format", + ), + ( + { + "variable": "FOO", + "location": {"latitude": 0, "longitude": 0}, "data_format": "foo", }, "Invalid data_format", @@ -144,7 +162,7 @@ def test_arco_select_variable( fp = arco_adaptor.retrieve( { "variable": variable, - "location": {"latitude": 0.0, "longitude": 0.0}, + "location": {"latitude": 0, "longitude": 0}, } ) ds = xr.open_dataset(fp.name) @@ -177,7 +195,7 @@ def test_arco_select_date( fp = arco_adaptor.retrieve( { "variable": "FOO", - "location": {"latitude": 0.0, "longitude": 0.0}, + "location": {"latitude": 0, "longitude": 0}, "date": date, } ) @@ -201,7 +219,7 @@ def test_arco_data_format( ): request = { "variable": "FOO", - "location": {"latitude": 0.0, "longitude": 0.0}, + "location": {"latitude": 0, "longitude": 0}, "data_format": data_format, } fp = arco_adaptor.retrieve(request) @@ -230,7 +248,7 @@ def test_arco_data_format( ( { "variable": "wrong", - "location": {"latitude": 0.0, "longitude": 0.0}, + "location": {"latitude": 0, "longitude": 0}, }, KeyError, "Invalid variable: 'wrong'.", @@ -238,7 +256,7 @@ def test_arco_data_format( ( { "variable": "FOO", - "location": {"latitude": 0.0, "longitude": 0.0}, + "location": {"latitude": 0, "longitude": 0}, "date": "foo", }, TypeError, @@ -247,7 +265,7 @@ def test_arco_data_format( ( { "variable": "FOO", - "location": {"latitude": 0.0, "longitude": 0.0}, + "location": {"latitude": 0, "longitude": 0}, "date": 1990, }, ArcoDataLakeNoDataError, @@ -274,7 +292,7 @@ def test_connection_problems( arco_adaptor.retrieve( { "variable": "FOO", - "location": {"latitude": 0.0, "longitude": 0.0}, + "location": {"latitude": 0, "longitude": 0}, } ) assert (