Skip to content

catalog_api

trestle.core.catalog.catalog_api ¤

Main entrypoint to interact with catalog in memory.

Attributes¤

logger = logging.getLogger(__name__) module-attribute ¤

Classes¤

CatalogAPI ¤

Main entrypoint to interact with catalog in memory.

Encapsulates all necessary functionality to manipulate, read and write the catalog and its markdown representation.

Source code in trestle/core/catalog/catalog_api.py
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 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
class CatalogAPI():
    """
    Main entrypoint to interact with catalog in memory.

    Encapsulates all necessary functionality to manipulate, read
    and write the catalog and its markdown representation.
    """

    def __init__(self, catalog: Optional[cat.Catalog], context: Optional[ControlContext] = None):
        """Initialize catalog api."""
        if not catalog:
            # catalog assemble initializes with no catalog but may merge into an existing one later
            logger.debug('No catalog was provided in CatalogAPI init, generating a new one.')
            catalog = gens.generate_sample_model(cat.Catalog)
        self._catalog = catalog
        self._catalog_interface = CatalogInterface(self._catalog)
        self._writer = CatalogWriter(self._catalog_interface)
        self._reader = CatalogReader(self._catalog_interface)
        self._merger = CatalogMerger(self._catalog_interface)
        self._context = context

    def update_context(self, context: ControlContext) -> None:
        """Update current context."""
        if not context:
            raise TrestleError('ControlContext cannot be empty.')
        self._context = context

    def write_catalog_as_markdown(self, label_as_key: bool = False) -> None:
        """
        Write out the catalog controls from dict as markdown files to the specified directory.

        Args:
            label_as_key: Whether to use label_as_key for part_id to label map

        Returns:
            None
        """
        # create the directory in which to write the control markdown files
        self._context.md_root.mkdir(exist_ok=True, parents=True)

        part_id_map = self._catalog_interface.get_statement_part_id_map(label_as_key=label_as_key)

        if self._context.purpose == ContextPurpose.PROFILE:
            found_alters, _, _ = self.read_additional_content_from_md(label_as_key=True)
            self._writer.write_catalog_as_profile_markdown(self._context, part_id_map, found_alters)
        elif self._context.purpose == ContextPurpose.COMPONENT:
            self._writer.write_catalog_as_component_markdown(self._context, part_id_map)
        elif self._context.purpose == ContextPurpose.SSP:
            self._writer.write_catalog_as_ssp_markdown(self._context, part_id_map)
        else:
            self._writer.write_catalog_as_catalog(self._context, part_id_map)

        # prune any directories that have no markdown files
        prune_empty_dirs(self._context.md_root, '*.md')

    def read_catalog_from_markdown(self, markdown_dir: pathlib.Path, is_set_parameters: bool) -> cat.Catalog:
        """Read catalog from markdown."""
        md_catalog = self._reader.read_catalog_from_markdown(markdown_dir, is_set_parameters)
        md_catalog_interface = CatalogInterface(md_catalog)
        if md_catalog_interface.get_count_of_controls_in_catalog(True) == 0:
            raise TrestleError(f'No controls were loaded from markdown {markdown_dir}.  No catalog created.')

        return md_catalog

    def read_additional_content_from_md(self,
                                        label_as_key: bool = False
                                        ) -> Tuple[List[prof.Alter], Dict[str, Any], Dict[str, str]]:
        """Read additional content from markdown."""
        if not self._context:
            raise TrestleError('Reading content from the markdown requires context to be initialized!')
        label_map = self._catalog_interface.get_statement_part_id_map(label_as_key=label_as_key)

        return self._reader.read_additional_content(
            self._context.md_root,
            self._context.required_sections,
            label_map,
            self._context.sections_dict,
            self._context.to_markdown
        )

    def merge_catalog(self, catalog: cat.Catalog, replace_params: bool) -> None:
        """Merge one catalog into another."""
        return self._merger.merge_catalog(catalog, replace_params)
Functions¤
__init__(catalog, context=None) ¤

Initialize catalog api.

Source code in trestle/core/catalog/catalog_api.py
42
43
44
45
46
47
48
49
50
51
52
53
def __init__(self, catalog: Optional[cat.Catalog], context: Optional[ControlContext] = None):
    """Initialize catalog api."""
    if not catalog:
        # catalog assemble initializes with no catalog but may merge into an existing one later
        logger.debug('No catalog was provided in CatalogAPI init, generating a new one.')
        catalog = gens.generate_sample_model(cat.Catalog)
    self._catalog = catalog
    self._catalog_interface = CatalogInterface(self._catalog)
    self._writer = CatalogWriter(self._catalog_interface)
    self._reader = CatalogReader(self._catalog_interface)
    self._merger = CatalogMerger(self._catalog_interface)
    self._context = context
merge_catalog(catalog, replace_params) ¤

Merge one catalog into another.

Source code in trestle/core/catalog/catalog_api.py
114
115
116
def merge_catalog(self, catalog: cat.Catalog, replace_params: bool) -> None:
    """Merge one catalog into another."""
    return self._merger.merge_catalog(catalog, replace_params)
read_additional_content_from_md(label_as_key=False) ¤

Read additional content from markdown.

Source code in trestle/core/catalog/catalog_api.py
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
def read_additional_content_from_md(self,
                                    label_as_key: bool = False
                                    ) -> Tuple[List[prof.Alter], Dict[str, Any], Dict[str, str]]:
    """Read additional content from markdown."""
    if not self._context:
        raise TrestleError('Reading content from the markdown requires context to be initialized!')
    label_map = self._catalog_interface.get_statement_part_id_map(label_as_key=label_as_key)

    return self._reader.read_additional_content(
        self._context.md_root,
        self._context.required_sections,
        label_map,
        self._context.sections_dict,
        self._context.to_markdown
    )
read_catalog_from_markdown(markdown_dir, is_set_parameters) ¤

Read catalog from markdown.

Source code in trestle/core/catalog/catalog_api.py
89
90
91
92
93
94
95
96
def read_catalog_from_markdown(self, markdown_dir: pathlib.Path, is_set_parameters: bool) -> cat.Catalog:
    """Read catalog from markdown."""
    md_catalog = self._reader.read_catalog_from_markdown(markdown_dir, is_set_parameters)
    md_catalog_interface = CatalogInterface(md_catalog)
    if md_catalog_interface.get_count_of_controls_in_catalog(True) == 0:
        raise TrestleError(f'No controls were loaded from markdown {markdown_dir}.  No catalog created.')

    return md_catalog
update_context(context) ¤

Update current context.

Source code in trestle/core/catalog/catalog_api.py
55
56
57
58
59
def update_context(self, context: ControlContext) -> None:
    """Update current context."""
    if not context:
        raise TrestleError('ControlContext cannot be empty.')
    self._context = context
write_catalog_as_markdown(label_as_key=False) ¤

Write out the catalog controls from dict as markdown files to the specified directory.

Parameters:

Name Type Description Default
label_as_key bool

Whether to use label_as_key for part_id to label map

False

Returns:

Type Description
None

None

Source code in trestle/core/catalog/catalog_api.py
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
def write_catalog_as_markdown(self, label_as_key: bool = False) -> None:
    """
    Write out the catalog controls from dict as markdown files to the specified directory.

    Args:
        label_as_key: Whether to use label_as_key for part_id to label map

    Returns:
        None
    """
    # create the directory in which to write the control markdown files
    self._context.md_root.mkdir(exist_ok=True, parents=True)

    part_id_map = self._catalog_interface.get_statement_part_id_map(label_as_key=label_as_key)

    if self._context.purpose == ContextPurpose.PROFILE:
        found_alters, _, _ = self.read_additional_content_from_md(label_as_key=True)
        self._writer.write_catalog_as_profile_markdown(self._context, part_id_map, found_alters)
    elif self._context.purpose == ContextPurpose.COMPONENT:
        self._writer.write_catalog_as_component_markdown(self._context, part_id_map)
    elif self._context.purpose == ContextPurpose.SSP:
        self._writer.write_catalog_as_ssp_markdown(self._context, part_id_map)
    else:
        self._writer.write_catalog_as_catalog(self._context, part_id_map)

    # prune any directories that have no markdown files
    prune_empty_dirs(self._context.md_root, '*.md')

Functions¤

handler: python