2020-10-17 02:56:45 +00:00
|
|
|
"""Support for RESTful API."""
|
2022-10-19 12:35:23 +00:00
|
|
|
from __future__ import annotations
|
|
|
|
|
2020-10-17 02:56:45 +00:00
|
|
|
import logging
|
|
|
|
|
|
|
|
import httpx
|
|
|
|
|
2022-10-19 12:35:23 +00:00
|
|
|
from homeassistant.core import HomeAssistant
|
2021-12-08 22:35:50 +00:00
|
|
|
from homeassistant.helpers import template
|
2020-12-09 16:18:57 +00:00
|
|
|
from homeassistant.helpers.httpx_client import get_async_client
|
|
|
|
|
2020-10-17 02:56:45 +00:00
|
|
|
DEFAULT_TIMEOUT = 10
|
|
|
|
|
|
|
|
_LOGGER = logging.getLogger(__name__)
|
|
|
|
|
|
|
|
|
|
|
|
class RestData:
|
|
|
|
"""Class for handling the data retrieval."""
|
|
|
|
|
|
|
|
def __init__(
|
|
|
|
self,
|
2022-10-19 12:35:23 +00:00
|
|
|
hass: HomeAssistant,
|
|
|
|
method: str,
|
|
|
|
resource: str,
|
|
|
|
auth: httpx.DigestAuth | tuple[str, str] | None,
|
|
|
|
headers: dict[str, str] | None,
|
|
|
|
params: dict[str, str] | None,
|
|
|
|
data: str | None,
|
|
|
|
verify_ssl: bool,
|
|
|
|
timeout: int = DEFAULT_TIMEOUT,
|
|
|
|
) -> None:
|
2020-10-17 02:56:45 +00:00
|
|
|
"""Initialize the data object."""
|
2020-12-09 16:18:57 +00:00
|
|
|
self._hass = hass
|
2020-10-17 02:56:45 +00:00
|
|
|
self._method = method
|
|
|
|
self._resource = resource
|
|
|
|
self._auth = auth
|
|
|
|
self._headers = headers
|
2020-11-11 19:03:55 +00:00
|
|
|
self._params = params
|
2020-10-17 02:56:45 +00:00
|
|
|
self._request_data = data
|
|
|
|
self._timeout = timeout
|
|
|
|
self._verify_ssl = verify_ssl
|
2022-10-19 12:35:23 +00:00
|
|
|
self._async_client: httpx.AsyncClient | None = None
|
|
|
|
self.data: str | None = None
|
|
|
|
self.last_exception: Exception | None = None
|
|
|
|
self.headers: httpx.Headers | None = None
|
2020-10-17 02:56:45 +00:00
|
|
|
|
2022-10-19 12:35:23 +00:00
|
|
|
def set_url(self, url: str) -> None:
|
2020-10-17 02:56:45 +00:00
|
|
|
"""Set url."""
|
|
|
|
self._resource = url
|
|
|
|
|
2022-10-19 12:35:23 +00:00
|
|
|
async def async_update(self, log_errors: bool = True) -> None:
|
2020-10-17 02:56:45 +00:00
|
|
|
"""Get the latest data from REST service with provided method."""
|
|
|
|
if not self._async_client:
|
2020-12-09 16:18:57 +00:00
|
|
|
self._async_client = get_async_client(
|
|
|
|
self._hass, verify_ssl=self._verify_ssl
|
|
|
|
)
|
2020-10-17 02:56:45 +00:00
|
|
|
|
2021-12-08 22:35:50 +00:00
|
|
|
rendered_headers = template.render_complex(self._headers, parse_result=False)
|
|
|
|
rendered_params = template.render_complex(self._params)
|
2021-10-29 21:36:47 +00:00
|
|
|
|
2020-10-17 02:56:45 +00:00
|
|
|
_LOGGER.debug("Updating from %s", self._resource)
|
|
|
|
try:
|
|
|
|
response = await self._async_client.request(
|
|
|
|
self._method,
|
|
|
|
self._resource,
|
2021-10-29 21:36:47 +00:00
|
|
|
headers=rendered_headers,
|
|
|
|
params=rendered_params,
|
2020-10-17 02:56:45 +00:00
|
|
|
auth=self._auth,
|
2022-10-18 15:15:08 +00:00
|
|
|
content=self._request_data,
|
2020-10-17 02:56:45 +00:00
|
|
|
timeout=self._timeout,
|
2021-12-08 21:03:07 +00:00
|
|
|
follow_redirects=True,
|
2020-10-17 02:56:45 +00:00
|
|
|
)
|
|
|
|
self.data = response.text
|
|
|
|
self.headers = response.headers
|
2022-09-18 19:38:27 +00:00
|
|
|
except httpx.TimeoutException as ex:
|
|
|
|
if log_errors:
|
|
|
|
_LOGGER.error("Timeout while fetching data: %s", self._resource)
|
|
|
|
self.last_exception = ex
|
|
|
|
self.data = None
|
|
|
|
self.headers = None
|
2020-10-17 02:56:45 +00:00
|
|
|
except httpx.RequestError as ex:
|
2021-04-05 03:26:18 +00:00
|
|
|
if log_errors:
|
|
|
|
_LOGGER.error(
|
|
|
|
"Error fetching data: %s failed with %s", self._resource, ex
|
|
|
|
)
|
|
|
|
self.last_exception = ex
|
2020-10-17 02:56:45 +00:00
|
|
|
self.data = None
|
|
|
|
self.headers = None
|