Home Assistant Unofficial Reference 2024.12.1
config_flow.py
Go to the documentation of this file.
1 """Config flow for pushover integration."""
2 
3 from __future__ import annotations
4 
5 from collections.abc import Mapping
6 from typing import Any
7 
8 from pushover_complete import BadAPIRequestError, PushoverAPI
9 import voluptuous as vol
10 
11 from homeassistant.config_entries import ConfigEntry, ConfigFlow, ConfigFlowResult
12 from homeassistant.const import CONF_API_KEY, CONF_NAME
13 from homeassistant.core import HomeAssistant
14 
15 from .const import CONF_USER_KEY, DEFAULT_NAME, DOMAIN
16 
17 USER_SCHEMA = vol.Schema(
18  {
19  vol.Optional(CONF_NAME, default=DEFAULT_NAME): str,
20  vol.Required(CONF_API_KEY): str,
21  vol.Required(CONF_USER_KEY): str,
22  }
23 )
24 
25 
26 async def validate_input(hass: HomeAssistant, data: dict[str, Any]) -> dict[str, str]:
27  """Validate user input."""
28  errors = {}
29  pushover_api = PushoverAPI(data[CONF_API_KEY])
30  try:
31  await hass.async_add_executor_job(pushover_api.validate, data[CONF_USER_KEY])
32  except BadAPIRequestError as err:
33  if "application token is invalid" in str(err):
34  errors[CONF_API_KEY] = "invalid_api_key"
35  elif "user key is invalid" in str(err):
36  errors[CONF_USER_KEY] = "invalid_user_key"
37  else:
38  errors["base"] = "cannot_connect"
39  return errors
40 
41 
42 class PushBulletConfigFlow(ConfigFlow, domain=DOMAIN):
43  """Handle a config flow for pushover integration."""
44 
45  _reauth_entry: ConfigEntry | None
46 
47  async def async_step_reauth(
48  self, entry_data: Mapping[str, Any]
49  ) -> ConfigFlowResult:
50  """Perform reauth upon an API authentication error."""
51  self._reauth_entry_reauth_entry = self.hass.config_entries.async_get_entry(
52  self.context["entry_id"]
53  )
54  return await self.async_step_reauth_confirm()
55 
56  async def async_step_reauth_confirm(
57  self, user_input: dict[str, str] | None = None
58  ) -> ConfigFlowResult:
59  """Confirm reauth dialog."""
60  errors = {}
61  if user_input is not None and self._reauth_entry_reauth_entry:
62  user_input = {**self._reauth_entry_reauth_entry.data, **user_input}
63  self._async_abort_entries_match_async_abort_entries_match(
64  {
65  CONF_USER_KEY: user_input[CONF_USER_KEY],
66  CONF_API_KEY: user_input[CONF_API_KEY],
67  }
68  )
69  errors = await validate_input(self.hass, user_input)
70  if not errors:
71  self.hass.config_entries.async_update_entry(
72  self._reauth_entry_reauth_entry, data=user_input
73  )
74  await self.hass.config_entries.async_reload(self._reauth_entry_reauth_entry.entry_id)
75  return self.async_abortasync_abortasync_abort(reason="reauth_successful")
76 
77  return self.async_show_formasync_show_formasync_show_form(
78  step_id="reauth_confirm",
79  data_schema=vol.Schema(
80  {
81  vol.Required(CONF_API_KEY): str,
82  }
83  ),
84  errors=errors,
85  )
86 
87  async def async_step_user(
88  self, user_input: dict[str, Any] | None = None
89  ) -> ConfigFlowResult:
90  """Handle the initial step."""
91  errors = {}
92 
93  if user_input is not None:
94  self._async_abort_entries_match_async_abort_entries_match(
95  {
96  CONF_USER_KEY: user_input[CONF_USER_KEY],
97  CONF_API_KEY: user_input[CONF_API_KEY],
98  }
99  )
100  self._async_abort_entries_match_async_abort_entries_match({CONF_NAME: user_input[CONF_NAME]})
101 
102  errors = await validate_input(self.hass, user_input)
103  if not errors:
104  return self.async_create_entryasync_create_entryasync_create_entry(
105  title=user_input[CONF_NAME],
106  data=user_input,
107  )
108 
109  return self.async_show_formasync_show_formasync_show_form(
110  step_id="user",
111  data_schema=USER_SCHEMA,
112  errors=errors,
113  )
ConfigFlowResult async_step_reauth(self, Mapping[str, Any] entry_data)
Definition: config_flow.py:49
ConfigFlowResult async_create_entry(self, *str title, Mapping[str, Any] data, str|None description=None, Mapping[str, str]|None description_placeholders=None, Mapping[str, Any]|None options=None)
ConfigFlowResult async_step_user(self, dict[str, Any]|None user_input=None)
ConfigFlowResult async_abort(self, *str reason, Mapping[str, str]|None description_placeholders=None)
None _async_abort_entries_match(self, dict[str, Any]|None match_dict=None)
ConfigFlowResult async_show_form(self, *str|None step_id=None, vol.Schema|None data_schema=None, dict[str, str]|None errors=None, Mapping[str, str]|None description_placeholders=None, bool|None last_step=None, str|None preview=None)
_FlowResultT async_show_form(self, *str|None step_id=None, vol.Schema|None data_schema=None, dict[str, str]|None errors=None, Mapping[str, str]|None description_placeholders=None, bool|None last_step=None, str|None preview=None)
_FlowResultT async_create_entry(self, *str|None title=None, Mapping[str, Any] data, str|None description=None, Mapping[str, str]|None description_placeholders=None)
_FlowResultT async_abort(self, *str reason, Mapping[str, str]|None description_placeholders=None)
dict[str, str] validate_input(HomeAssistant hass, dict[str, Any] data)
Definition: config_flow.py:26