core/homeassistant/helpers/data_entry_flow.py

124 lines
4.1 KiB
Python
Raw Normal View History

"""Helpers for the data entry flow."""
from typing import Any, Dict
from aiohttp import web
import voluptuous as vol
from homeassistant import config_entries, data_entry_flow
from homeassistant.components.http import HomeAssistantView
from homeassistant.components.http.data_validator import RequestDataValidator
2020-04-08 22:57:47 +00:00
from homeassistant.const import HTTP_NOT_FOUND
2020-02-15 23:36:57 +00:00
import homeassistant.helpers.config_validation as cv
2019-07-31 19:25:30 +00:00
class _BaseFlowManagerView(HomeAssistantView):
"""Foundation for flow manager views."""
def __init__(self, flow_mgr: data_entry_flow.FlowManager) -> None:
"""Initialize the flow manager index view."""
self._flow_mgr = flow_mgr
# pylint: disable=no-self-use
def _prepare_result_json(self, result: Dict[str, Any]) -> Dict[str, Any]:
"""Convert result to JSON."""
2019-07-31 19:25:30 +00:00
if result["type"] == data_entry_flow.RESULT_TYPE_CREATE_ENTRY:
data = result.copy()
2019-07-31 19:25:30 +00:00
data.pop("result")
data.pop("data")
return data
2019-07-31 19:25:30 +00:00
if result["type"] != data_entry_flow.RESULT_TYPE_FORM:
return result
import voluptuous_serialize # pylint: disable=import-outside-toplevel
data = result.copy()
2019-07-31 19:25:30 +00:00
schema = data["data_schema"]
if schema is None:
2019-07-31 19:25:30 +00:00
data["data_schema"] = []
else:
2020-02-15 23:36:57 +00:00
data["data_schema"] = voluptuous_serialize.convert(
schema, custom_serializer=cv.custom_serializer
)
return data
class FlowManagerIndexView(_BaseFlowManagerView):
"""View to create config flows."""
2019-07-31 19:25:30 +00:00
@RequestDataValidator(
vol.Schema(
{
vol.Required("handler"): vol.Any(str, list),
vol.Optional("show_advanced_options", default=False): cv.boolean,
},
extra=vol.ALLOW_EXTRA,
)
2019-07-31 19:25:30 +00:00
)
async def post(self, request: web.Request, data: Dict[str, Any]) -> web.Response:
"""Handle a POST request."""
2019-07-31 19:25:30 +00:00
if isinstance(data["handler"], list):
handler = tuple(data["handler"])
else:
2019-07-31 19:25:30 +00:00
handler = data["handler"]
try:
result = await self._flow_mgr.async_init(
handler, # type: ignore
context={
"source": config_entries.SOURCE_USER,
"show_advanced_options": data["show_advanced_options"],
},
2019-07-31 19:25:30 +00:00
)
except data_entry_flow.UnknownHandler:
2020-04-08 22:57:47 +00:00
return self.json_message("Invalid handler specified", HTTP_NOT_FOUND)
except data_entry_flow.UnknownStep:
2019-07-31 19:25:30 +00:00
return self.json_message("Handler does not support user", 400)
result = self._prepare_result_json(result)
return self.json(result)
class FlowManagerResourceView(_BaseFlowManagerView):
"""View to interact with the flow manager."""
async def get(self, request: web.Request, flow_id: str) -> web.Response:
"""Get the current state of a data_entry_flow."""
try:
result = await self._flow_mgr.async_configure(flow_id)
except data_entry_flow.UnknownFlow:
2020-04-08 22:57:47 +00:00
return self.json_message("Invalid flow specified", HTTP_NOT_FOUND)
result = self._prepare_result_json(result)
return self.json(result)
@RequestDataValidator(vol.Schema(dict), allow_empty=True)
async def post(
self, request: web.Request, flow_id: str, data: Dict[str, Any]
) -> web.Response:
"""Handle a POST request."""
try:
result = await self._flow_mgr.async_configure(flow_id, data)
except data_entry_flow.UnknownFlow:
2020-04-08 22:57:47 +00:00
return self.json_message("Invalid flow specified", HTTP_NOT_FOUND)
except vol.Invalid:
2019-07-31 19:25:30 +00:00
return self.json_message("User input malformed", 400)
result = self._prepare_result_json(result)
return self.json(result)
async def delete(self, request: web.Request, flow_id: str) -> web.Response:
"""Cancel a flow in progress."""
try:
self._flow_mgr.async_abort(flow_id)
except data_entry_flow.UnknownFlow:
2020-04-08 22:57:47 +00:00
return self.json_message("Invalid flow specified", HTTP_NOT_FOUND)
2019-07-31 19:25:30 +00:00
return self.json_message("Flow aborted")