diff --git a/src/pysofar/sofar.py b/src/pysofar/sofar.py index 2673022..35ef2e7 100644 --- a/src/pysofar/sofar.py +++ b/src/pysofar/sofar.py @@ -574,19 +574,20 @@ def __str__(self): # ---------------------------------- Util Functions -------------------------------------- # -def get_and_update_spotters(_api=None): +def get_and_update_spotters(_api=None, _processes=None): """ :return: A list of the Spotter objects associated with this account """ from itertools import repeat api = _api or SofarApi() + processes = _processes or 16 # grab device id's and query for device data # initialize Spotter objects spot_data = api.devices - pool = ThreadPool(processes=16) + pool = ThreadPool(processes=processes) spotters = pool.starmap(_spot_worker, zip(spot_data, repeat(api))) pool.close() diff --git a/tests/test_sofar_api_class.py b/tests/test_sofar_api_class.py index 8d41070..5ec5d60 100644 --- a/tests/test_sofar_api_class.py +++ b/tests/test_sofar_api_class.py @@ -1,30 +1,37 @@ """ -This file is part of pysofar: A client for interfacing with Sofar Oceans Spotter API +This file is part of pysofar: +A client for interfacing with Sofar Ocean Technologies Spotter API Contents: Tests for device endpoints -Copyright (C) 2019 +Copyright (C) 2019-2023 Sofar Ocean Technologies -Authors: Mike Sosa +Authors: Mike Sosa et al """ +import os +import pytest + from pysofar import wavefleet_exceptions from pysofar.sofar import SofarApi from unittest.mock import patch +# try to read custom token from environment. +# if absent, default to hard-coded value in this source module +custom_token = os.getenv('PYSOFAR_CUSTOM_TOKEN', 'custom_api_token_here') +custom_spotter_id = os.getenv('PYSOFAR_TEST_SPOTTER_ID', 'SPOT-30344R') # The custom token will fail to authenticate so use a mock to bypass the `_sync step` with patch.object(SofarApi, '_sync', return_value=None) as mock_method: - custom_api = SofarApi(custom_token='custom_api_token_here') + custom_token = os.getenv('PYSOFAR_CUSTOM_TOKEN', 'custom_api_token_here') + custom_api = SofarApi(custom_token=custom_token) def test_custom_api(): # test that custom api token is set - assert custom_api.token == 'custom_api_token_here' - + assert custom_api.token == custom_token api = SofarApi() -latest_dat = api.get_latest_data('SPOT-0350', include_wind_data=True) - +latest_dat = api.get_latest_data(custom_spotter_id, include_wind_data=True) def test_get_latest_data(): # test basic that latest_data is able to be queried @@ -41,7 +48,7 @@ def test_get_and_update_spotters(): from pysofar.spotter import Spotter from pysofar.sofar import get_and_update_spotters - sptrs = get_and_update_spotters(_api=api) + sptrs = get_and_update_spotters(_api=api, _processes=2) assert sptrs is not None assert all(map(lambda x: isinstance(x, Spotter), sptrs)) @@ -49,8 +56,8 @@ def test_get_and_update_spotters(): def test_get_all_wave_data(): # Test that all wave data is able to be queried in a time range - st = '2019-05-02' - end = '2019-07-10' + st = '2023-05-02' + end = '2023-05-10' dat = api.get_wave_data(start_date=st, end_date=end) assert dat is not None @@ -61,8 +68,8 @@ def test_get_all_wave_data(): def test_get_all_wind_data(): # Test that all wind data over all time is able to be queried - st = '2021-05-02' - end = '2021-07-10' + st = '2023-05-02' + end = '2023-05-10' dat = api.get_wind_data(start_date=st, end_date=end) assert dat is not None @@ -70,11 +77,10 @@ def test_get_all_wind_data(): assert 'wind' in dat assert len(dat['wind']) > 0 - def test_get_all_tracking_data(): # Test that all tracking data is able to be queried in a time range - st = '2021-05-02' - end = '2021-06-10' + st = '2023-05-02' + end = '2023-05-10' dat = api.get_track_data(start_date=st, end_date=end) assert dat is not None @@ -82,13 +88,13 @@ def test_get_all_tracking_data(): assert 'track' in dat assert len(dat['track']) > 0 - +@pytest.mark.xfail(reason="A Spotter will return no frequency data if it was not in Waves:Spectrum") def test_get_all_frequency_data(): # Test that all frequency data is able to be queried in a time range - st = '2021-06-08' - end = '2021-06-10' + st = '2022-07-26' + end = '2022-08-04' dat = api.get_frequency_data(start_date=st, end_date=end) - + print(dat.keys()) assert dat is not None assert isinstance(dat, dict) assert 'frequency' in dat @@ -96,7 +102,7 @@ def test_get_all_frequency_data(): def test_get_all_data(): - # Test that grabbing data from all spotters from all data types works + # Test that grabbing data from all Spotters from all data types works st = '2019-01-18' end = '2019-01-25' @@ -112,12 +118,13 @@ def test_get_all_data(): def test_get_sensor_data(): # Test that getting sensor data in a time range works - spotter_id = 'SPOT-9999' - st = '2021-07-18' - end = '2021-07-19' + spotter_id = 'SPOT-30081D' + st = '2022-08-01' + end = '2022-08-02' dat = api.get_sensor_data(spotter_id, start_date=st, end_date=end) assert dat is not None + print(dat) assert 'sensorPosition' in dat[-1] diff --git a/tests/test_spotter_class.py b/tests/test_spotter_class.py index 4754c91..92b1d6b 100644 --- a/tests/test_spotter_class.py +++ b/tests/test_spotter_class.py @@ -1,23 +1,26 @@ """ -This file is part of pysofar: A client for interfacing with Sofar Oceans Spotter API +This file is part of pysofar: +A client for interfacing with Sofar Ocean Technologies Spotter API Contents: Tests for device endpoints -Copyright (C) 2019 +Copyright (C) 2019-2023 Sofar Ocean Technologies -Authors: Mike Sosa +Authors: Mike Sosa et al """ +import os +import pytest + from pysofar.sofar import SofarApi from pysofar.spotter import Spotter api = SofarApi() -device = Spotter('SPOT-0350', '') - +device = Spotter(os.getenv('PYSOFAR_TEST_SPOTTER_ID', 'SPOT-30344R'), '', session = api) def test_spotter_update(): - # tests the spotter updates correctly + # tests the Spotter updates correctly device.update() assert device.mode is not None @@ -67,18 +70,17 @@ def test_spotter_edit(): def test_spotter_mode(): - # test the spotter mode property is set correctly + # test the Spotter mode property is set correctly device.mode = 'track' assert device.mode == 'tracking' device.mode = 'full' assert device.mode == 'waves_spectrum' - -def test_spotter_grab_data(): - # test spotter can correctly grab data +@pytest.mark.xfail(reason="will fail if device is not owned by the token making the request") +def test_spotter_grab_data_with_limit(): + # test Spotter can correctly grab data with limit dat = device.grab_data(limit=20) - print(dat) assert 'waves' in dat assert len(dat['waves']) <= 20 diff --git a/tests/test_wave_query_class.py b/tests/test_wave_query_class.py index 930f8a5..4bc9808 100644 --- a/tests/test_wave_query_class.py +++ b/tests/test_wave_query_class.py @@ -3,16 +3,18 @@ Contents: Tests for device endpoints -Copyright (C) 2019 +Copyright (C) 2019-2023 Sofar Ocean Technologies -Authors: Mike Sosa +Authors: Mike Sosa et al """ +import os + from pysofar.sofar import WaveDataQuery -st = '2019-05-02' -end = '2019-05-10' -q = WaveDataQuery('SPOT-0350', limit=100, start_date=st, end_date=end) +st = '2023-05-02' +end = '2023-05-10' +q = WaveDataQuery(os.getenv('PYSOFAR_TEST_SPOTTER_ID', 'SPOT-30344R'), limit=100, start_date=st, end_date=end) q.wind(True) @@ -28,7 +30,7 @@ def test_query_execute(): def test_query_no_dates(): - # resturned latest data first + # returned latest data first q.limit(10) q.clear_start_date() q.clear_end_date() @@ -42,7 +44,7 @@ def test_query_no_dates(): def test_query_no_start(): - # resturned + # returned q.limit(10) q.clear_start_date() @@ -70,18 +72,17 @@ def test_query_no_end(): assert 'waves' in response assert 'wind' in response -# TODO: need to get a viable spotter for testing -# def test_query_surface_temp(): -# q.surface_temp(True) -# q.limit = 10 -# -# q.clear_end_date() -# response = q.execute() -# q.set_start_date(st) -# -# assert response is not None -# assert isinstance(response, dict) -# -# assert 'waves' in response -# assert 'wind' in response -# assert 'surfaceTemp' in response +def test_query_surface_temp(): + q.surface_temp(True) + q.limit = 10 + + q.clear_end_date() + response = q.execute() + q.set_start_date(st) + + assert response is not None + assert isinstance(response, dict) + + assert 'waves' in response + assert 'wind' in response + assert 'surfaceTemp' in response