1import jinja2
 2from opentelemetry import trace
 3from opentelemetry.semconv._incubating.attributes.code_attributes import (
 4    CODE_FUNCTION_NAME,
 5    CODE_NAMESPACE,
 6)
 7
 8from .jinja import environment
 9
10tracer = trace.get_tracer("plain")
11
12
13class TemplateFileMissing(Exception):
14    def __str__(self) -> str:
15        if self.args:
16            return f"Template file {self.args[0]} not found"
17        else:
18            return "Template file not found"
19
20
21class Template:
22    def __init__(self, filename: str) -> None:
23        self.filename = filename
24
25        try:
26            self._jinja_template = environment.get_template(filename)
27        except jinja2.TemplateNotFound:
28            raise TemplateFileMissing(filename)
29
30    def render(self, context: dict) -> str:
31        with tracer.start_as_current_span(
32            f"render {self.filename}",
33            kind=trace.SpanKind.INTERNAL,
34            attributes={
35                CODE_FUNCTION_NAME: "render",
36                CODE_NAMESPACE: f"{self.__class__.__module__}.{self.__class__.__qualname__}",
37                "template.filename": self.filename,
38                "template.engine": "jinja2",
39            },
40        ):
41            result = self._jinja_template.render(context)
42            return result