"""Init file for Supervisor network RESTful API.""" import voluptuous as vol from ..const import ( ATTR_ADDON, ATTR_CONFIG, ATTR_DISCOVERY, ATTR_SERVICE, ATTR_SERVICES, ATTR_UUID, REQUEST_FROM, ) from ..coresys import CoreSysAttributes from ..discovery.validate import valid_discovery_service from ..exceptions import APIError, APIForbidden from .utils import api_process, api_validate, require_home_assistant SCHEMA_DISCOVERY = vol.Schema( { vol.Required(ATTR_SERVICE): valid_discovery_service, vol.Optional(ATTR_CONFIG): vol.Maybe(dict), } ) class APIDiscovery(CoreSysAttributes): """Handle RESTful API for discovery functions.""" def _extract_message(self, request): """Extract discovery message from URL.""" message = self.sys_discovery.get(request.match_info.get("uuid")) if not message: raise APIError("Discovery message not found") return message @api_process @require_home_assistant async def list(self, request): """Show register services.""" # Get available discovery discovery = [] for message in self.sys_discovery.list_messages: discovery.append( { ATTR_ADDON: message.addon, ATTR_SERVICE: message.service, ATTR_UUID: message.uuid, ATTR_CONFIG: message.config, } ) # Get available services/add-ons services = {} for addon in self.sys_addons.all: for name in addon.discovery: services.setdefault(name, []).append(addon.slug) return {ATTR_DISCOVERY: discovery, ATTR_SERVICES: services} @api_process async def set_discovery(self, request): """Write data into a discovery pipeline.""" body = await api_validate(SCHEMA_DISCOVERY, request) addon = request[REQUEST_FROM] # Access? if body[ATTR_SERVICE] not in addon.discovery: raise APIForbidden("Can't use discovery!") # Process discovery message message = self.sys_discovery.send(addon, **body) return {ATTR_UUID: message.uuid} @api_process @require_home_assistant async def get_discovery(self, request): """Read data into a discovery message.""" message = self._extract_message(request) return { ATTR_ADDON: message.addon, ATTR_SERVICE: message.service, ATTR_UUID: message.uuid, ATTR_CONFIG: message.config, } @api_process async def del_discovery(self, request): """Delete data into a discovery message.""" message = self._extract_message(request) addon = request[REQUEST_FROM] # Permission if message.addon != addon.slug: raise APIForbidden("Can't remove discovery message") self.sys_discovery.remove(message) return True