Source code for resoterre.utils

"""General utilities."""

import datetime
import hashlib
import os
from string import Template
from typing import Any


[docs] class TemplateStore: """ Collection of string templates with substitution capabilities. Parameters ---------- templates : dict[str, str | Template] Dictionary of templates. substitutes : dict[str, str] Dictionary of substitution values. substitute_timestamp : bool Whether to automatically substitute the current timestamp. substitute_pid : bool Whether to automatically substitute the current process ID. """ templates: dict[str, Template] substitutes: dict[str, str] def __init__( self, templates: dict[str, str | Template] | None = None, substitutes: dict[str, str] | None = None, substitute_timestamp: bool = True, substitute_pid: bool = True, ) -> None: self.templates = {} if templates is not None: d: dict[str, Template] = {} for key, value in templates.items(): if isinstance(value, Template): d[key] = value else: d[key] = Template(value) self.templates = d if substitutes is None: self.substitutes = {} else: self.substitutes = substitutes self.substitute_timestamp = substitute_timestamp self.substitute_pid = substitute_pid def __copy__(self) -> "TemplateStore": """ Create a copy of the TemplateStore. Returns ------- TemplateStore A copy of the current TemplateStore. """ templates_copy: dict[str, str | Template] = {} for key, value in self.templates.items(): templates_copy[key] = Template(value.template) return TemplateStore( templates=templates_copy, substitutes=self.substitutes.copy(), substitute_timestamp=self.substitute_timestamp, substitute_pid=self.substitute_pid, ) def __getitem__(self, template_name: str) -> str: """ Get the template string with substitutions applied. Parameters ---------- template_name : str Name of the template to retrieve. Returns ------- str The template string with substitutions applied. """ delete_timestamp = False if self.substitute_timestamp and ("timestamp" not in self.substitutes): self.substitutes["timestamp"] = datetime.datetime.now().strftime("%Y-%m-%dT%H-%M-%S") delete_timestamp = True delete_pid = False if self.substitute_pid and ("pid" not in self.substitutes): self.substitutes["pid"] = str(os.getpid()) delete_pid = True substituted_str = self.templates[template_name].substitute(self.substitutes) if delete_timestamp: del self.substitutes["timestamp"] if delete_pid: del self.substitutes["pid"] return substituted_str
[docs] def complete(self, template_name: str) -> str: """ Complete the template by performing substitutions. Parameters ---------- template_name : str Name of the template to complete. Returns ------- str The completed template string. """ template_str = self[template_name] # ToDo: template.get_identifiers() is available in Python 3.11 if "$" in template_str: raise ValueError("Template not completely substituted.") return template_str
def __contains__(self, key: str) -> bool: """ Check if a template exists. Parameters ---------- key : str Name of the template. Returns ------- bool True if the template exists, False otherwise. """ return key in self.templates
[docs] def add(self, key: str, value: str | Template) -> None: """ Add a new template. Parameters ---------- key : str Name of the template. value : str | Template The template string or Template object. """ if not isinstance(value, Template): self.templates[key] = Template(value) else: self.templates[key] = value
[docs] def add_substitutes(self, **kwargs: str) -> None: r""" Add new substitution values. Parameters ---------- \*\*kwargs : dict[str, str] Key-value pairs for substitution. """ for key, value in kwargs.items(): self.substitutes[key] = value
[docs] def unique_hex_digest(unique_elements: Any, length: int = 8) -> str: """ Generate a unique hexadecimal digest based on the input elements. Parameters ---------- unique_elements : Any The elements to generate a unique digest for. They must have a unique string representation. length : int The length of the hexadecimal digest truncation to return. Returns ------- str A hexadecimal digest string of the specified length. """ return hashlib.sha256(str(unique_elements).encode()).hexdigest()[0:length]