Skip to content

Commit

Permalink
Add rest to strict-typing (home-assistant#86149)
Browse files Browse the repository at this point in the history
* Add type hints to rest notify

* Add rest to strict-typing
  • Loading branch information
epenet authored Feb 7, 2023
1 parent 59ca778 commit b854dd9
Show file tree
Hide file tree
Showing 6 changed files with 74 additions and 64 deletions.
1 change: 1 addition & 0 deletions .strict-typing
Original file line number Diff line number Diff line change
Expand Up @@ -247,6 +247,7 @@ homeassistant.components.recorder.*
homeassistant.components.remote.*
homeassistant.components.renault.*
homeassistant.components.repairs.*
homeassistant.components.rest.*
homeassistant.components.rfxtrx.*
homeassistant.components.rhasspy.*
homeassistant.components.ridwell.*
Expand Down
10 changes: 7 additions & 3 deletions homeassistant/components/rest/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
import contextlib
from datetime import timedelta
import logging
from typing import Any
from typing import Any, cast

import httpx
import voluptuous as vol
Expand Down Expand Up @@ -149,8 +149,12 @@ def _rest_coordinator(
"""Wrap a DataUpdateCoordinator around the rest object."""
if resource_template:

async def _async_refresh_with_resource_template():
rest.set_url(resource_template.async_render(parse_result=False))
async def _async_refresh_with_resource_template() -> None:
rest.set_url(
cast(template.Template, resource_template).async_render(
parse_result=False
)
)
await rest.async_update()

update_method = _async_refresh_with_resource_template
Expand Down
22 changes: 13 additions & 9 deletions homeassistant/components/rest/binary_sensor.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,11 +20,14 @@
from homeassistant.exceptions import PlatformNotReady
import homeassistant.helpers.config_validation as cv
from homeassistant.helpers.entity_platform import AddEntitiesCallback
from homeassistant.helpers.template import Template
from homeassistant.helpers.template_entity import TemplateEntity
from homeassistant.helpers.typing import ConfigType, DiscoveryInfoType
from homeassistant.helpers.update_coordinator import DataUpdateCoordinator

from . import async_get_config_and_coordinator, create_rest_data_from_config
from .const import DEFAULT_BINARY_SENSOR_NAME
from .data import RestData
from .entity import RestEntity
from .schema import BINARY_SENSOR_SCHEMA, RESOURCE_SCHEMA

Expand Down Expand Up @@ -79,19 +82,19 @@ class RestBinarySensor(RestEntity, TemplateEntity, BinarySensorEntity):

def __init__(
self,
hass,
coordinator,
rest,
config,
unique_id,
):
hass: HomeAssistant,
coordinator: DataUpdateCoordinator[None] | None,
rest: RestData,
config: ConfigType,
unique_id: str | None,
) -> None:
"""Initialize a REST binary sensor."""
RestEntity.__init__(
self,
coordinator,
rest,
config.get(CONF_RESOURCE_TEMPLATE),
config.get(CONF_FORCE_UPDATE),
config[CONF_FORCE_UPDATE],
)
TemplateEntity.__init__(
self,
Expand All @@ -101,16 +104,17 @@ def __init__(
unique_id=unique_id,
)
self._previous_data = None
self._value_template = config.get(CONF_VALUE_TEMPLATE)
self._value_template: Template | None = config.get(CONF_VALUE_TEMPLATE)
if (value_template := self._value_template) is not None:
value_template.hass = hass

self._attr_device_class = config.get(CONF_DEVICE_CLASS)

def _update_from_rest_data(self):
def _update_from_rest_data(self) -> None:
"""Update state from the rest data."""
if self.rest.data is None:
self._attr_is_on = False
return

response = self.rest.data

Expand Down
55 changes: 28 additions & 27 deletions homeassistant/components/rest/notify.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@

from http import HTTPStatus
import logging
from typing import Any

import requests
from requests.auth import AuthBase, HTTPBasicAuth, HTTPDigestAuth
Expand Down Expand Up @@ -77,18 +78,18 @@ def get_service(
discovery_info: DiscoveryInfoType | None = None,
) -> RestNotificationService:
"""Get the RESTful notification service."""
resource = config.get(CONF_RESOURCE)
method = config.get(CONF_METHOD)
headers = config.get(CONF_HEADERS)
params = config.get(CONF_PARAMS)
message_param_name = config.get(CONF_MESSAGE_PARAMETER_NAME)
title_param_name = config.get(CONF_TITLE_PARAMETER_NAME)
target_param_name = config.get(CONF_TARGET_PARAMETER_NAME)
data = config.get(CONF_DATA)
data_template = config.get(CONF_DATA_TEMPLATE)
username = config.get(CONF_USERNAME)
password = config.get(CONF_PASSWORD)
verify_ssl = config.get(CONF_VERIFY_SSL)
resource: str = config[CONF_RESOURCE]
method: str = config[CONF_METHOD]
headers: dict[str, str] | None = config.get(CONF_HEADERS)
params: dict[str, str] | None = config.get(CONF_PARAMS)
message_param_name: str = config[CONF_MESSAGE_PARAMETER_NAME]
title_param_name: str | None = config.get(CONF_TITLE_PARAMETER_NAME)
target_param_name: str | None = config.get(CONF_TARGET_PARAMETER_NAME)
data: dict[str, Any] | None = config.get(CONF_DATA)
data_template: dict[str, Any] | None = config.get(CONF_DATA_TEMPLATE)
username: str | None = config.get(CONF_USERNAME)
password: str | None = config.get(CONF_PASSWORD)
verify_ssl: bool = config[CONF_VERIFY_SSL]

auth: AuthBase | None = None
if username and password:
Expand Down Expand Up @@ -118,19 +119,19 @@ class RestNotificationService(BaseNotificationService):

def __init__(
self,
hass,
resource,
method,
headers,
params,
message_param_name,
title_param_name,
target_param_name,
data,
data_template,
auth,
verify_ssl,
):
hass: HomeAssistant,
resource: str,
method: str,
headers: dict[str, str] | None,
params: dict[str, str] | None,
message_param_name: str,
title_param_name: str | None,
target_param_name: str | None,
data: dict[str, Any] | None,
data_template: dict[str, Any] | None,
auth: AuthBase | None,
verify_ssl: bool,
) -> None:
"""Initialize the service."""
self._resource = resource
self._hass = hass
Expand All @@ -145,7 +146,7 @@ def __init__(
self._auth = auth
self._verify_ssl = verify_ssl

def send_message(self, message="", **kwargs):
def send_message(self, message: str = "", **kwargs: Any) -> None:
"""Send a message to a user."""
data = {self._message_param_name: message}

Expand All @@ -160,7 +161,7 @@ def send_message(self, message="", **kwargs):
if self._data_template or self._data:
kwargs[ATTR_MESSAGE] = message

def _data_template_creator(value):
def _data_template_creator(value: Any) -> Any:
"""Recursive template creator helper function."""
if isinstance(value, list):
return [_data_template_creator(item) for item in value]
Expand Down
40 changes: 15 additions & 25 deletions homeassistant/components/rest/sensor.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,9 +28,11 @@
from homeassistant.helpers.json import json_dumps, json_loads
from homeassistant.helpers.template_entity import TemplateSensor
from homeassistant.helpers.typing import ConfigType, DiscoveryInfoType
from homeassistant.helpers.update_coordinator import DataUpdateCoordinator

from . import async_get_config_and_coordinator, create_rest_data_from_config
from .const import CONF_JSON_ATTRS, CONF_JSON_ATTRS_PATH, DEFAULT_SENSOR_NAME
from .data import RestData
from .entity import RestEntity
from .schema import RESOURCE_SCHEMA, SENSOR_SCHEMA

Expand Down Expand Up @@ -67,7 +69,7 @@ async def async_setup_platform(
raise PlatformNotReady from rest.last_exception
raise PlatformNotReady

unique_id = conf.get(CONF_UNIQUE_ID)
unique_id: str | None = conf.get(CONF_UNIQUE_ID)

async_add_entities(
[
Expand All @@ -87,19 +89,19 @@ class RestSensor(RestEntity, TemplateSensor):

def __init__(
self,
hass,
coordinator,
rest,
config,
unique_id,
):
hass: HomeAssistant,
coordinator: DataUpdateCoordinator[None] | None,
rest: RestData,
config: ConfigType,
unique_id: str | None,
) -> None:
"""Initialize the REST sensor."""
RestEntity.__init__(
self,
coordinator,
rest,
config.get(CONF_RESOURCE_TEMPLATE),
config.get(CONF_FORCE_UPDATE),
config[CONF_FORCE_UPDATE],
)
TemplateSensor.__init__(
self,
Expand All @@ -108,25 +110,13 @@ def __init__(
fallback_name=DEFAULT_SENSOR_NAME,
unique_id=unique_id,
)
self._state = None
self._value_template = config.get(CONF_VALUE_TEMPLATE)
if (value_template := self._value_template) is not None:
value_template.hass = hass
self._json_attrs = config.get(CONF_JSON_ATTRS)
self._attributes = None
self._json_attrs_path = config.get(CONF_JSON_ATTRS_PATH)

@property
def native_value(self):
"""Return the state of the device."""
return self._state

@property
def extra_state_attributes(self):
"""Return the state attributes."""
return self._attributes

def _update_from_rest_data(self):
def _update_from_rest_data(self) -> None:
"""Update state from the rest data."""
value = self.rest.data
_LOGGER.debug("Data fetched from resource: %s", value)
Expand All @@ -150,7 +140,7 @@ def _update_from_rest_data(self):
_LOGGER.debug("Erroneous XML: %s", value)

if self._json_attrs:
self._attributes = {}
self._attr_extra_state_attributes = {}
if value:
try:
json_dict = json_loads(value)
Expand All @@ -165,7 +155,7 @@ def _update_from_rest_data(self):
attrs = {
k: json_dict[k] for k in self._json_attrs if k in json_dict
}
self._attributes = attrs
self._attr_extra_state_attributes = attrs
else:
_LOGGER.warning(
"JSON result was not a dictionary"
Expand All @@ -187,9 +177,9 @@ def _update_from_rest_data(self):
SensorDeviceClass.DATE,
SensorDeviceClass.TIMESTAMP,
):
self._state = value
self._attr_native_value = value
return

self._state = async_parse_date_datetime(
self._attr_native_value = async_parse_date_datetime(
value, self.entity_id, self.device_class
)
10 changes: 10 additions & 0 deletions mypy.ini
Original file line number Diff line number Diff line change
Expand Up @@ -2225,6 +2225,16 @@ disallow_untyped_defs = true
warn_return_any = true
warn_unreachable = true

[mypy-homeassistant.components.rest.*]
check_untyped_defs = true
disallow_incomplete_defs = true
disallow_subclassing_any = true
disallow_untyped_calls = true
disallow_untyped_decorators = true
disallow_untyped_defs = true
warn_return_any = true
warn_unreachable = true

[mypy-homeassistant.components.rfxtrx.*]
check_untyped_defs = true
disallow_incomplete_defs = true
Expand Down

0 comments on commit b854dd9

Please sign in to comment.