From 4210835dcd7e9bf3f83db3b651d44f027e4917ea Mon Sep 17 00:00:00 2001 From: Paulus Schoutsen Date: Wed, 3 Oct 2018 07:53:54 +0200 Subject: [PATCH] Async response all the things (#17073) * Use async_response * Update device_registry.py --- homeassistant/components/config/auth.py | 74 ++++++++----------- .../components/config/device_registry.py | 40 ++++------ .../components/websocket_api/__init__.py | 1 + .../components/websocket_api/decorators.py | 22 +++--- 4 files changed, 59 insertions(+), 78 deletions(-) diff --git a/homeassistant/components/config/auth.py b/homeassistant/components/config/auth.py index 6da0fe61d96..fb60b4075ef 100644 --- a/homeassistant/components/config/auth.py +++ b/homeassistant/components/config/auth.py @@ -1,9 +1,7 @@ """Offer API to configure Home Assistant auth.""" import voluptuous as vol -from homeassistant.core import callback from homeassistant.components import websocket_api -from homeassistant.components.websocket_api.decorators import require_owner WS_TYPE_LIST = 'config/auth/list' @@ -41,61 +39,49 @@ async def async_setup(hass): return True -@callback -@require_owner -def websocket_list(hass, connection, msg): +@websocket_api.require_owner +@websocket_api.async_response +async def websocket_list(hass, connection, msg): """Return a list of users.""" - async def send_users(): - """Send users.""" - result = [_user_info(u) for u in await hass.auth.async_get_users()] + result = [_user_info(u) for u in await hass.auth.async_get_users()] - connection.send_message( - websocket_api.result_message(msg['id'], result)) - - hass.async_create_task(send_users()) + connection.send_message( + websocket_api.result_message(msg['id'], result)) -@callback -@require_owner -def websocket_delete(hass, connection, msg): +@websocket_api.require_owner +@websocket_api.async_response +async def websocket_delete(hass, connection, msg): """Delete a user.""" - async def delete_user(): - """Delete user.""" - if msg['user_id'] == connection.user.id: - connection.send_message(websocket_api.error_message( - msg['id'], 'no_delete_self', - 'Unable to delete your own account')) - return + if msg['user_id'] == connection.user.id: + connection.send_message(websocket_api.error_message( + msg['id'], 'no_delete_self', + 'Unable to delete your own account')) + return - user = await hass.auth.async_get_user(msg['user_id']) + user = await hass.auth.async_get_user(msg['user_id']) - if not user: - connection.send_message(websocket_api.error_message( - msg['id'], 'not_found', 'User not found')) - return + if not user: + connection.send_message(websocket_api.error_message( + msg['id'], 'not_found', 'User not found')) + return - await hass.auth.async_remove_user(user) + await hass.auth.async_remove_user(user) - connection.send_message( - websocket_api.result_message(msg['id'])) - - hass.async_create_task(delete_user()) + connection.send_message( + websocket_api.result_message(msg['id'])) -@callback -@require_owner -def websocket_create(hass, connection, msg): +@websocket_api.require_owner +@websocket_api.async_response +async def websocket_create(hass, connection, msg): """Create a user.""" - async def create_user(): - """Create a user.""" - user = await hass.auth.async_create_user(msg['name']) + user = await hass.auth.async_create_user(msg['name']) - connection.send_message( - websocket_api.result_message(msg['id'], { - 'user': _user_info(user) - })) - - hass.async_create_task(create_user()) + connection.send_message( + websocket_api.result_message(msg['id'], { + 'user': _user_info(user) + })) def _user_info(user): diff --git a/homeassistant/components/config/device_registry.py b/homeassistant/components/config/device_registry.py index acffd516d21..ecbac703296 100644 --- a/homeassistant/components/config/device_registry.py +++ b/homeassistant/components/config/device_registry.py @@ -1,7 +1,6 @@ """HTTP views to interact with the device registry.""" import voluptuous as vol -from homeassistant.core import callback from homeassistant.helpers.device_registry import async_get_registry from homeassistant.components import websocket_api @@ -22,26 +21,19 @@ async def async_setup(hass): return True -@callback -def websocket_list_devices(hass, connection, msg): - """Handle list devices command. - - Async friendly. - """ - async def retrieve_entities(): - """Get devices from registry.""" - registry = await async_get_registry(hass) - connection.send_message(websocket_api.result_message( - msg['id'], [{ - 'config_entries': list(entry.config_entries), - 'connections': list(entry.connections), - 'manufacturer': entry.manufacturer, - 'model': entry.model, - 'name': entry.name, - 'sw_version': entry.sw_version, - 'id': entry.id, - 'hub_device_id': entry.hub_device_id, - } for entry in registry.devices.values()] - )) - - hass.async_create_task(retrieve_entities()) +@websocket_api.async_response +async def websocket_list_devices(hass, connection, msg): + """Handle list devices command.""" + registry = await async_get_registry(hass) + connection.send_message(websocket_api.result_message( + msg['id'], [{ + 'config_entries': list(entry.config_entries), + 'connections': list(entry.connections), + 'manufacturer': entry.manufacturer, + 'model': entry.model, + 'name': entry.name, + 'sw_version': entry.sw_version, + 'id': entry.id, + 'hub_device_id': entry.hub_device_id, + } for entry in registry.devices.values()] + )) diff --git a/homeassistant/components/websocket_api/__init__.py b/homeassistant/components/websocket_api/__init__.py index 41d0efaf3aa..90c802423ce 100644 --- a/homeassistant/components/websocket_api/__init__.py +++ b/homeassistant/components/websocket_api/__init__.py @@ -20,6 +20,7 @@ BASE_COMMAND_MESSAGE_SCHEMA = messages.BASE_COMMAND_MESSAGE_SCHEMA error_message = messages.error_message result_message = messages.result_message async_response = decorators.async_response +require_owner = decorators.require_owner ws_require_user = decorators.ws_require_user # pylint: enable=invalid-name diff --git a/homeassistant/components/websocket_api/decorators.py b/homeassistant/components/websocket_api/decorators.py index aaa054e4054..5f78790f5db 100644 --- a/homeassistant/components/websocket_api/decorators.py +++ b/homeassistant/components/websocket_api/decorators.py @@ -10,22 +10,24 @@ from . import messages _LOGGER = logging.getLogger(__name__) +async def _handle_async_response(func, hass, connection, msg): + """Create a response and handle exception.""" + try: + await func(hass, connection, msg) + except Exception: # pylint: disable=broad-except + _LOGGER.exception("Unexpected exception") + connection.send_message(messages.error_message( + msg['id'], 'unknown', 'Unexpected error occurred')) + + def async_response(func): """Decorate an async function to handle WebSocket API messages.""" - async def handle_msg_response(hass, connection, msg): - """Create a response and handle exception.""" - try: - await func(hass, connection, msg) - except Exception: # pylint: disable=broad-except - _LOGGER.exception("Unexpected exception") - connection.send_message(messages.error_message( - msg['id'], 'unknown', 'Unexpected error occurred')) - @callback @wraps(func) def schedule_handler(hass, connection, msg): """Schedule the handler.""" - hass.async_create_task(handle_msg_response(hass, connection, msg)) + hass.async_create_task( + _handle_async_response(func, hass, connection, msg)) return schedule_handler