Async response all the things (#17073)

* Use async_response

* Update device_registry.py
pull/17129/head
Paulus Schoutsen 2018-10-03 07:53:54 +02:00 committed by Pascal Vizeli
parent 15a160a630
commit 4210835dcd
4 changed files with 59 additions and 78 deletions

View File

@ -1,9 +1,7 @@
"""Offer API to configure Home Assistant auth.""" """Offer API to configure Home Assistant auth."""
import voluptuous as vol import voluptuous as vol
from homeassistant.core import callback
from homeassistant.components import websocket_api from homeassistant.components import websocket_api
from homeassistant.components.websocket_api.decorators import require_owner
WS_TYPE_LIST = 'config/auth/list' WS_TYPE_LIST = 'config/auth/list'
@ -41,61 +39,49 @@ async def async_setup(hass):
return True return True
@callback @websocket_api.require_owner
@require_owner @websocket_api.async_response
def websocket_list(hass, connection, msg): async def websocket_list(hass, connection, msg):
"""Return a list of users.""" """Return a list of users."""
async def send_users(): result = [_user_info(u) for u in await hass.auth.async_get_users()]
"""Send users."""
result = [_user_info(u) for u in await hass.auth.async_get_users()]
connection.send_message( connection.send_message(
websocket_api.result_message(msg['id'], result)) websocket_api.result_message(msg['id'], result))
hass.async_create_task(send_users())
@callback @websocket_api.require_owner
@require_owner @websocket_api.async_response
def websocket_delete(hass, connection, msg): async def websocket_delete(hass, connection, msg):
"""Delete a user.""" """Delete a user."""
async def delete_user(): if msg['user_id'] == connection.user.id:
"""Delete user.""" connection.send_message(websocket_api.error_message(
if msg['user_id'] == connection.user.id: msg['id'], 'no_delete_self',
connection.send_message(websocket_api.error_message( 'Unable to delete your own account'))
msg['id'], 'no_delete_self', return
'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: if not user:
connection.send_message(websocket_api.error_message( connection.send_message(websocket_api.error_message(
msg['id'], 'not_found', 'User not found')) msg['id'], 'not_found', 'User not found'))
return return
await hass.auth.async_remove_user(user) await hass.auth.async_remove_user(user)
connection.send_message( connection.send_message(
websocket_api.result_message(msg['id'])) websocket_api.result_message(msg['id']))
hass.async_create_task(delete_user())
@callback @websocket_api.require_owner
@require_owner @websocket_api.async_response
def websocket_create(hass, connection, msg): async def websocket_create(hass, connection, msg):
"""Create a user.""" """Create a user."""
async def create_user(): user = await hass.auth.async_create_user(msg['name'])
"""Create a user."""
user = await hass.auth.async_create_user(msg['name'])
connection.send_message( connection.send_message(
websocket_api.result_message(msg['id'], { websocket_api.result_message(msg['id'], {
'user': _user_info(user) 'user': _user_info(user)
})) }))
hass.async_create_task(create_user())
def _user_info(user): def _user_info(user):

View File

@ -1,7 +1,6 @@
"""HTTP views to interact with the device registry.""" """HTTP views to interact with the device registry."""
import voluptuous as vol import voluptuous as vol
from homeassistant.core import callback
from homeassistant.helpers.device_registry import async_get_registry from homeassistant.helpers.device_registry import async_get_registry
from homeassistant.components import websocket_api from homeassistant.components import websocket_api
@ -22,26 +21,19 @@ async def async_setup(hass):
return True return True
@callback @websocket_api.async_response
def websocket_list_devices(hass, connection, msg): async def websocket_list_devices(hass, connection, msg):
"""Handle list devices command. """Handle list devices command."""
registry = await async_get_registry(hass)
Async friendly. connection.send_message(websocket_api.result_message(
""" msg['id'], [{
async def retrieve_entities(): 'config_entries': list(entry.config_entries),
"""Get devices from registry.""" 'connections': list(entry.connections),
registry = await async_get_registry(hass) 'manufacturer': entry.manufacturer,
connection.send_message(websocket_api.result_message( 'model': entry.model,
msg['id'], [{ 'name': entry.name,
'config_entries': list(entry.config_entries), 'sw_version': entry.sw_version,
'connections': list(entry.connections), 'id': entry.id,
'manufacturer': entry.manufacturer, 'hub_device_id': entry.hub_device_id,
'model': entry.model, } for entry in registry.devices.values()]
'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())

View File

@ -20,6 +20,7 @@ BASE_COMMAND_MESSAGE_SCHEMA = messages.BASE_COMMAND_MESSAGE_SCHEMA
error_message = messages.error_message error_message = messages.error_message
result_message = messages.result_message result_message = messages.result_message
async_response = decorators.async_response async_response = decorators.async_response
require_owner = decorators.require_owner
ws_require_user = decorators.ws_require_user ws_require_user = decorators.ws_require_user
# pylint: enable=invalid-name # pylint: enable=invalid-name

View File

@ -10,22 +10,24 @@ from . import messages
_LOGGER = logging.getLogger(__name__) _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): def async_response(func):
"""Decorate an async function to handle WebSocket API messages.""" """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 @callback
@wraps(func) @wraps(func)
def schedule_handler(hass, connection, msg): def schedule_handler(hass, connection, msg):
"""Schedule the handler.""" """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 return schedule_handler