use normal async client for api calls

This commit is contained in:
Mikhail Epifanov
2024-03-26 22:46:04 +01:00
parent b67281bbc8
commit 441c55936d
2 changed files with 37 additions and 27 deletions

View File

@@ -1,26 +1,33 @@
import logging import logging
from logging import Logger 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.connectors.connector import Connector
from cookbook.models import ShoppingListEntry, ConnectorConfig, Space from cookbook.models import ShoppingListEntry, ConnectorConfig, Space
class HomeAssistant(Connector): class HomeAssistant(Connector):
_domains_cache: dict[str, Domain]
_config: ConnectorConfig _config: ConnectorConfig
_logger: Logger _logger: Logger
_client: Client
def __init__(self, config: ConnectorConfig): def __init__(self, config: ConnectorConfig):
if not config.token or not config.url or not config.todo_entity: if not config.token or not config.url or not config.todo_entity:
raise ValueError("config for HomeAssistantConnector in incomplete") raise ValueError("config for HomeAssistantConnector in incomplete")
self._domains_cache = dict()
self._config = config self._config = config
self._logger = logging.getLogger("connector.HomeAssistant") 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: 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: 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) item, description = _format_shopping_list_entry(shopping_list_entry)
todo_domain = self._domains_cache.get('todo') logging.debug(f"adding {item=} to {self._config.name}")
try:
if todo_domain is None:
todo_domain = await self._client.async_get_domain('todo')
self._domains_cache['todo'] = todo_domain
logging.debug(f"pushing {item} to {self._config.name}") data = {
await todo_domain.add_item(entity_id=self._config.todo_entity, item=item) "entity_id": self._config.todo_entity,
except HomeassistantAPIError as err: "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)=}") 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: 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: if not self._config.on_shopping_list_entry_deleted_enabled:
return 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: try:
if todo_domain is None: await self.send_api_call("POST", "services/todo/remove_item", data)
todo_domain = await self._client.async_get_domain('todo') except ClientError as err:
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:
self._logger.warning(f"[HomeAssistant {self._config.name}] Received an exception from the api: {err=}, {type(err)=}") self._logger.warning(f"[HomeAssistant {self._config.name}] Received an exception from the api: {err=}, {type(err)=}")
async def close(self) -> None: async def close(self) -> None:
await self._client.async_cache_session.close() pass
def _format_shopping_list_entry(shopping_list_entry: ShoppingListEntry): def _format_shopping_list_entry(shopping_list_entry: ShoppingListEntry):
@@ -76,10 +86,10 @@ def _format_shopping_list_entry(shopping_list_entry: ShoppingListEntry):
else: else:
item += ")" 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: 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: else:
description += f", created by {shopping_list_entry.created_by.username}" description += f", by {shopping_list_entry.created_by.username}"
return item, description return item, description

View File

@@ -43,7 +43,7 @@ django-auth-ldap==4.6.0
pyppeteer==2.0.0 pyppeteer==2.0.0
validators==0.20.0 validators==0.20.0
pytube==15.0.0 pytube==15.0.0
homeassistant-api==4.1.1.post2 aiohttp==3.9.3
# Development # Development
pytest==8.0.0 pytest==8.0.0