From 441c55936d895a31cd1d28697e0973fd21183090 Mon Sep 17 00:00:00 2001 From: Mikhail Epifanov Date: Tue, 26 Mar 2024 22:46:04 +0100 Subject: [PATCH] use normal async client for api calls --- cookbook/connectors/homeassistant.py | 62 ++++++++++++++++------------ requirements.txt | 2 +- 2 files changed, 37 insertions(+), 27 deletions(-) diff --git a/cookbook/connectors/homeassistant.py b/cookbook/connectors/homeassistant.py index e653c3f3d..bdd52c8b1 100644 --- a/cookbook/connectors/homeassistant.py +++ b/cookbook/connectors/homeassistant.py @@ -1,26 +1,33 @@ import logging from logging import Logger +from typing import Dict +from urllib.parse import urljoin -from homeassistant_api import Client, HomeassistantAPIError, Domain +from aiohttp import ClientError, request from cookbook.connectors.connector import Connector from cookbook.models import ShoppingListEntry, ConnectorConfig, Space class HomeAssistant(Connector): - _domains_cache: dict[str, Domain] _config: ConnectorConfig _logger: Logger - _client: Client def __init__(self, config: ConnectorConfig): if not config.token or not config.url or not config.todo_entity: raise ValueError("config for HomeAssistantConnector in incomplete") - self._domains_cache = dict() self._config = config self._logger = logging.getLogger("connector.HomeAssistant") - self._client = Client(self._config.url, self._config.token, async_cache_session=False, use_async=True) + + async def send_api_call(self, method: str, path: str, data: Dict) -> str: + headers = { + "Authorization": f"Bearer {self._config.token}", + "Content-Type": "application/json" + } + async with request(method, urljoin(self._config.url, path), headers=headers, json=data) as response: + response.raise_for_status() + return await response.json() async def on_shopping_list_entry_created(self, space: Space, shopping_list_entry: ShoppingListEntry) -> None: if not self._config.on_shopping_list_entry_created_enabled: @@ -28,15 +35,17 @@ class HomeAssistant(Connector): item, description = _format_shopping_list_entry(shopping_list_entry) - todo_domain = self._domains_cache.get('todo') - try: - if todo_domain is None: - todo_domain = await self._client.async_get_domain('todo') - self._domains_cache['todo'] = todo_domain + logging.debug(f"adding {item=} to {self._config.name}") - logging.debug(f"pushing {item} to {self._config.name}") - await todo_domain.add_item(entity_id=self._config.todo_entity, item=item) - except HomeassistantAPIError as err: + data = { + "entity_id": self._config.todo_entity, + "item": item, + "description": description, + } + + try: + await self.send_api_call("POST", "services/todo/add_item", data) + except ClientError as err: self._logger.warning(f"[HomeAssistant {self._config.name}] Received an exception from the api: {err=}, {type(err)=}") async def on_shopping_list_entry_updated(self, space: Space, shopping_list_entry: ShoppingListEntry) -> None: @@ -48,21 +57,22 @@ class HomeAssistant(Connector): if not self._config.on_shopping_list_entry_deleted_enabled: return - item, description = _format_shopping_list_entry(shopping_list_entry) + item, _ = _format_shopping_list_entry(shopping_list_entry) + + logging.debug(f"removing {item=} from {self._config.name}") + + data = { + "entity_id": self._config.todo_entity, + "item": item, + } - todo_domain = self._domains_cache.get('todo') try: - if todo_domain is None: - todo_domain = await self._client.async_get_domain('todo') - self._domains_cache['todo'] = todo_domain - - logging.debug(f"deleting {item} from {self._config.name}") - await todo_domain.remove_item(entity_id=self._config.todo_entity, item=item) - except HomeassistantAPIError as err: + await self.send_api_call("POST", "services/todo/remove_item", data) + except ClientError as err: self._logger.warning(f"[HomeAssistant {self._config.name}] Received an exception from the api: {err=}, {type(err)=}") async def close(self) -> None: - await self._client.async_cache_session.close() + pass def _format_shopping_list_entry(shopping_list_entry: ShoppingListEntry): @@ -76,10 +86,10 @@ def _format_shopping_list_entry(shopping_list_entry: ShoppingListEntry): else: item += ")" - description = "Imported by TandoorRecipes" + description = "From TandoorRecipes" if shopping_list_entry.created_by.first_name and len(shopping_list_entry.created_by.first_name) > 0: - description += f", created by {shopping_list_entry.created_by.first_name}" + description += f", by {shopping_list_entry.created_by.first_name}" else: - description += f", created by {shopping_list_entry.created_by.username}" + description += f", by {shopping_list_entry.created_by.username}" return item, description diff --git a/requirements.txt b/requirements.txt index 1c4962076..3ef2dd2b6 100644 --- a/requirements.txt +++ b/requirements.txt @@ -43,7 +43,7 @@ django-auth-ldap==4.6.0 pyppeteer==2.0.0 validators==0.20.0 pytube==15.0.0 -homeassistant-api==4.1.1.post2 +aiohttp==3.9.3 # Development pytest==8.0.0