def __getattr__(self, name): """Return the domain state.""" if "." in name: if not valid_entity_id(name): raise TemplateError("Invalid entity ID '{}'".format(name)) return _get_state(self._hass, name) if not valid_entity_id(name + ".entity"): raise TemplateError("Invalid domain name '{}'".format(name)) return DomainStates(self._hass, name)
def test_update_template_error(self, mock_render): hass = mock.MagicMock() vs = template.BinarySensorTemplate(hass, 'parent', 'Parent', 'motion', '{{ 1 > 1 }}') mock_render.side_effect = TemplateError('foo') vs.update() mock_render.side_effect = TemplateError( "UndefinedError: 'None' has no attribute") vs.update()
def test_update_template_error(self, mock_render): """"Test the template update error.""" vs = template.BinarySensorTemplate( self.hass, 'parent', 'Parent', 'motion', template_hlpr.Template('{{ 1 > 1 }}', self.hass), MATCH_ALL) mock_render.side_effect = TemplateError('foo') vs.update() mock_render.side_effect = TemplateError( "UndefinedError: 'None' has no attribute") vs.update()
def test_update_template_error(self, mock_render): """"Test the template update error.""" vs = run_callback_threadsafe( self.hass.loop, template.BinarySensorTemplate, self.hass, 'parent', 'Parent', 'motion', template_hlpr.Template('{{ 1 > 1 }}', self.hass), None, None, MATCH_ALL, None, None).result() mock_render.side_effect = TemplateError('foo') run_callback_threadsafe(self.hass.loop, vs.async_check_state).result() mock_render.side_effect = TemplateError( "UndefinedError: 'None' has no attribute") run_callback_threadsafe(self.hass.loop, vs.async_check_state).result()
def __getattr__(self, name): """Return the domain state.""" if "." in name: if not valid_entity_id(name): raise TemplateError(f"Invalid entity ID '{name}'") return _get_state(self._hass, name) if name in _RESERVED_NAMES: return None if not valid_entity_id(f"{name}.entity"): raise TemplateError(f"Invalid domain name '{name}'") return DomainStates(self._hass, name)
def async_render( self, variables: TemplateVarsType = None, parse_result: bool = True, limited: bool = False, **kwargs: Any, ) -> Any: """Render given template. This method must be run in the event loop. If limited is True, the template is not allowed to access any function or filter depending on hass or the state machine. """ if self.is_static: if self.hass.config.legacy_templates or not parse_result: return self.template return self._parse_result(self.template) compiled = self._compiled or self._ensure_compiled(limited) if variables is not None: kwargs.update(variables) try: render_result = compiled.render(kwargs) except Exception as err: raise TemplateError(err) from err render_result = render_result.strip() if self.hass.config.legacy_templates or not parse_result: return render_result return self._parse_result(render_result)
def _get_state_if_valid( hass: HomeAssistantType, entity_id: str ) -> Optional[TemplateState]: state = hass.states.get(entity_id) if state is None and not valid_entity_id(entity_id): raise TemplateError(f"Invalid entity ID '{entity_id}'") # type: ignore return _get_template_state_from_state(hass, entity_id, state)
def async_render( self, variables: TemplateVarsType = None, parse_result: bool = True, **kwargs: Any, ) -> Any: """Render given template. This method must be run in the event loop. """ if self.is_static: if self.hass.config.legacy_templates or not parse_result: return self.template return self._parse_result(self.template) compiled = self._compiled or self._ensure_compiled() if variables is not None: kwargs.update(variables) try: render_result = compiled.render(kwargs) except Exception as err: # pylint: disable=broad-except raise TemplateError(err) from err render_result = render_result.strip() if self.hass.config.legacy_templates or not parse_result: return render_result return self._parse_result(render_result)
def ensure_valid(self) -> None: """Return if template is valid.""" if self._compiled_code is not None: return try: self._compiled_code = self._env.compile(self.template) # type: ignore[no-untyped-call] except jinja2.TemplateError as err: raise TemplateError(err) from err
def ensure_valid(self): """Return if template is valid.""" if self._compiled_code is not None: return try: self._compiled_code = self._env.compile(self.template) except jinja2.exceptions.TemplateSyntaxError as err: raise TemplateError(err)
async def async_render_will_timeout( self, timeout: float, variables: TemplateVarsType = None, strict: bool = False, **kwargs: Any, ) -> bool: """Check to see if rendering a template will timeout during render. This is intended to check for expensive templates that will make the system unstable. The template is rendered in the executor to ensure it does not tie up the event loop. This function is not a security control and is only intended to be used as a safety check when testing templates. This method must be run in the event loop. """ if self.is_static: return False compiled = self._compiled or self._ensure_compiled(strict=strict) if variables is not None: kwargs.update(variables) self._exc_info = None finish_event = asyncio.Event() def _render_template() -> None: try: _render_with_context(self.template, compiled, **kwargs) except TimeoutError: pass except Exception: # pylint: disable=broad-except self._exc_info = sys.exc_info() finally: run_callback_threadsafe(self.hass.loop, finish_event.set) try: template_render_thread = ThreadWithException( target=_render_template) template_render_thread.start() await asyncio.wait_for(finish_event.wait(), timeout=timeout) if self._exc_info: raise TemplateError(self._exc_info[1].with_traceback( self._exc_info[2])) except asyncio.TimeoutError: template_render_thread.raise_exc(TimeoutError) return True finally: template_render_thread.join() return False
def render(hass, template, variables=None, **kwargs): """ Render given template. """ if variables is not None: kwargs.update(variables) try: return ENV.from_string(template, { 'states': AllStates(hass), 'is_state': hass.states.is_state }).render(kwargs).strip() except jinja2.TemplateError as err: raise TemplateError(err)
def async_render(self, variables: TemplateVarsType = None, **kwargs) -> str: """Render given template. This method must be run in the event loop. """ compiled = self._compiled or self._ensure_compiled() if variables is not None: kwargs.update(variables) try: return compiled.render(kwargs).strip() except jinja2.TemplateError as err: raise TemplateError(err)
def async_render(self, variables: TemplateVarsType = None, **kwargs: Any) -> str: """Render given template. This method must be run in the event loop. """ if self.is_static: return self.template.strip() compiled = self._compiled or self._ensure_compiled() if variables is not None: kwargs.update(variables) try: return compiled.render(kwargs).strip() except Exception as err: # pylint: disable=broad-except raise TemplateError(err) from err
def render(hass, template, variables=None, **kwargs): """Render given template.""" if variables is not None: kwargs.update(variables) location_methods = LocationMethods(hass) utcnow = dt_util.utcnow() try: return ENV.from_string(template, { 'closest': location_methods.closest, 'distance': location_methods.distance, 'float': forgiving_float, 'is_state': hass.states.is_state, 'is_state_attr': hass.states.is_state_attr, 'now': dt_util.as_local(utcnow), 'states': AllStates(hass), 'utcnow': utcnow, }).render(kwargs).strip() except jinja2.TemplateError as err: raise TemplateError(err)
def async_render(self, variables: TemplateVarsType = None, **kwargs: Any) -> Any: """Render given template. This method must be run in the event loop. """ if self.is_static: return self.template.strip() compiled = self._compiled or self._ensure_compiled() if variables is not None: kwargs.update(variables) try: render_result = compiled.render(kwargs) except jinja2.TemplateError as err: raise TemplateError(err) from err render_result = render_result.strip() if not self.hass.config.legacy_templates: try: result = literal_eval(render_result) # If the literal_eval result is a string, use the original # render, by not returning right here. The evaluation of strings # resulting in strings impacts quotes, to avoid unexpected # output; use the original render instead of the evaluated one. if not isinstance(result, str): return result except (ValueError, SyntaxError, MemoryError): pass return render_result
def __getattr__(self, name): """Return the states.""" entity_id = "{}.{}".format(self._domain, name) if not valid_entity_id(entity_id): raise TemplateError("Invalid entity ID '{}'".format(entity_id)) return _get_state(self._hass, entity_id)
def warn_unsupported(*args, **kwargs): raise TemplateError( f"Use of '{name}' is not supported in limited templates" )
def __getattr__(self, name): """Return the states.""" entity_id = f"{self._domain}.{name}" if not valid_entity_id(entity_id): raise TemplateError(f"Invalid entity ID '{entity_id}'") return _get_state(self._hass, entity_id)