1 """RESTful platform for notify component."""
3 from __future__
import annotations
5 from http
import HTTPStatus
10 import voluptuous
as vol
17 PLATFORM_SCHEMA
as NOTIFY_PLATFORM_SCHEMA,
18 BaseNotificationService,
30 HTTP_BASIC_AUTHENTICATION,
31 HTTP_DIGEST_AUTHENTICATION,
40 CONF_DATA_TEMPLATE =
"data_template"
41 CONF_MESSAGE_PARAMETER_NAME =
"message_param_name"
42 CONF_TARGET_PARAMETER_NAME =
"target_param_name"
43 CONF_TITLE_PARAMETER_NAME =
"title_param_name"
44 DEFAULT_MESSAGE_PARAM_NAME =
"message"
45 DEFAULT_METHOD =
"GET"
46 DEFAULT_VERIFY_SSL =
True
48 PLATFORM_SCHEMA = NOTIFY_PLATFORM_SCHEMA.extend(
50 vol.Required(CONF_RESOURCE): cv.url,
52 CONF_MESSAGE_PARAMETER_NAME, default=DEFAULT_MESSAGE_PARAM_NAME
54 vol.Optional(CONF_METHOD, default=DEFAULT_METHOD): vol.In(
55 [
"POST",
"GET",
"POST_JSON"]
57 vol.Optional(CONF_HEADERS): vol.Schema({cv.string: cv.string}),
58 vol.Optional(CONF_PARAMS): vol.Schema({cv.string: cv.string}),
59 vol.Optional(CONF_NAME): cv.string,
60 vol.Optional(CONF_TARGET_PARAMETER_NAME): cv.string,
61 vol.Optional(CONF_TITLE_PARAMETER_NAME): cv.string,
62 vol.Optional(CONF_DATA): vol.All(dict, cv.template_complex),
63 vol.Optional(CONF_DATA_TEMPLATE): vol.All(dict, cv.template_complex),
64 vol.Optional(CONF_AUTHENTICATION): vol.In(
65 [HTTP_BASIC_AUTHENTICATION, HTTP_DIGEST_AUTHENTICATION]
67 vol.Optional(CONF_PASSWORD): cv.string,
68 vol.Optional(CONF_USERNAME): cv.string,
69 vol.Optional(CONF_VERIFY_SSL, default=DEFAULT_VERIFY_SSL): cv.boolean,
73 _LOGGER = logging.getLogger(__name__)
79 discovery_info: DiscoveryInfoType |
None =
None,
80 ) -> RestNotificationService:
81 """Get the RESTful notification service."""
82 resource: str = config[CONF_RESOURCE]
83 method: str = config[CONF_METHOD]
84 headers: dict[str, str] |
None = config.get(CONF_HEADERS)
85 params: dict[str, str] |
None = config.get(CONF_PARAMS)
86 message_param_name: str = config[CONF_MESSAGE_PARAMETER_NAME]
87 title_param_name: str |
None = config.get(CONF_TITLE_PARAMETER_NAME)
88 target_param_name: str |
None = config.get(CONF_TARGET_PARAMETER_NAME)
89 data: dict[str, Any] |
None = config.get(CONF_DATA)
90 data_template: dict[str, Any] |
None = config.get(CONF_DATA_TEMPLATE)
91 username: str |
None = config.get(CONF_USERNAME)
92 password: str |
None = config.get(CONF_PASSWORD)
93 verify_ssl: bool = config[CONF_VERIFY_SSL]
95 auth: httpx.Auth |
None =
None
96 if username
and password:
97 if config.get(CONF_AUTHENTICATION) == HTTP_DIGEST_AUTHENTICATION:
98 auth = httpx.DigestAuth(username, password)
100 auth = httpx.BasicAuth(username, password)
119 """Implementation of a notification service for REST."""
126 headers: dict[str, str] |
None,
127 params: dict[str, str] |
None,
128 message_param_name: str,
129 title_param_name: str |
None,
130 target_param_name: str |
None,
131 data: dict[str, Any] |
None,
132 data_template: dict[str, Any] |
None,
133 auth: httpx.Auth |
None,
136 """Initialize the service."""
151 """Send a message to a user."""
155 data[self.
_title_param_name_title_param_name] = kwargs.get(ATTR_TITLE, ATTR_TITLE_DEFAULT)
163 kwargs[ATTR_MESSAGE] = message
165 def _data_template_creator(value: Any) -> Any:
166 """Recursive template creator helper function."""
167 if isinstance(value, list):
168 return [_data_template_creator(item)
for item
in value]
169 if isinstance(value, dict):
171 key: _data_template_creator(item)
for key, item
in value.items()
173 if not isinstance(value, Template):
175 return value.async_render(kwargs, parse_result=
False)
178 data.update(_data_template_creator(self.
_data_data))
180 data.update(_data_template_creator(self.
_data_template_data_template))
183 if self.
_method_method ==
"POST":
184 response = await websession.post(
190 auth=self.
_auth_auth
or httpx.USE_CLIENT_DEFAULT,
192 elif self.
_method_method ==
"POST_JSON":
193 response = await websession.post(
199 auth=self.
_auth_auth
or httpx.USE_CLIENT_DEFAULT,
202 response = await websession.get(
205 params={**self.
_params_params, **data}
if self.
_params_params
else data,
207 auth=self.
_auth_auth,
211 response.status_code >= HTTPStatus.INTERNAL_SERVER_ERROR
212 and response.status_code < 600
215 "Server error. Response %d: %s:",
216 response.status_code,
217 response.reason_phrase,
220 response.status_code >= HTTPStatus.BAD_REQUEST
221 and response.status_code < HTTPStatus.INTERNAL_SERVER_ERROR
224 "Client error. Response %d: %s:",
225 response.status_code,
226 response.reason_phrase,
229 response.status_code >= HTTPStatus.OK
230 and response.status_code < HTTPStatus.MULTIPLE_CHOICES
233 "Success. Response %d: %s:",
234 response.status_code,
235 response.reason_phrase,
239 "Response %d: %s:", response.status_code, response.reason_phrase
None async_send_message(self, str message="", **Any kwargs)
None __init__(self, HomeAssistant hass, str resource, str method, dict[str, str]|None headers, dict[str, str]|None params, str message_param_name, str|None title_param_name, str|None target_param_name, dict[str, Any]|None data, dict[str, Any]|None data_template, httpx.Auth|None auth, bool verify_ssl)
RestNotificationService async_get_service(HomeAssistant hass, ConfigType config, DiscoveryInfoType|None discovery_info=None)
httpx.AsyncClient get_async_client(HomeAssistant hass, bool verify_ssl=True)