API & Client - remove DarkSky weather provider

This commit is contained in:
Sam 2023-04-11 16:55:18 +02:00
parent ef65689263
commit 642b15d521
6 changed files with 6 additions and 193 deletions

View File

@ -9,7 +9,6 @@ from gpxpy.gpx import GPXTrackPoint
from fittrackee.tests.mixins import CallArgsMixin from fittrackee.tests.mixins import CallArgsMixin
from fittrackee.tests.utils import random_string from fittrackee.tests.utils import random_string
from fittrackee.workouts.utils.weather.dark_sky import DarkSky
from fittrackee.workouts.utils.weather.visual_crossing import VisualCrossing from fittrackee.workouts.utils.weather.visual_crossing import VisualCrossing
from fittrackee.workouts.utils.weather.weather_service import WeatherService from fittrackee.workouts.utils.weather.weather_service import WeatherService
@ -55,82 +54,6 @@ class WeatherTestCase:
return GPXTrackPoint(latitude=48.866667, longitude=2.333333, time=time) return GPXTrackPoint(latitude=48.866667, longitude=2.333333, time=time)
class TestDarksky(WeatherTestCase):
def test_it_calls_forecast_io_with_datetime_in_utc_when_naive_datetime_is_provided( # noqa
self,
) -> None:
naive_point_time = datetime(
year=2022, month=6, day=11, hour=10, minute=23, second=00
)
point = self.get_gpx_point(naive_point_time)
darksky = DarkSky(api_key=self.api_key)
with patch(
'fittrackee.workouts.utils.weather.dark_sky.forecastio'
) as forecast_io_mock:
darksky.get_weather(point)
forecast_io_mock.load_forecast.assert_called_with(
self.api_key,
point.latitude,
point.longitude,
time=datetime(
year=2022,
month=6,
day=11,
hour=10,
minute=23,
second=00,
tzinfo=pytz.utc,
),
units='si',
)
def test_it_calls_forecast_io_with_provided_datetime_when_with_timezone(
self,
) -> None:
paris_point_time = datetime(
year=2022,
month=6,
day=11,
hour=10,
minute=23,
second=00,
).astimezone(pytz.timezone('Europe/Paris'))
point = self.get_gpx_point(paris_point_time)
darksky = DarkSky(api_key=self.api_key)
with patch(
'fittrackee.workouts.utils.weather.dark_sky.forecastio'
) as forecast_io_mock:
darksky.get_weather(point)
forecast_io_mock.load_forecast.assert_called_with(
self.api_key,
point.latitude,
point.longitude,
time=paris_point_time,
units='si',
)
def test_it_returns_forecast_currently_data(self) -> None:
darksky = DarkSky(api_key=self.api_key)
with patch(
'fittrackee.workouts.utils.weather.dark_sky.forecastio'
) as forecast_io_mock:
forecast_io_mock.load_forecast().currently.return_value = sentinel
weather_data = darksky.get_weather(
self.get_gpx_point(datetime.utcnow())
)
assert weather_data == {
'icon': sentinel.icon,
'temperature': sentinel.temperature,
'humidity': sentinel.humidity,
'wind': sentinel.windSpeed,
'windBearing': sentinel.windBearing,
}
class TestVisualCrossingGetTimestamp(WeatherTestCase): class TestVisualCrossingGetTimestamp(WeatherTestCase):
def test_it_returns_expected_timestamp_as_integer(self) -> None: def test_it_returns_expected_timestamp_as_integer(self) -> None:
time = datetime.utcnow() time = datetime.utcnow()
@ -246,9 +169,10 @@ class TestWeatherService(WeatherTestCase):
@pytest.mark.parametrize( @pytest.mark.parametrize(
'input_api_key,input_provider', 'input_api_key,input_provider',
[ [
('', 'darksky'), ('', 'visualcrossing'),
('valid_api_key', ''), ('valid_api_key', ''),
('valid_api_key', 'invalid_provider'), ('valid_api_key', 'invalid_provider'),
('valid_api_key', 'darksky'), # removed provider
], ],
) )
def test_weather_api_is_none_when_configuration_is_invalid( def test_weather_api_is_none_when_configuration_is_invalid(
@ -264,22 +188,6 @@ class TestWeatherService(WeatherTestCase):
assert weather_service.weather_api is None assert weather_service.weather_api is None
@pytest.mark.parametrize(
'input_provider',
['darksky', 'DARKSKY'],
)
def test_weather_api_is_darksky_when_configured(
self,
monkeypatch: pytest.MonkeyPatch,
input_provider: str,
) -> None:
monkeypatch.setenv('WEATHER_API_KEY', 'valid_api_key')
monkeypatch.setenv('WEATHER_API_PROVIDER', input_provider)
weather_service = WeatherService()
assert isinstance(weather_service.weather_api, DarkSky)
@pytest.mark.parametrize( @pytest.mark.parametrize(
'input_provider', 'input_provider',
['visualcrossing', 'VisualCrossing'], ['visualcrossing', 'VisualCrossing'],
@ -307,7 +215,7 @@ class TestWeatherService(WeatherTestCase):
def test_it_returns_none_when_point_time_is_none(self) -> None: def test_it_returns_none_when_point_time_is_none(self) -> None:
weather_service = WeatherService() weather_service = WeatherService()
weather_service.weather_api = DarkSky('api_key') weather_service.weather_api = VisualCrossing('api_key')
point = self.get_gpx_point(None) point = self.get_gpx_point(None)
weather_data = weather_service.get_weather(point) weather_data = weather_service.get_weather(point)

View File

@ -1,37 +0,0 @@
from datetime import datetime
from typing import Dict, Optional
import forecastio
import pytz
from .base_weather import BaseWeather
class DarkSky(BaseWeather):
# Deprecated (API will end on March 31st, 2023)
def _get_data(
self, latitude: float, longitude: float, time: datetime
) -> Optional[Dict]:
# get point time in UTC
point_time = (
pytz.utc.localize(time)
if time.tzinfo is None # naive datetime
else time
)
forecast = forecastio.load_forecast(
self.api_key,
latitude,
longitude,
time=point_time,
units='si',
)
weather = forecast.currently()
return {
'humidity': weather.humidity,
'icon': weather.icon,
'temperature': weather.temperature,
'wind': weather.windSpeed,
'windBearing': weather.windBearing,
}

View File

@ -5,14 +5,12 @@ from gpxpy.gpx import GPXTrackPoint
from fittrackee import appLog from fittrackee import appLog
from .dark_sky import DarkSky
from .visual_crossing import VisualCrossing from .visual_crossing import VisualCrossing
class WeatherService: class WeatherService:
""" """
Available API: Available API:
- DarkSky (deprecated, will end on March 31st, 2023)
- VisualCrossing - VisualCrossing
""" """
@ -20,7 +18,7 @@ class WeatherService:
self.weather_api = self._get_weather_api() self.weather_api = self._get_weather_api()
@staticmethod @staticmethod
def _get_weather_api() -> Union[DarkSky, VisualCrossing, None]: def _get_weather_api() -> Union[VisualCrossing, None]:
weather_api_key: str = os.getenv('WEATHER_API_KEY', '') weather_api_key: str = os.getenv('WEATHER_API_KEY', '')
weather_api_provider: str = os.getenv( weather_api_provider: str = os.getenv(
'WEATHER_API_PROVIDER', '' 'WEATHER_API_PROVIDER', ''
@ -28,8 +26,6 @@ class WeatherService:
if not weather_api_key: if not weather_api_key:
return None return None
if weather_api_provider == 'darksky': # deprecated
return DarkSky(weather_api_key)
if weather_api_provider == 'visualcrossing': if weather_api_provider == 'visualcrossing':
return VisualCrossing(weather_api_key) return VisualCrossing(weather_api_key)
return None return None

View File

@ -75,10 +75,6 @@
function get_weather_provider() { function get_weather_provider() {
const weather_provider: Record<string, string> = {} const weather_provider: Record<string, string> = {}
if (appConfig.value.weather_provider === 'darksky') {
weather_provider['name'] = 'Dark Sky'
weather_provider['url'] = 'https://darksky.net'
}
if (appConfig.value.weather_provider === 'visualcrossing') { if (appConfig.value.weather_provider === 'visualcrossing') {
weather_provider['name'] = 'Visual Crossing' weather_provider['name'] = 'Visual Crossing'
weather_provider['url'] = 'https://www.visualcrossing.com' weather_provider['url'] = 'https://www.visualcrossing.com'

53
poetry.lock generated
View File

@ -1944,21 +1944,6 @@ files = [
[package.dependencies] [package.dependencies]
six = ">=1.5" six = ">=1.5"
[[package]]
name = "python-forecastio"
version = "1.4.0"
description = "A thin Python Wrapper for the Dark Sky (formerly Forecast.io) weather API"
category = "main"
optional = false
python-versions = "*"
files = [
{file = "python-forecastio-1.4.0.tar.gz", hash = "sha256:144419d65e3b46961f38853f959a91f6e6cfa9e6d5b6f47aa9dc5e431471d454"},
]
[package.dependencies]
requests = ">=1.6"
responses = "*"
[[package]] [[package]]
name = "pytz" name = "pytz"
version = "2023.3" version = "2023.3"
@ -1975,7 +1960,7 @@ files = [
name = "pyyaml" name = "pyyaml"
version = "6.0" version = "6.0"
description = "YAML parser and emitter for Python" description = "YAML parser and emitter for Python"
category = "main" category = "dev"
optional = false optional = false
python-versions = ">=3.6" python-versions = ">=3.6"
files = [ files = [
@ -2081,28 +2066,6 @@ urllib3 = ">=1.21.1,<1.27"
socks = ["PySocks (>=1.5.6,!=1.5.7)"] socks = ["PySocks (>=1.5.6,!=1.5.7)"]
use-chardet-on-py3 = ["chardet (>=3.0.2,<6)"] use-chardet-on-py3 = ["chardet (>=3.0.2,<6)"]
[[package]]
name = "responses"
version = "0.23.1"
description = "A utility library for mocking out the `requests` Python library."
category = "main"
optional = false
python-versions = ">=3.7"
files = [
{file = "responses-0.23.1-py3-none-any.whl", hash = "sha256:8a3a5915713483bf353b6f4079ba8b2a29029d1d1090a503c70b0dc5d9d0c7bd"},
{file = "responses-0.23.1.tar.gz", hash = "sha256:c4d9aa9fc888188f0c673eff79a8dadbe2e75b7fe879dc80a221a06e0a68138f"},
]
[package.dependencies]
pyyaml = "*"
requests = ">=2.22.0,<3.0"
types-PyYAML = "*"
typing-extensions = {version = "*", markers = "python_version < \"3.8\""}
urllib3 = ">=1.25.10"
[package.extras]
tests = ["coverage (>=6.0.0)", "flake8", "mypy", "pytest (>=7.0.0)", "pytest-asyncio", "pytest-cov", "pytest-httpserver", "tomli", "tomli-w", "types-requests"]
[[package]] [[package]]
name = "rich" name = "rich"
version = "13.3.3" version = "13.3.3"
@ -2650,18 +2613,6 @@ files = [
{file = "types_pytz-2023.3.0.0-py3-none-any.whl", hash = "sha256:4fc2a7fbbc315f0b6630e0b899fd6c743705abe1094d007b0e612d10da15e0f3"}, {file = "types_pytz-2023.3.0.0-py3-none-any.whl", hash = "sha256:4fc2a7fbbc315f0b6630e0b899fd6c743705abe1094d007b0e612d10da15e0f3"},
] ]
[[package]]
name = "types-pyyaml"
version = "6.0.12.9"
description = "Typing stubs for PyYAML"
category = "main"
optional = false
python-versions = "*"
files = [
{file = "types-PyYAML-6.0.12.9.tar.gz", hash = "sha256:c51b1bd6d99ddf0aa2884a7a328810ebf70a4262c292195d3f4f9a0005f9eeb6"},
{file = "types_PyYAML-6.0.12.9-py3-none-any.whl", hash = "sha256:5aed5aa66bd2d2e158f75dda22b059570ede988559f030cf294871d3b647e3e8"},
]
[[package]] [[package]]
name = "types-redis" name = "types-redis"
version = "4.5.4.1" version = "4.5.4.1"
@ -2886,4 +2837,4 @@ testing = ["big-O", "flake8 (<5)", "jaraco.functools", "jaraco.itertools", "more
[metadata] [metadata]
lock-version = "2.0" lock-version = "2.0"
python-versions = "^3.7" python-versions = "^3.7"
content-hash = "a2bb6c51cd1e0e3cc88e09ec8c598109b2fab9b1cfbdccf73e95496577959710" content-hash = "2a735d57527529962e3b55820d8e236d14399f077247ff208a8507838d1bcbec"

View File

@ -39,7 +39,6 @@ humanize = "^4.6"
psycopg2-binary = "^2.9" psycopg2-binary = "^2.9"
pyjwt = "^2.6" pyjwt = "^2.6"
pyopenssl = "^23.0" pyopenssl = "^23.0"
python-forecastio = "^1.4"
pytz = "^2023.3" pytz = "^2023.3"
shortuuid = "^1.0.11" shortuuid = "^1.0.11"
staticmap = "^0.5.5" staticmap = "^0.5.5"