Skip to content

Vega templates

Template

Source code in dvc_render/vega_templates.py
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
class Template:
    EXTENSION = ".json"
    ANCHOR = "<DVC_METRIC_{}>"

    DEFAULT_CONTENT: dict[str, Any] = {}
    DEFAULT_NAME: str = ""

    def __init__(
        self, content: Optional[dict[str, Any]] = None, name: Optional[str] = None
    ):
        if (
            content
            and not isinstance(content, dict)
            or self.DEFAULT_CONTENT
            and not isinstance(self.DEFAULT_CONTENT, dict)
        ):
            raise BadTemplateError
        self._original_content = content or self.DEFAULT_CONTENT
        self.content: dict[str, Any] = self._original_content
        self.name = name or self.DEFAULT_NAME
        self.filename = Path(self.name).with_suffix(self.EXTENSION)

    @classmethod
    def anchor(cls, name):
        "Get ANCHOR formatted with name."
        return cls.ANCHOR.format(name.upper())

    @classmethod
    def escape_special_characters(cls, value: str) -> str:
        "Escape special characters in `value`"
        for character in (".", "[", "]"):
            value = value.replace(character, "\\" + character)
        return value

    @staticmethod
    def check_field_exists(data, field):
        "Raise NoFieldInDataError if `field` not in `data`."
        if not any(field in row for row in data):
            raise NoFieldInDataError(field)

    def reset(self):
        """Reset self.content to its original state."""
        self.content = self._original_content

    def has_anchor(self, name) -> bool:
        "Check if ANCHOR formatted with name is in content."
        return find_value(self.content, self.anchor(name))

    def fill_anchor(self, name, value) -> None:
        "Replace anchor `name` with `value` in content."
        self.content = dict_replace_value(self.content, self.anchor(name), value)

anchor(name) classmethod

Get ANCHOR formatted with name.

Source code in dvc_render/vega_templates.py
101
102
103
104
@classmethod
def anchor(cls, name):
    "Get ANCHOR formatted with name."
    return cls.ANCHOR.format(name.upper())

check_field_exists(data, field) staticmethod

Raise NoFieldInDataError if field not in data.

Source code in dvc_render/vega_templates.py
113
114
115
116
117
@staticmethod
def check_field_exists(data, field):
    "Raise NoFieldInDataError if `field` not in `data`."
    if not any(field in row for row in data):
        raise NoFieldInDataError(field)

escape_special_characters(value) classmethod

Escape special characters in value

Source code in dvc_render/vega_templates.py
106
107
108
109
110
111
@classmethod
def escape_special_characters(cls, value: str) -> str:
    "Escape special characters in `value`"
    for character in (".", "[", "]"):
        value = value.replace(character, "\\" + character)
    return value

fill_anchor(name, value)

Replace anchor name with value in content.

Source code in dvc_render/vega_templates.py
127
128
129
def fill_anchor(self, name, value) -> None:
    "Replace anchor `name` with `value` in content."
    self.content = dict_replace_value(self.content, self.anchor(name), value)

has_anchor(name)

Check if ANCHOR formatted with name is in content.

Source code in dvc_render/vega_templates.py
123
124
125
def has_anchor(self, name) -> bool:
    "Check if ANCHOR formatted with name is in content."
    return find_value(self.content, self.anchor(name))

reset()

Reset self.content to its original state.

Source code in dvc_render/vega_templates.py
119
120
121
def reset(self):
    """Reset self.content to its original state."""
    self.content = self._original_content

dump_templates(output, targets=None)

Write TEMPLATES in .json format to output.

Source code in dvc_render/vega_templates.py
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
def dump_templates(output: "StrPath", targets: Optional[list] = None) -> None:
    "Write TEMPLATES in `.json` format to `output`."
    output = Path(output)
    output.mkdir(exist_ok=True)

    if targets:
        templates = [
            template for template in TEMPLATES if template.DEFAULT_NAME in targets
        ]
    else:
        templates = TEMPLATES

    for template_cls in templates:
        template = template_cls()
        path = output / template.filename

        if path.exists():
            content = path.read_text(encoding="utf-8")
            if content != template.content:
                raise TemplateContentDoesNotMatchError(template.DEFAULT_NAME, str(path))
        else:
            path.write_text(json.dumps(template.content), encoding="utf-8")

get_template(template=None, template_dir=None, fs=None)

Return template instance based on given template arg.

If template is already an instance, return it. If template is None, return default linear template. If template is a path, will try to find it: - Inside template_dir - As a relative path to cwd. If template matches one of the DEFAULT_NAMEs in TEMPLATES, return an instance of the one matching.

Source code in dvc_render/vega_templates.py
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
def get_template(
    template: Union[Optional[str], Template] = None,
    template_dir: Optional[str] = None,
    fs=None,
) -> Template:
    """Return template instance based on given template arg.

    If template is already an instance, return it.
    If template is None, return default `linear` template.
    If template is a path, will try to find it:
        - Inside `template_dir`
        - As a relative path to cwd.
    If template matches one of the DEFAULT_NAMEs in TEMPLATES,
    return an instance of the one matching.
    """
    if isinstance(template, Template):
        return template

    if template is None:
        template = "linear"

    template_path = _find_template(template, template_dir, fs)

    _open = open if fs is None else fs.open
    if template_path:
        with _open(template_path, encoding="utf-8") as f:
            content = json.load(f)
        return Template(content, name=template)

    for template_cls in TEMPLATES:
        if template == template_cls.DEFAULT_NAME:
            return template_cls()

    raise TemplateNotFoundError(template)