Skip to content

Commit 407430f

Browse files
committed
Addded caching for render_... functions
1 parent 60e4615 commit 407430f

File tree

1 file changed

+62
-6
lines changed

1 file changed

+62
-6
lines changed

adafruit_templateengine.py

Lines changed: 62 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -848,12 +848,16 @@ def __init__(self, template_path: str, *, language: str = Language.HTML) -> None
848848
super().__init__(template_string, language=language)
849849

850850

851+
_CACHE: "dict[int, Template| FileTemplate]" = {}
852+
853+
851854
def render_string_iter(
852855
template_string: str,
853856
context: dict = None,
854857
*,
855858
chunk_size: int = None,
856859
language: str = Language.HTML,
860+
cache: bool = True,
857861
):
858862
"""
859863
Creates a `Template` from the given ``template_string`` and renders it using the provided
@@ -863,6 +867,7 @@ def render_string_iter(
863867
:param int chunk_size: Size of the chunks to be yielded. If ``None``, the generator yields
864868
the template in chunks sized specifically for the given template
865869
:param str language: Language for autoescaping. Defaults to HTML
870+
:param bool cache: When ``True``, the template is saved and reused on next calls.
866871
867872
Example::
868873
@@ -872,8 +877,20 @@ def render_string_iter(
872877
list(render_string_iter(r"Hello {{ name }}!", {"name": "CircuitPython"}, chunk_size=3))
873878
# ['Hel', 'lo ', 'Cir', 'cui', 'tPy', 'tho', 'n!']
874879
"""
875-
return Template(template_string, language=language).render_iter(
876-
context or {}, chunk_size=chunk_size
880+
key = hash(template_string)
881+
882+
if cache and key in _CACHE:
883+
return _yield_as_sized_chunks(
884+
_CACHE[key].render_iter(context or {}, chunk_size), chunk_size
885+
)
886+
887+
template = Template(template_string, language=language)
888+
889+
if cache:
890+
_CACHE[key] = template
891+
892+
return _yield_as_sized_chunks(
893+
template.render_iter(context or {}), chunk_size=chunk_size
877894
)
878895

879896

@@ -882,20 +899,32 @@ def render_string(
882899
context: dict = None,
883900
*,
884901
language: str = Language.HTML,
902+
cache: bool = True,
885903
):
886904
"""
887905
Creates a `Template` from the given ``template_string`` and renders it using the provided
888906
``context``. Returns the rendered output as a string.
889907
890908
:param dict context: Dictionary containing the context for the template
891909
:param str language: Language for autoescaping. Defaults to HTML
910+
:param bool cache: When ``True``, the template is saved and reused on next calls.
892911
893912
Example::
894913
895914
render_string(r"Hello {{ name }}!", {"name": "World"})
896915
# 'Hello World!'
897916
"""
898-
return Template(template_string, language=language).render(context or {})
917+
key = hash(template_string)
918+
919+
if cache and key in _CACHE:
920+
return _CACHE[key].render(context or {})
921+
922+
template = Template(template_string, language=language)
923+
924+
if cache:
925+
_CACHE[key] = template
926+
927+
return template.render(context or {})
899928

900929

901930
def render_template_iter(
@@ -904,6 +933,7 @@ def render_template_iter(
904933
*,
905934
chunk_size: int = None,
906935
language: str = Language.HTML,
936+
cache: bool = True,
907937
):
908938
"""
909939
Creates a `FileTemplate` from the given ``template_path`` and renders it using the provided
@@ -913,6 +943,7 @@ def render_template_iter(
913943
:param int chunk_size: Size of the chunks to be yielded. If ``None``, the generator yields
914944
the template in chunks sized specifically for the given template
915945
:param str language: Language for autoescaping. Defaults to HTML
946+
:param bool cache: When ``True``, the template is saved and reused on next calls.
916947
917948
Example::
918949
@@ -922,8 +953,20 @@ def render_template_iter(
922953
list(render_template_iter(..., {"name": "CircuitPython"}, chunk_size=3))
923954
# ['Hel', 'lo ', 'Cir', 'cui', 'tPy', 'tho', 'n!']
924955
"""
925-
return FileTemplate(template_path, language=language).render_iter(
926-
context or {}, chunk_size=chunk_size
956+
key = hash(template_path)
957+
958+
if cache and key in _CACHE:
959+
return _yield_as_sized_chunks(
960+
_CACHE[key].render_iter(context or {}, chunk_size), chunk_size
961+
)
962+
963+
template = FileTemplate(template_path, language=language)
964+
965+
if cache:
966+
_CACHE[key] = template
967+
968+
return _yield_as_sized_chunks(
969+
template.render_iter(context or {}, chunk_size=chunk_size), chunk_size
927970
)
928971

929972

@@ -932,17 +975,30 @@ def render_template(
932975
context: dict = None,
933976
*,
934977
language: str = Language.HTML,
978+
cache: bool = True,
935979
):
936980
"""
937981
Creates a `FileTemplate` from the given ``template_path`` and renders it using the provided
938982
``context``. Returns the rendered output as a string.
939983
940984
:param dict context: Dictionary containing the context for the template
941985
:param str language: Language for autoescaping. Defaults to HTML
986+
:param bool cache: When ``True``, the template is saved and reused on next calls.
942987
943988
Example::
944989
945990
render_template(..., {"name": "World"}) # r"Hello {{ name }}!"
946991
# 'Hello World!'
947992
"""
948-
return FileTemplate(template_path, language=language).render(context or {})
993+
994+
key = hash(template_path)
995+
996+
if cache and key in _CACHE:
997+
return _CACHE[key].render(context or {})
998+
999+
template = FileTemplate(template_path, language=language)
1000+
1001+
if cache:
1002+
_CACHE[key] = template
1003+
1004+
return template.render(context or {})

0 commit comments

Comments
 (0)