diff --git a/doc/source/API_Guide.md b/doc/source/API_Guide.md index ecfa88b..5a91f46 100644 --- a/doc/source/API_Guide.md +++ b/doc/source/API_Guide.md @@ -12,9 +12,17 @@ Check [here](https://wiki.oceannetworks.ca/display/O2A/Glossary+of+Terms) for mo The [ONC](#onc.onc.ONC) class provides a wrapper for Oceans 3.0 API requests. All the client library's functionality is provided as methods of this class. +Each [Oceans 3.0 public API](https://data.oceannetworks.ca/OpenAPI) has a corresponding public method in this class. +In addition, the ONC class provides some useful helper methods that involve multiple APIs to simplify the workflow. Create an ONC object to access this library's functionalities. +```python +from onc import ONC + +onc = ONC("YOUR_TOKEN_HERE") +``` + ## Discovery methods Discovery methods can be used to search for available locations, deployments, device categories, devices, properties, and data products. @@ -65,12 +73,20 @@ If the data product requested doesn't exist in our archive, it will be generated ::: -| Method | Description | API Endpoint | -| :-----------------------------------------------------: | :--------------------------------------------: | :------------------------------------------------------------------------------------------------------: | -| [orderDataProduct](#onc.onc.ONC.orderDataProduct) | Request, run, and download
a data product | | -| [requestDataProduct](#onc.onc.ONC.requestDataProduct) | Request a data product | [/dataProductDelivery/request](https://data.oceannetworks.ca/OpenAPI#get-/dataProductDelivery/request) | -| [runDataProduct](#onc.onc.ONC.runDataProduct) | Run a requested data product | [/dataProductDelivery/run](https://data.oceannetworks.ca/OpenAPI#get-/dataProductDelivery/run) | -| [downloadDataProduct](#onc.onc.ONC.downloadDataProduct) | Download a data product | [/dataProductDelivery/download](https://data.oceannetworks.ca/OpenAPI#get-/dataProductDelivery/download) | +| Method | Description | API Endpoint | +| :-----------------------------------------------------: | :-------------------------------------------: | :------------------------------------------------------------------------------------------------------: | +| [requestDataProduct](#onc.onc.ONC.requestDataProduct) | Request a data product | [/dataProductDelivery/request](https://data.oceannetworks.ca/OpenAPI#get-/dataProductDelivery/request) | +| [checkDataProduct](#onc.onc.ONC.checkDataProduct) | Check status of a
requested data product | [/dataProductDelivery/status](https://data.oceannetworks.ca/OpenAPI#get-/dataProductDelivery/status) | +| [runDataProduct](#onc.onc.ONC.runDataProduct) | Run a requested data product | [/dataProductDelivery/run](https://data.oceannetworks.ca/OpenAPI#get-/dataProductDelivery/run) | +| [cancelDataProduct](#onc.onc.ONC.cancelDataProduct) | Cancel a running data product | [/dataProductDelivery/cancel](https://data.oceannetworks.ca/OpenAPI#get-/dataProductDelivery/cancel) | +| [restartDataProduct](#onc.onc.ONC.restartDataProduct) | Restart a cancelled data product | [/dataProductDelivery/restart](https://data.oceannetworks.ca/OpenAPI#get-/dataProductDelivery/restart) | +| [downloadDataProduct](#onc.onc.ONC.downloadDataProduct) | Download a data product | [/dataProductDelivery/download](https://data.oceannetworks.ca/OpenAPI#get-/dataProductDelivery/download) | + +Helper methods are listed below. + +| Method | Description | +| :-----------------------------------------------: | :---------------------------------------: | +| [orderDataProduct](#onc.onc.ONC.orderDataProduct) | Request, run, and download a data product | ## Near real-time data access methods @@ -103,6 +119,12 @@ Use the _allPages_ parameter to automatically download all pages required for yo | [getDirectRawByLocation](#onc.onc.ONC.getDirectRawByLocation) | Returns raw data
from a specific location and device category | [/rawdata/location](https://data.oceannetworks.ca/OpenAPI#get-/rawdata/location) | | [getDirectRawByDevice](#onc.onc.ONC.getDirectRawByDevice) | Returns raw data from a specific device | [/rawdata/device](https://data.oceannetworks.ca/OpenAPI#get-/rawdata/device) | +Helper methods are listed below. + +| Method | Description | +| :-----------------------------------------------------------: | :-----------------------------------------------------------------------------------: | +| [getSensorCategoryCodes](#onc.onc.ONC.getSensorCategoryCodes) | Returns a list of sensor category codes
prior to querying the scalardata service | + ## Archive file download methods These methods allow users to directly download previously generated data product files from our archive. @@ -131,4 +153,9 @@ Due to security regulations, some very recent files (e.g. hydrophone.wav files i | [getListByLocation](#onc.onc.ONC.getListByLocation) | Returns a list of available archive files
from a specific location and device category | [/archivefile/location](https://data.oceannetworks.ca/OpenAPI#get-/archivefile/location) | | [getListByDevice](#onc.onc.ONC.getListByDevice) | Returns a list of available archive files
from a specific device | [/archivefile/device](https://data.oceannetworks.ca/OpenAPI#get-/archivefile/device) | | [getFile](#onc.onc.ONC.getFile) | Download an archive file | [/archivefile/download](https://data.oceannetworks.ca/OpenAPI#get-/archivefile/download) | -| [getDirectFiles](#onc.onc.ONC.getDirectFiles) | Download a list of archived files
that match the filters provided | | + +Helper methods are listed below. + +| Method | Description | +| :-------------------------------------------: | :---------------------------------------------------------------: | +| [getDirectFiles](#onc.onc.ONC.getDirectFiles) | Download a list of archived files that match the filters provided | diff --git a/src/onc/modules/_OncDelivery.py b/src/onc/modules/_OncDelivery.py index c47bdf8..6123e75 100644 --- a/src/onc/modules/_OncDelivery.py +++ b/src/onc/modules/_OncDelivery.py @@ -74,6 +74,13 @@ def requestDataProduct(self, filters: dict): self._printProductRequest(response) return response + def checkDataProduct(self, dpRequestId: int): + url = f"{self._config('baseUrl')}api/dataProductDelivery/status" + filters = { + "dpRequestId": dpRequestId, + } + return self._doRequest(url, filters) + def runDataProduct(self, dpRequestId: int, waitComplete: bool): """ Run a product request. @@ -83,6 +90,9 @@ def runDataProduct(self, dpRequestId: int, waitComplete: bool): """ status = "" log = _PollLog(True) + print( + f"To cancel the running data product, run 'onc.cancelDataProduct({dpRequestId})'" # noqa: E501 + ) url = f"{self._config('baseUrl')}api/dataProductDelivery" runResult = {"runIds": [], "fileCount": 0, "runTime": 0, "requestCount": 0} @@ -108,6 +118,8 @@ def runDataProduct(self, dpRequestId: int, waitComplete: bool): if waitComplete: status = data[0]["status"] log.logMessage(data) + if status == "cancelled": + break if code != 200: sleep(self.pollPeriod) else: @@ -128,6 +140,24 @@ def runDataProduct(self, dpRequestId: int, waitComplete: bool): return runResult + def cancelDataProduct(self, dpRequestId: int): + url = f"{self._config('baseUrl')}api/dataProductDelivery/cancel" + filters = { + "dpRequestId": dpRequestId, + } + return self._doRequest(url, filters) + + def restartDataProduct(self, dpRequestId: int, waitComplete: bool): + url = f"{self._config('baseUrl')}api/dataProductDelivery/restart" + filters = { + "dpRequestId": dpRequestId, + } + data = self._doRequest(url, filters) + if waitComplete: + return self.runDataProduct(dpRequestId, True) + else: + return data + def downloadDataProduct( self, runId: int, diff --git a/src/onc/modules/_OncRealTime.py b/src/onc/modules/_OncRealTime.py index d39d782..5ff5c85 100644 --- a/src/onc/modules/_OncRealTime.py +++ b/src/onc/modules/_OncRealTime.py @@ -1,3 +1,5 @@ +from typing import Any + from ._MultiPage import _MultiPage from ._OncService import _OncService @@ -46,9 +48,16 @@ def getDirectRawByDevice(self, filters: dict, allPages: bool): """ return self._getDirectAllPages(filters, "rawdata", "getByDevice", allPages) + def getSensorCategoryCodes(self, filters: dict): + updated_filters = filters | {"returnOptions": "excludeScalarData"} + if "deviceCode" in filters: + return self.getDirectByDevice(updated_filters, False)["sensorData"] + else: + return self.getDirectByLocation(updated_filters, False)["sensorData"] + def _getDirectAllPages( self, filters: dict, service: str, method: str, allPages: bool - ): + ) -> Any: """ Keeps downloading all scalar or raw data pages until finished. diff --git a/src/onc/modules/_OncService.py b/src/onc/modules/_OncService.py index 442983f..3d47fc9 100644 --- a/src/onc/modules/_OncService.py +++ b/src/onc/modules/_OncService.py @@ -39,6 +39,7 @@ def _doRequest(self, url: str, filters: dict | None = None, getTime: bool = Fals """ if filters is None: filters = {} + filters["token"] = self._config("token") timeout = self._config("timeout") txtParams = parse.unquote(parse.urlencode(filters)) diff --git a/src/onc/onc.py b/src/onc/onc.py index 12ef40c..5add9ee 100644 --- a/src/onc/onc.py +++ b/src/onc/onc.py @@ -782,9 +782,80 @@ def orderDataProduct( def requestDataProduct(self, filters: dict): return self.delivery.requestDataProduct(filters) + def checkDataProduct(self, dpRequestId: int): + """ + Check status of a requested data product. + + The API endpoint is ``/dataProductDelivery/status``. + + See https://data.oceannetworks.ca/OpenAPI#get-/dataProductDelivery/status + for usage. + + Parameters + ---------- + dpRequestId : int + A dpRequestId returned from calling ``requestDataProduct``. + + Returns + ------- + dict + API response. + """ + return self.delivery.checkDataProduct(dpRequestId) + def runDataProduct(self, dpRequestId: int, waitComplete: bool = True): return self.delivery.runDataProduct(dpRequestId, waitComplete) + def cancelDataProduct(self, dpRequestId: int): + """ + Cancel a running data product. + + The API endpoint is ``/dataProductDelivery/cancel``. + + See https://data.oceannetworks.ca/OpenAPI#get-/dataProductDelivery/cancel + for usage. + + Parameters + ---------- + dpRequestId : int + A dpRequestId returned from calling ``requestDataProduct``. + + Returns + ------- + list of dict + API response. Each status returned in the list is a dict with the following structure. + + - dpRunId: int + - status: str + """ # noqa: E501 + return self.delivery.cancelDataProduct(dpRequestId) + + def restartDataProduct(self, dpRequestId: int, waitComplete: bool = True): + """ + Restart a cancelled data product. + + The API endpoint is ``/dataProductDelivery/restart``. + + Restart searches cancelled by calling the ``cancelDataProduct`` method. + + See https://data.oceannetworks.ca/OpenAPI#get-/dataProductDelivery/restart + for usage. + + Parameters + ---------- + dpRequestId : int + A dpRequestId returned from calling ``requestDataProduct``. + + Returns + ------- + list of dict + API response. Each status returned in the list is a dict with the following structure. + + - dpRunId: int + - status: str + """ # noqa: E501 + return self.delivery.restartDataProduct(dpRequestId, waitComplete) + def downloadDataProduct( self, runId: int, @@ -815,6 +886,71 @@ def getDirectRawByLocation(self, filters: dict = None, allPages: bool = False): def getDirectRawByDevice(self, filters: dict = None, allPages: bool = False): return self.realTime.getDirectRawByDevice(filters, allPages) + def getSensorCategoryCodes(self, filters: dict): + """ + Return a list of sensor category codes. + + A helper method for narrowing down the sensorCategoryCodes that are of interest + prior to the use of the scalardata service. + + Parameters + ---------- + filters : dict + Query string parameters in the API request. + Use the same filters for calling ``getDirectByLocation`` or ``getDirectByDevice``. + + Returns + ------- + list of dict + API response. Each sensor category code returned in the list is a dict with the following structure. + + - outputFormat: str + - sensorCategoryCode: str + - sensorCode: str + - sensorName: str + - unitOfMeasure: str + + Examples + -------- + >>> params = { + ... "locationCode": "NCBC", + ... "deviceCategoryCode": "BPR", + ... "propertyCode": "seawatertemperature,totalpressure", + ... } # doctest: +SKIP + >>> onc.getSensorCategoryCodes(params) # doctest: +SKIP + [ + { + "outputFormat": "array", + "sensorCategoryCode": "pressure", + "sensorCode": "Pressure", + "sensorName": "Seafloor Pressure", + "unitOfMeasure": "decibar", + }, + { + "outputFormat": "array", + "sensorCategoryCode": "temperature", + "sensorCode": "Temperature", + "sensorName": "Housing Temperature", + "unitOfMeasure": "C", + }, + { + "outputFormat": "array", + "sensorCategoryCode": "temperature1", + "sensorCode": "temperature1", + "sensorName": "Temperature", + "unitOfMeasure": "C", + }, + { + "outputFormat": "array", + "sensorCategoryCode": "temperature2", + "sensorCode": "temperature2", + "sensorName": "P-Sensor Temperature", + "unitOfMeasure": "C", + }, + ] + """ # noqa: E501 + return self.realTime.getSensorCategoryCodes(filters) + # Archive file methods def getListByLocation(self, filters: dict = None, allPages: bool = False): diff --git a/tests/data_product_delivery/conftest.py b/tests/data_product_delivery/conftest.py index dd36980..8d8950e 100644 --- a/tests/data_product_delivery/conftest.py +++ b/tests/data_product_delivery/conftest.py @@ -13,3 +13,17 @@ def params() -> dict: "dpo_qualityControl": 1, "dpo_resample": "none", } + + +@pytest.fixture() +def expected_keys_download_results() -> dict: + return { + "url": str, + "status": str, + "size": int, + "file": str, + "index": str, + "downloaded": bool, + "requestCount": int, + "fileDownloadTime": float, + } diff --git a/tests/data_product_delivery/test_data_product_delivery_cancel.py b/tests/data_product_delivery/test_data_product_delivery_cancel.py new file mode 100644 index 0000000..ab347b7 --- /dev/null +++ b/tests/data_product_delivery/test_data_product_delivery_cancel.py @@ -0,0 +1,7 @@ +import pytest +import requests + + +def test_invalid_request_id(requester): + with pytest.raises(requests.HTTPError, match=r"API Error 127"): + requester.cancelDataProduct(1234567890) diff --git a/tests/data_product_delivery/test_data_product_delivery_order.py b/tests/data_product_delivery/test_data_product_delivery_order.py index 348305a..17ff728 100644 --- a/tests/data_product_delivery/test_data_product_delivery_order.py +++ b/tests/data_product_delivery/test_data_product_delivery_order.py @@ -2,20 +2,6 @@ import requests -@pytest.fixture() -def expected_keys_download_results() -> dict: - return { - "url": str, - "status": str, - "size": int, - "file": str, - "index": str, - "downloaded": bool, - "requestCount": int, - "fileDownloadTime": float, - } - - def test_invalid_param_value(requester, params): params_invalid_param_value = params | {"dataProductCode": "XYZ123"} with pytest.raises(requests.HTTPError, match=r"API Error 127"): @@ -83,25 +69,3 @@ def test_valid_results_only(requester, params, expected_keys_download_results, u util.assert_dict_key_types( data["downloadResults"][0], expected_keys_download_results ) - - -def test_valid_manual(requester, params, expected_keys_download_results, util): - request_id = requester.requestDataProduct(params)["dpRequestId"] - run_id = requester.runDataProduct(request_id)["runIds"][0] - data = requester.downloadDataProduct(run_id) - - assert ( - len(data) == 3 - ), "The first two are png files, and the third one is the metadata." - - assert data[0]["status"] == "complete" - assert data[0]["index"] == "1" - assert data[0]["downloaded"] is True - - assert data[2]["status"] == "complete" - assert data[2]["index"] == "meta" - assert data[2]["downloaded"] is True - - assert util.get_download_files_num(requester) == 3 - - util.assert_dict_key_types(data[0], expected_keys_download_results) diff --git a/tests/data_product_delivery/test_data_product_delivery_restart.py b/tests/data_product_delivery/test_data_product_delivery_restart.py new file mode 100644 index 0000000..4cf1fe5 --- /dev/null +++ b/tests/data_product_delivery/test_data_product_delivery_restart.py @@ -0,0 +1,7 @@ +import pytest +import requests + + +def test_invalid_request_id(requester): + with pytest.raises(requests.HTTPError, match=r"API Error 127"): + requester.restartDataProduct(1234567890) diff --git a/tests/data_product_delivery/test_data_product_delivery_status.py b/tests/data_product_delivery/test_data_product_delivery_status.py new file mode 100644 index 0000000..a5eb452 --- /dev/null +++ b/tests/data_product_delivery/test_data_product_delivery_status.py @@ -0,0 +1,7 @@ +import pytest +import requests + + +def test_invalid_request_id(requester): + with pytest.raises(requests.HTTPError, match=r"API Error 127"): + requester.checkDataProduct(1234567890) diff --git a/tests/data_product_delivery/test_integration.py b/tests/data_product_delivery/test_integration.py new file mode 100644 index 0000000..39014c7 --- /dev/null +++ b/tests/data_product_delivery/test_integration.py @@ -0,0 +1,65 @@ +import pytest + + +def test_valid_manual(requester, params, expected_keys_download_results, util): + """ + Test request -> status -> run -> download -> status. + + """ + request_id = requester.requestDataProduct(params)["dpRequestId"] + data_status_before_download = requester.checkDataProduct(request_id) + + assert data_status_before_download["searchHdrStatus"] == "OPEN" + + run_id = requester.runDataProduct(request_id)["runIds"][0] + data = requester.downloadDataProduct(run_id) + + assert ( + len(data) == 3 + ), "The first two are png files, and the third one is the metadata." + + assert data[0]["status"] == "complete" + assert data[0]["index"] == "1" + assert data[0]["downloaded"] is True + + assert data[2]["status"] == "complete" + assert data[2]["index"] == "meta" + assert data[2]["downloaded"] is True + + assert util.get_download_files_num(requester) == 3 + + util.assert_dict_key_types(data[0], expected_keys_download_results) + + data_status_after_download = requester.checkDataProduct(request_id) + + assert data_status_after_download["searchHdrStatus"] == "COMPLETED" + + +def test_valid_cancel_restart(requester, params, expected_keys_download_results, util): + """ + Test request -> run -> cancel -> download (fail) -> restart -> download. + + """ + request_id = requester.requestDataProduct(params)["dpRequestId"] + run_id = requester.runDataProduct(request_id, waitComplete=False)["runIds"][0] + data_cancel = requester.cancelDataProduct(request_id) + + assert data_cancel == [{"dpRunId": run_id, "status": "cancelled"}] + + # Uncomment after backend fixes the issue that + # this 400 error response does not contain "errors" key + # with pytest.raises(requests.HTTPError, match=r"API Error XXX"): + with pytest.raises(KeyError): + requester.downloadDataProduct(run_id) + + run_id_2 = requester.restartDataProduct(request_id)["runIds"][0] + assert run_id_2 == run_id + data = requester.downloadDataProduct(run_id) + + assert ( + len(data) == 3 + ), "The first two are png files, and the third one is the metadata." + + assert util.get_download_files_num(requester) == 3 + + util.assert_dict_key_types(data[0], expected_keys_download_results) diff --git a/tests/scalar_data/conftest.py b/tests/scalar_data/conftest.py new file mode 100644 index 0000000..0d71a22 --- /dev/null +++ b/tests/scalar_data/conftest.py @@ -0,0 +1,23 @@ +import pytest + + +@pytest.fixture +def params_device(): + return { + "deviceCode": "BPR-Folger-59", + "dateFrom": "2019-11-23T00:00:00.000Z", + "dateTo": "2019-11-23T00:01:00.000Z", + "rowLimit": 80000, + } + + +@pytest.fixture +def params_location(): + return { + "locationCode": "NCBC", + "deviceCategoryCode": "BPR", + "propertyCode": "seawatertemperature,totalpressure", + "dateFrom": "2019-11-23T00:00:00.000Z", + "dateTo": "2019-11-23T00:01:00.000Z", + "rowLimit": 80000, + } diff --git a/tests/scalar_data/test_get_sensor_category_codes.py b/tests/scalar_data/test_get_sensor_category_codes.py new file mode 100644 index 0000000..ce5ce28 --- /dev/null +++ b/tests/scalar_data/test_get_sensor_category_codes.py @@ -0,0 +1,22 @@ +import pytest + + +@pytest.fixture +def expected_keys(): + return { + "outputFormat": str, + "sensorCategoryCode": str, + "sensorCode": str, + "sensorName": str, + "unitOfMeasure": str, + } + + +def test_valid_params_by_location(requester, params_location, expected_keys, util): + data = requester.getSensorCategoryCodes(params_location) + util.assert_dict_key_types(data[0], expected_keys) + + +def test_valid_params_by_device(requester, params_device, expected_keys, util): + data = requester.getSensorCategoryCodes(params_device) + util.assert_dict_key_types(data[0], expected_keys) diff --git a/tests/scalar_data/test_scalardata_device.py b/tests/scalar_data/test_scalardata_device.py index 929ab81..83ea4f6 100644 --- a/tests/scalar_data/test_scalardata_device.py +++ b/tests/scalar_data/test_scalardata_device.py @@ -3,42 +3,32 @@ @pytest.fixture -def params(): - return { - "deviceCode": "BPR-Folger-59", - "dateFrom": "2019-11-23T00:00:00.000Z", - "dateTo": "2019-11-23T00:01:00.000Z", - "rowLimit": 80000, - } - - -@pytest.fixture -def params_multiple_pages(params): +def params_multiple_pages(params_device): # rowLimit should be less than the total number of rows. - return params | {"rowLimit": 25} + return params_device | {"rowLimit": 25} -def test_invalid_param_value(requester, params): - params_invalid_param_value = params | {"deviceCode": "XYZ123"} +def test_invalid_param_value(requester, params_device): + params_invalid_param_value = params_device | {"deviceCode": "XYZ123"} with pytest.raises(requests.HTTPError, match=r"API Error 127"): requester.getDirectByDevice(params_invalid_param_value) -def test_invalid_param_name(requester, params): - params_invalid_param_name = params | {"deviceCodes": "BPR-Folger-59"} +def test_invalid_param_name(requester, params_device): + params_invalid_param_name = params_device | {"deviceCodes": "BPR-Folger-59"} with pytest.raises(requests.HTTPError, match=r"API Error 129"): requester.getDirectByDevice(params_invalid_param_name) -def test_no_data(requester, params): - params_no_data = params | {"dateFrom": "2000-01-01", "dateTo": "2000-01-02"} +def test_no_data(requester, params_device): + params_no_data = params_device | {"dateFrom": "2000-01-01", "dateTo": "2000-01-02"} data = requester.getDirectByDevice(params_no_data) assert data["sensorData"] is None -def test_valid_params_one_page(requester, params, params_multiple_pages): - data = requester.getDirectByDevice(params) +def test_valid_params_one_page(requester, params_device, params_multiple_pages): + data = requester.getDirectByDevice(params_device) data_all_pages = requester.getDirectByDevice(params_multiple_pages, allPages=True) assert ( diff --git a/tests/scalar_data/test_scalardata_location.py b/tests/scalar_data/test_scalardata_location.py index 0d0327e..8c9631c 100644 --- a/tests/scalar_data/test_scalardata_location.py +++ b/tests/scalar_data/test_scalardata_location.py @@ -3,43 +3,34 @@ @pytest.fixture -def params(): - return { - "locationCode": "NCBC", - "deviceCategoryCode": "BPR", - "propertyCode": "seawatertemperature,totalpressure", - "dateFrom": "2019-11-23T00:00:00.000Z", - "dateTo": "2019-11-23T00:01:00.000Z", - "rowLimit": 80000, - } - - -@pytest.fixture -def params_multiple_pages(params): +def params_multiple_pages(params_location): # rowLimit should be less than the total number of rows. - return params | {"rowLimit": 25} + return params_location | {"rowLimit": 25} -def test_invalid_param_value(requester, params): - params_invalid_param_value = params | {"locationCode": "XYZ123"} +def test_invalid_param_value(requester, params_location): + params_invalid_param_value = params_location | {"locationCode": "XYZ123"} with pytest.raises(requests.HTTPError, match=r"API Error 127"): requester.getDirectByLocation(params_invalid_param_value) -def test_invalid_param_name(requester, params): - params_invalid_param_name = params | {"locationCodes": "NCBC"} +def test_invalid_param_name(requester, params_location): + params_invalid_param_name = params_location | {"locationCodes": "NCBC"} with pytest.raises(requests.HTTPError, match=r"API Error 129"): requester.getDirectByLocation(params_invalid_param_name) -def test_no_data(requester, params): - params_no_data = params | {"dateFrom": "2000-01-01", "dateTo": "2000-01-02"} +def test_no_data(requester, params_location): + params_no_data = params_location | { + "dateFrom": "2000-01-01", + "dateTo": "2000-01-02", + } with pytest.raises(requests.HTTPError, match=r"API Error 127"): requester.getDirectByLocation(params_no_data) -def test_valid_params_one_page(requester, params, params_multiple_pages): - data = requester.getDirectByLocation(params) +def test_valid_params_one_page(requester, params_location, params_multiple_pages): + data = requester.getDirectByLocation(params_location) data_all_pages = requester.getDirectByLocation(params_multiple_pages, allPages=True) assert (