Cache transient templates compiles provided via api

partially fixes #89047 (there is more going on here)
This commit is contained in:
J. Nick Koston
2023-03-02 10:40:20 -10:00
parent 8968ed1c47
commit 0971453d71
3 changed files with 18 additions and 4 deletions

View File

@@ -1,5 +1,6 @@
"""Rest API for Home Assistant.""" """Rest API for Home Assistant."""
import asyncio import asyncio
from functools import lru_cache
from http import HTTPStatus from http import HTTPStatus
import logging import logging
@@ -350,6 +351,9 @@ class APIComponentsView(HomeAssistantView):
return self.json(request.app["hass"].config.components) return self.json(request.app["hass"].config.components)
_cached_template = lru_cache(template.Template)
class APITemplateView(HomeAssistantView): class APITemplateView(HomeAssistantView):
"""View to handle Template requests.""" """View to handle Template requests."""
@@ -362,7 +366,8 @@ class APITemplateView(HomeAssistantView):
raise Unauthorized() raise Unauthorized()
try: try:
data = await request.json() data = await request.json()
tpl = template.Template(data["template"], request.app["hass"]) tpl = _cached_template(data["template"])
tpl.hass = request.app["hass"]
return tpl.async_render(variables=data.get("variables"), parse_result=False) return tpl.async_render(variables=data.get("variables"), parse_result=False)
except (ValueError, TemplateError) as ex: except (ValueError, TemplateError) as ex:
return self.json_message( return self.json_message(

View File

@@ -4,7 +4,7 @@ from __future__ import annotations
import asyncio import asyncio
from collections.abc import Callable, Coroutine from collections.abc import Callable, Coroutine
from contextlib import suppress from contextlib import suppress
from functools import wraps from functools import lru_cache, wraps
from http import HTTPStatus from http import HTTPStatus
import logging import logging
import secrets import secrets
@@ -365,6 +365,9 @@ async def webhook_stream_camera(
return webhook_response(resp, registration=config_entry.data) return webhook_response(resp, registration=config_entry.data)
_cached_template = lru_cache(template.Template)
@WEBHOOK_COMMANDS.register("render_template") @WEBHOOK_COMMANDS.register("render_template")
@validate_schema( @validate_schema(
{ {
@@ -381,7 +384,8 @@ async def webhook_render_template(
resp = {} resp = {}
for key, item in data.items(): for key, item in data.items():
try: try:
tpl = template.Template(item[ATTR_TEMPLATE], hass) tpl = _cached_template(item[ATTR_TEMPLATE])
tpl.hass = hass
resp[key] = tpl.async_render(item.get(ATTR_TEMPLATE_VARIABLES)) resp[key] = tpl.async_render(item.get(ATTR_TEMPLATE_VARIABLES))
except TemplateError as ex: except TemplateError as ex:
resp[key] = {"error": str(ex)} resp[key] = {"error": str(ex)}

View File

@@ -4,6 +4,7 @@ from __future__ import annotations
from collections.abc import Callable from collections.abc import Callable
from contextlib import suppress from contextlib import suppress
import datetime as dt import datetime as dt
from functools import lru_cache
import json import json
from typing import Any, cast from typing import Any, cast
@@ -424,6 +425,9 @@ def handle_ping(
connection.send_message(pong_message(msg["id"])) connection.send_message(pong_message(msg["id"]))
_cached_template = lru_cache(template.Template)
@decorators.websocket_command( @decorators.websocket_command(
{ {
vol.Required("type"): "render_template", vol.Required("type"): "render_template",
@@ -440,7 +444,8 @@ async def handle_render_template(
) -> None: ) -> None:
"""Handle render_template command.""" """Handle render_template command."""
template_str = msg["template"] template_str = msg["template"]
template_obj = template.Template(template_str, hass) template_obj = _cached_template(template_str)
template_obj.hass = hass
variables = msg.get("variables") variables = msg.get("variables")
timeout = msg.get("timeout") timeout = msg.get("timeout")
info = None info = None