1 """Config flow for habitica integration."""
3 from __future__
import annotations
5 from http
import HTTPStatus
9 from aiohttp
import ClientResponseError
10 from habitipy.aio
import HabitipyAsync
11 import voluptuous
as vol
38 STEP_ADVANCED_DATA_SCHEMA = vol.Schema(
40 vol.Required(CONF_API_USER): str,
41 vol.Required(CONF_API_KEY): str,
42 vol.Optional(CONF_URL, default=DEFAULT_URL): str,
43 vol.Required(CONF_VERIFY_SSL, default=
True): bool,
47 STEP_LOGIN_DATA_SCHEMA = vol.Schema(
51 type=TextSelectorType.EMAIL,
57 type=TextSelectorType.PASSWORD,
58 autocomplete=
"current-password",
64 _LOGGER = logging.getLogger(__name__)
68 """Handle a config flow for habitica."""
73 self, user_input: dict[str, Any] |
None =
None
74 ) -> ConfigFlowResult:
75 """Handle the initial step."""
79 menu_options=[
"login",
"advanced"],
80 description_placeholders={
81 "signup": SIGN_UP_URL,
82 "habiticans": HABITICANS_URL,
87 self, user_input: dict[str, Any] |
None =
None
88 ) -> ConfigFlowResult:
89 """Config flow with username/password.
91 Simplified configuration setup that retrieves API credentials
92 from Habitica.com by authenticating with login and password.
94 errors: dict[str, str] = {}
95 if user_input
is not None:
98 api = await self.hass.async_add_executor_job(
106 login_response = await api.user.auth.local.login.post(
108 username=user_input[CONF_USERNAME],
109 password=user_input[CONF_PASSWORD],
112 except ClientResponseError
as ex:
113 if ex.status == HTTPStatus.UNAUTHORIZED:
114 errors[
"base"] =
"invalid_auth"
116 errors[
"base"] =
"cannot_connect"
118 _LOGGER.exception(
"Unexpected exception")
119 errors[
"base"] =
"unknown"
124 title=login_response[
"username"],
126 CONF_API_USER: login_response[
"id"],
127 CONF_API_KEY: login_response[
"apiToken"],
128 CONF_USERNAME: login_response[
"username"],
129 CONF_URL: DEFAULT_URL,
130 CONF_VERIFY_SSL:
True,
137 data_schema=STEP_LOGIN_DATA_SCHEMA, suggested_values=user_input
140 description_placeholders={
"forgot_password": FORGOT_PASSWORD_URL},
144 self, user_input: dict[str, Any] |
None =
None
145 ) -> ConfigFlowResult:
146 """Advanced configuration with User Id and API Token.
148 Advanced configuration allows connecting to Habitica instances
149 hosted on different domains or to self-hosted instances.
151 errors: dict[str, str] = {}
152 if user_input
is not None:
155 self.hass, verify_ssl=user_input.get(CONF_VERIFY_SSL,
True)
157 api = await self.hass.async_add_executor_job(
160 "login": user_input[CONF_API_USER],
161 "password": user_input[CONF_API_KEY],
162 "url": user_input.get(CONF_URL, DEFAULT_URL),
165 api_response = await api.user.get(
169 except ClientResponseError
as ex:
170 if ex.status == HTTPStatus.UNAUTHORIZED:
171 errors[
"base"] =
"invalid_auth"
173 errors[
"base"] =
"cannot_connect"
175 _LOGGER.exception(
"Unexpected exception")
176 errors[
"base"] =
"unknown"
180 user_input[CONF_USERNAME] = api_response[
"auth"][
"local"][
"username"]
182 title=user_input[CONF_USERNAME], data=user_input
188 data_schema=STEP_ADVANCED_DATA_SCHEMA, suggested_values=user_input
191 description_placeholders={
192 "site_data": SITE_DATA_URL,
193 "default_url": DEFAULT_URL,
ConfigFlowResult async_step_advanced(self, dict[str, Any]|None user_input=None)
ConfigFlowResult async_step_login(self, dict[str, Any]|None user_input=None)
ConfigFlowResult async_step_user(self, dict[str, Any]|None user_input=None)
None _abort_if_unique_id_configured(self, dict[str, Any]|None updates=None, bool reload_on_update=True, *str error="already_configured")
ConfigEntry|None async_set_unique_id(self, str|None unique_id=None, *bool raise_on_progress=True)
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_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)
vol.Schema add_suggested_values_to_schema(self, vol.Schema data_schema, Mapping[str, Any]|None suggested_values)
_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_show_menu(self, *str|None step_id=None, Container[str] menu_options, Mapping[str, str]|None description_placeholders=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)
aiohttp.ClientSession async_get_clientsession(HomeAssistant hass, bool verify_ssl=True, socket.AddressFamily family=socket.AF_UNSPEC, ssl_util.SSLCipherList ssl_cipher=ssl_util.SSLCipherList.PYTHON_DEFAULT)