Source code for colander_data_converter.exporters.graphviz

 1import json
 2from importlib import resources
 3from typing import TextIO
 4
 5from colander_data_converter.base.models import ColanderFeed
 6from colander_data_converter.exporters.exporter import BaseExporter
 7from colander_data_converter.exporters.template import TemplateExporter
 8
 9resource_package = __name__
10
11
[docs] 12class GraphvizExporter(BaseExporter): 13 """ 14 Exporter for generating Graphviz_ DOT format files from Colander data feeds. 15 16 This exporter creates Graphviz-compatible DOT format output that can be used to 17 visualize entity relationships and hierarchies. It uses Jinja2_ templates for 18 rendering and supports customizable themes for styling the generated graphs. 19 20 The exporter automatically loads a default theme if none is provided, ensuring 21 consistent visual output. The theme controls various visual aspects like colors, 22 shapes, and styling attributes for different entity types. 23 24 .. _Graphviz: https://graphviz.org/ 25 .. _Jinja2: https://jinja.palletsprojects.com/ 26 """ 27
[docs] 28 def __init__(self, feed: ColanderFeed, theme: dict = None): 29 """ 30 Initialize the GraphvizExporter with feed data and optional theme configuration. 31 32 Sets up the exporter with the provided data feed and theme. If no theme is 33 provided, loads the default theme from the package resources. Initializes 34 the internal :py:class:`~colander_data_converter.exporters.template.TemplateExporter` with the Graphviz_ template. 35 36 Args: 37 feed (~colander_data_converter.base.models.ColanderFeed): The data feed containing entities to 38 be exported. This feed will be processed and converted to Graphviz DOT format. 39 theme (dict, optional): Theme configuration dictionary that controls the 40 visual styling of the generated graph. If None, the 41 default theme will be loaded automatically. 42 """ 43 self.feed = feed 44 self.theme = theme 45 if not self.theme: 46 self.load_default_theme() 47 template_name = "graphviz.jinja2" 48 template_source_dir = resources.files(resource_package).joinpath("..").joinpath("data").joinpath("templates") 49 self.template_exporter = TemplateExporter(feed, str(template_source_dir), template_name) 50 self.feed.resolve_references()
51
[docs] 52 def load_default_theme(self): 53 """ 54 Load the default theme configuration from the package resources. 55 56 Reads the default theme JSON file from the package's data/themes directory 57 and loads it into the theme attribute. This method is automatically called 58 during initialization if no custom theme is provided. 59 """ 60 theme_file = ( 61 resources.files(resource_package) 62 .joinpath("..") 63 .joinpath("data") 64 .joinpath("themes") 65 .joinpath("default.json") 66 ) 67 with theme_file.open() as f: 68 self.theme = json.load(f)
69
[docs] 70 def export(self, output: TextIO, **kwargs): 71 """ 72 Export the feed data as Graphviz DOT format to the specified output stream. 73 74 Renders the Colander data feed using the configured Jinja2_ template and theme 75 to produce Graphviz_ DOT format output. The theme is passed to the template 76 as a context variable, allowing the template to apply consistent styling. 77 78 Args: 79 output (TextIO): A text-based output stream where the DOT format content 80 will be written. This can be a file object, StringIO, or 81 any object implementing the TextIO interface. 82 **kwargs: Additional keyword arguments that will be passed to the underlying 83 :py:class:`~colander_data_converter.exporters.template.TemplateExporter`. These can be used to 84 provide additional context variables to the Jinja2 template. 85 86 Raises: 87 jinja2.TemplateError: If there are errors in the template syntax or rendering 88 jinja2.TemplateNotFound: If the Graphviz template file cannot be found 89 IOError: If there are issues writing to the output stream 90 91 Note: 92 The generated DOT format can be processed by Graphviz_ tools (dot, neato, etc.) 93 to create visual representations in various formats (PNG, SVG, PDF, etc.). 94 The theme dictionary is automatically passed to the template as the 'theme' 95 variable. 96 """ 97 self.template_exporter.export(output, theme=self.theme)