From 066db11620bfae5848d5120a82212a8a1dd7b252 Mon Sep 17 00:00:00 2001 From: Kevin Stillhammer Date: Mon, 14 Aug 2023 10:02:30 +0200 Subject: [PATCH] Exchange WazeRouteCalculator with pywaze in waze_travel_time (#98169) * exchange WazeRouteCalculator with pywaze * directly use async is_valid_config_entry * store pywaze client as property * fix tests * Remove obsolete error logs * Reuse existing httpx client * Remove redundant typing * Do not clcose common httpx client --- .../waze_travel_time/config_flow.py | 3 +- .../components/waze_travel_time/helpers.py | 16 ++++++--- .../components/waze_travel_time/manifest.json | 4 +-- .../components/waze_travel_time/sensor.py | 33 +++++++++-------- requirements_all.txt | 6 ++-- requirements_test_all.txt | 6 ++-- tests/components/waze_travel_time/conftest.py | 35 +++++++------------ .../waze_travel_time/test_sensor.py | 14 ++++---- 8 files changed, 58 insertions(+), 59 deletions(-) diff --git a/homeassistant/components/waze_travel_time/config_flow.py b/homeassistant/components/waze_travel_time/config_flow.py index a743844659c..60134452025 100644 --- a/homeassistant/components/waze_travel_time/config_flow.py +++ b/homeassistant/components/waze_travel_time/config_flow.py @@ -129,8 +129,7 @@ class ConfigFlow(config_entries.ConfigFlow, domain=DOMAIN): if user_input: user_input[CONF_REGION] = user_input[CONF_REGION].upper() - if await self.hass.async_add_executor_job( - is_valid_config_entry, + if await is_valid_config_entry( self.hass, user_input[CONF_ORIGIN], user_input[CONF_DESTINATION], diff --git a/homeassistant/components/waze_travel_time/helpers.py b/homeassistant/components/waze_travel_time/helpers.py index 8468bb8ea9a..0659424429f 100644 --- a/homeassistant/components/waze_travel_time/helpers.py +++ b/homeassistant/components/waze_travel_time/helpers.py @@ -1,19 +1,25 @@ """Helpers for Waze Travel Time integration.""" import logging -from WazeRouteCalculator import WazeRouteCalculator, WRCError +from pywaze.route_calculator import WazeRouteCalculator, WRCError +from homeassistant.core import HomeAssistant +from homeassistant.helpers.httpx_client import get_async_client from homeassistant.helpers.location import find_coordinates _LOGGER = logging.getLogger(__name__) -def is_valid_config_entry(hass, origin, destination, region): +async def is_valid_config_entry( + hass: HomeAssistant, origin: str, destination: str, region: str +) -> bool: """Return whether the config entry data is valid.""" - origin = find_coordinates(hass, origin) - destination = find_coordinates(hass, destination) + resolved_origin = find_coordinates(hass, origin) + resolved_destination = find_coordinates(hass, destination) + httpx_client = get_async_client(hass) + client = WazeRouteCalculator(region=region, client=httpx_client) try: - WazeRouteCalculator(origin, destination, region).calc_all_routes_info() + await client.calc_all_routes_info(resolved_origin, resolved_destination) except WRCError as error: _LOGGER.error("Error trying to validate entry: %s", error) return False diff --git a/homeassistant/components/waze_travel_time/manifest.json b/homeassistant/components/waze_travel_time/manifest.json index 5e19ee6949c..3f1f8c6d67b 100644 --- a/homeassistant/components/waze_travel_time/manifest.json +++ b/homeassistant/components/waze_travel_time/manifest.json @@ -5,6 +5,6 @@ "config_flow": true, "documentation": "https://www.home-assistant.io/integrations/waze_travel_time", "iot_class": "cloud_polling", - "loggers": ["WazeRouteCalculator", "homeassistant.helpers.location"], - "requirements": ["WazeRouteCalculator==0.14"] + "loggers": ["pywaze", "homeassistant.helpers.location"], + "requirements": ["pywaze==0.3.0"] } diff --git a/homeassistant/components/waze_travel_time/sensor.py b/homeassistant/components/waze_travel_time/sensor.py index 2a620e48937..2b3010a39cb 100644 --- a/homeassistant/components/waze_travel_time/sensor.py +++ b/homeassistant/components/waze_travel_time/sensor.py @@ -5,7 +5,8 @@ from datetime import timedelta import logging from typing import Any -from WazeRouteCalculator import WazeRouteCalculator, WRCError +import httpx +from pywaze.route_calculator import WazeRouteCalculator, WRCError from homeassistant.components.sensor import ( SensorDeviceClass, @@ -23,6 +24,7 @@ from homeassistant.const import ( from homeassistant.core import CoreState, HomeAssistant from homeassistant.helpers.device_registry import DeviceEntryType, DeviceInfo from homeassistant.helpers.entity_platform import AddEntitiesCallback +from homeassistant.helpers.httpx_client import get_async_client from homeassistant.helpers.location import find_coordinates from homeassistant.util.unit_conversion import DistanceConverter @@ -60,6 +62,7 @@ async def async_setup_entry( data = WazeTravelTimeData( region, + get_async_client(hass), config_entry, ) @@ -132,31 +135,33 @@ class WazeTravelTime(SensorEntity): async def first_update(self, _=None) -> None: """Run first update and write state.""" - await self.hass.async_add_executor_job(self.update) + await self.async_update() self.async_write_ha_state() - def update(self) -> None: + async def async_update(self) -> None: """Fetch new state data for the sensor.""" _LOGGER.debug("Fetching Route for %s", self._attr_name) self._waze_data.origin = find_coordinates(self.hass, self._origin) self._waze_data.destination = find_coordinates(self.hass, self._destination) - self._waze_data.update() + await self._waze_data.async_update() class WazeTravelTimeData: """WazeTravelTime Data object.""" - def __init__(self, region: str, config_entry: ConfigEntry) -> None: + def __init__( + self, region: str, client: httpx.AsyncClient, config_entry: ConfigEntry + ) -> None: """Set up WazeRouteCalculator.""" - self.region = region self.config_entry = config_entry + self.client = WazeRouteCalculator(region=region, client=client) self.origin: str | None = None self.destination: str | None = None self.duration = None self.distance = None self.route = None - def update(self): + async def async_update(self): """Update WazeRouteCalculator Sensor.""" _LOGGER.debug( "Getting update for origin: %s destination: %s", @@ -177,17 +182,17 @@ class WazeTravelTimeData: avoid_ferries = self.config_entry.options[CONF_AVOID_FERRIES] units = self.config_entry.options[CONF_UNITS] + routes = {} try: - params = WazeRouteCalculator( + routes = await self.client.calc_all_routes_info( self.origin, self.destination, - self.region, - vehicle_type, - avoid_toll_roads, - avoid_subscription_roads, - avoid_ferries, + vehicle_type=vehicle_type, + avoid_toll_roads=avoid_toll_roads, + avoid_subscription_roads=avoid_subscription_roads, + avoid_ferries=avoid_ferries, + real_time=realtime, ) - routes = params.calc_all_routes_info(real_time=realtime) if incl_filter not in {None, ""}: routes = { diff --git a/requirements_all.txt b/requirements_all.txt index 7e21d0778fa..39ac9a5a19a 100644 --- a/requirements_all.txt +++ b/requirements_all.txt @@ -139,9 +139,6 @@ TwitterAPI==2.7.12 # homeassistant.components.onvif WSDiscovery==2.0.0 -# homeassistant.components.waze_travel_time -WazeRouteCalculator==0.14 - # homeassistant.components.accuweather accuweather==1.0.0 @@ -2226,6 +2223,9 @@ pyvlx==0.2.20 # homeassistant.components.volumio pyvolumio==0.1.5 +# homeassistant.components.waze_travel_time +pywaze==0.3.0 + # homeassistant.components.html5 pywebpush==1.9.2 diff --git a/requirements_test_all.txt b/requirements_test_all.txt index 99cd624b45b..99970f83219 100644 --- a/requirements_test_all.txt +++ b/requirements_test_all.txt @@ -120,9 +120,6 @@ SQLAlchemy==2.0.15 # homeassistant.components.onvif WSDiscovery==2.0.0 -# homeassistant.components.waze_travel_time -WazeRouteCalculator==0.14 - # homeassistant.components.accuweather accuweather==1.0.0 @@ -1634,6 +1631,9 @@ pyvizio==0.1.61 # homeassistant.components.volumio pyvolumio==0.1.5 +# homeassistant.components.waze_travel_time +pywaze==0.3.0 + # homeassistant.components.html5 pywebpush==1.9.2 diff --git a/tests/components/waze_travel_time/conftest.py b/tests/components/waze_travel_time/conftest.py index 65c2616d1dc..64c05a5dcc1 100644 --- a/tests/components/waze_travel_time/conftest.py +++ b/tests/components/waze_travel_time/conftest.py @@ -2,42 +2,31 @@ from unittest.mock import patch import pytest -from WazeRouteCalculator import WRCError - - -@pytest.fixture(name="mock_wrc", autouse=True) -def mock_wrc_fixture(): - """Mock out WazeRouteCalculator.""" - with patch( - "homeassistant.components.waze_travel_time.sensor.WazeRouteCalculator" - ) as mock_wrc: - yield mock_wrc +from pywaze.route_calculator import WRCError @pytest.fixture(name="mock_update") -def mock_update_fixture(mock_wrc): +def mock_update_fixture(): """Mock an update to the sensor.""" - obj = mock_wrc.return_value - obj.calc_all_routes_info.return_value = {"My route": (150, 300)} + with patch( + "pywaze.route_calculator.WazeRouteCalculator.calc_all_routes_info", + return_value={"My route": (150, 300)}, + ) as mock_wrc: + yield mock_wrc @pytest.fixture(name="validate_config_entry") -def validate_config_entry_fixture(): +def validate_config_entry_fixture(mock_update): """Return valid config entry.""" - with patch( - "homeassistant.components.waze_travel_time.helpers.WazeRouteCalculator" - ) as mock_wrc: - obj = mock_wrc.return_value - obj.calc_all_routes_info.return_value = None - yield mock_wrc + mock_update.return_value = None + return mock_update @pytest.fixture(name="invalidate_config_entry") def invalidate_config_entry_fixture(validate_config_entry): """Return invalid config entry.""" - obj = validate_config_entry.return_value - obj.calc_all_routes_info.return_value = {} - obj.calc_all_routes_info.side_effect = WRCError("test") + validate_config_entry.side_effect = WRCError("test") + return validate_config_entry @pytest.fixture(name="bypass_platform_setup") diff --git a/tests/components/waze_travel_time/test_sensor.py b/tests/components/waze_travel_time/test_sensor.py index a3367a48d2a..adcc334889d 100644 --- a/tests/components/waze_travel_time/test_sensor.py +++ b/tests/components/waze_travel_time/test_sensor.py @@ -1,6 +1,6 @@ """Test Waze Travel Time sensors.""" import pytest -from WazeRouteCalculator import WRCError +from pywaze.route_calculator import WRCError from homeassistant.components.waze_travel_time.const import ( CONF_AVOID_FERRIES, @@ -35,17 +35,17 @@ async def mock_config_fixture(hass, data, options): @pytest.fixture(name="mock_update_wrcerror") -def mock_update_wrcerror_fixture(mock_wrc): +def mock_update_wrcerror_fixture(mock_update): """Mock an update to the sensor failed with WRCError.""" - obj = mock_wrc.return_value - obj.calc_all_routes_info.side_effect = WRCError("test") + mock_update.side_effect = WRCError("test") + return mock_update @pytest.fixture(name="mock_update_keyerror") -def mock_update_keyerror_fixture(mock_wrc): +def mock_update_keyerror_fixture(mock_update): """Mock an update to the sensor failed with KeyError.""" - obj = mock_wrc.return_value - obj.calc_all_routes_info.side_effect = KeyError("test") + mock_update.side_effect = KeyError("test") + return mock_update @pytest.mark.parametrize(