capellambse package

The capellambse package.

capellambse.load_model_extensions()

Load all model extensions.

This function loads all entry points in the group capellambse.model_extensions and executes them.

It is automatically called when loading a model. Calling it more than once has no effect, so it is safe (although not necessary) to explicitly call this function before loading a model.

Return type:

None

Subpackages

Submodules

capellambse.auditing module

class capellambse.auditing.AttributeAuditor

Bases: object

Audits access to attributes of ModelElements.

Warning

This will permanently add an audit hook to the global hook table. The auditor will keep the model alive, which may consume excessive memory. To avoid this, call the auditor object’s detach() method once you are done with it. This is automatically done if you use it as a context manager.

Examples

>>> auditor = AttributeAuditor(model, {"name", "description"})
>>> print(model.la.all_components[0].name)
Hogwarts
>>> auditor.recorded_ids
{'0d2edb8f-fa34-4e73-89ec-fb9a63001440'}
>>> # Cleanup
>>> auditor.detach()
>>> with AttributeAuditor(model, {"name", "description"}) as recorded_ids:
...     print(model.la.all_components[0].name)
...
Hogwarts
>>> recorded_ids
{'0d2edb8f-fa34-4e73-89ec-fb9a63001440'}
__init__(model, attrs=())
Parameters:
Return type:

None

detach()
Return type:

None

class capellambse.auditing.WriteProtector

Bases: object

Prevents accidental modifications to a model.

This class intentionally has very limited features. It is intended as inspiration and guidance for more specific classes that make more sophisticated use of audit events.

This class also contains a publicly usable set of events that signify changes to the model.

__init__(model)
Parameters:

model (MelodyModel)

Return type:

None

detach()
Return type:

None

events: Final = frozenset({'capellambse.create', 'capellambse.delete', 'capellambse.insert', 'capellambse.setattr', 'capellambse.setitem'})

Contains all built-in audit events that may modify the model.

capellambse.cli_helpers module

Helpers for working with models in CLI scripts.

capellambse.cli_helpers.ModelCLI(*__, **_)

Raise a dependency error.

capellambse.cli_helpers.ModelInfoCLI(*__, **_)

Raise a dependency error.

capellambse.cli_helpers.enumerate_known_models()

Enumerate the models that are found in the known_models folders.

Two places are searched for models: The known_models folder in the user’s configuration directory, and the known_models folder in the installed capellambse package.

Run the following command to print the location of the user’s known_models folder:

python -m capellambse.cli_helpers

In order to make a custom model known, place a JSON file in one of these known_models folders. It should contain a dictionary with the keyword arguments to MelodyModel - specifically it needs a path, optionally an entrypoint, and any additional arguments that the underlying FileHandler might need to gain access to the model.

Files in the user’s configuration directory take precedence over files in the package directory. If a file with the same name exists in both places, the one in the user’s configuration directory will be used.

Be aware that relative paths in the JSON will be interpreted relative to the current working directory.

Return type:

Iterator[Traversable]

capellambse.cli_helpers.loadcli(value)

Load a model from a file or JSON string.

This function works like loadinfo(), and also loads the model for convenience.

Parameters:

value (str | PathLike[str]) – As described for loadinfo().

Returns:

The loaded model, as described by the value.

Return type:

MelodyModel

Examples

def main():
    model = capellambse.loadcli(sys.argv[1])
capellambse.cli_helpers.loadinfo(value)

Load information about how to load a model as dict.

Parameters:

value (str | PathLike[str]) –

One of the following:

  • A str or PathLike pointing to an .aird file

  • A str or PathLike pointing to a .json file, which contains the arguments to instantiate a MelodyModel

  • The contents of such a JSON file (as string)

Returns:

A dict with information about how to load a MelodyModel.

Return type:

dict[str, Any]

Raises:
  • TypeError – If the value cannot be parsed as described above.

  • ValueError – If the value looks like a “known model” name, but the name is not defined.

Examples

def main():
    modelinfo = capellambse.loadinfo(sys.argv[1])
    # change any options, for example:
    modelinfo["diagram_cache"] = "/tmp/diagrams"
    model = MelodyModel(**modelinfo)

capellambse.decl module

Support for YAML-based declarative modelling.

A YAML-based approach to describing how to create and modify capellambse compatible models.

For an in-depth explanation, please refer to the full documentation about declarative modelling.

class capellambse.decl.FindBy

Bases: object

Find an object by specific attributes.

__init__(attributes)
Parameters:

attributes (Mapping[str, Any])

Return type:

None

attributes: Mapping[str, Any]
capellambse.decl.NewObject

alias of _NewObject

class capellambse.decl.Promise

Bases: object

References a model object that will be created later.

__init__(identifier)
Parameters:

identifier (str)

Return type:

None

identifier: str
class capellambse.decl.UUIDReference

Bases: object

References a model object by its UUID.

__init__(uuid)
Parameters:

uuid (UUIDString)

Return type:

None

uuid: UUIDString
exception capellambse.decl.UnfulfilledPromisesError

Bases: RuntimeError

A promise could not be fulfilled.

This exception is raised when a promise is referenced via !promise, but it is never fulfilled by declaring an object with the same promise_id.

class capellambse.decl.YDMDumper

Bases: SafeDumper

A YAML dumper with extensions for declarative modelling.

represent_findby(data)
Parameters:

data (Any)

Return type:

Node

represent_newobj(data)
Parameters:

data (Any)

Return type:

Node

represent_promise(data)
Parameters:

data (Any)

Return type:

Node

represent_uuidref(data)
Parameters:

data (Any)

Return type:

Node

yaml_representers = {<class 'NoneType'>: <function SafeRepresenter.represent_none>, <class 'bool'>: <function SafeRepresenter.represent_bool>, <class 'bytes'>: <function SafeRepresenter.represent_binary>, <class 'capellambse.decl.FindBy'>: <function YDMDumper.represent_findby>, <class 'capellambse.decl.Promise'>: <function YDMDumper.represent_promise>, <class 'capellambse.decl.UUIDReference'>: <function YDMDumper.represent_uuidref>, <class 'capellambse.model.common.accessors._NewObject'>: <function YDMDumper.represent_newobj>, <class 'datetime.date'>: <function SafeRepresenter.represent_date>, <class 'datetime.datetime'>: <function SafeRepresenter.represent_datetime>, <class 'dict'>: <function SafeRepresenter.represent_dict>, <class 'float'>: <function SafeRepresenter.represent_float>, <class 'int'>: <function SafeRepresenter.represent_int>, <class 'list'>: <function SafeRepresenter.represent_list>, <class 'set'>: <function SafeRepresenter.represent_set>, <class 'str'>: <function SafeRepresenter.represent_str>, <class 'tuple'>: <function SafeRepresenter.represent_list>, None: <function SafeRepresenter.represent_undefined>}
class capellambse.decl.YDMLoader

Bases: SafeLoader

A YAML loader with extensions for declarative modelling.

construct_findby(node)
Parameters:

node (Node)

Return type:

FindBy

construct_newobj(node)
Parameters:

node (Node)

Return type:

_NewObject

construct_promise(node)
Parameters:

node (Node)

Return type:

Promise

construct_uuidref(node)
Parameters:

node (Node)

Return type:

UUIDReference

yaml_constructors = {'!find': <function YDMLoader.construct_findby>, '!new_object': <function YDMLoader.construct_newobj>, '!promise': <function YDMLoader.construct_promise>, '!uuid': <function YDMLoader.construct_uuidref>, 'tag:yaml.org,2002:binary': <function SafeConstructor.construct_yaml_binary>, 'tag:yaml.org,2002:bool': <function SafeConstructor.construct_yaml_bool>, 'tag:yaml.org,2002:float': <function SafeConstructor.construct_yaml_float>, 'tag:yaml.org,2002:int': <function SafeConstructor.construct_yaml_int>, 'tag:yaml.org,2002:map': <function SafeConstructor.construct_yaml_map>, 'tag:yaml.org,2002:null': <function SafeConstructor.construct_yaml_null>, 'tag:yaml.org,2002:omap': <function SafeConstructor.construct_yaml_omap>, 'tag:yaml.org,2002:pairs': <function SafeConstructor.construct_yaml_pairs>, 'tag:yaml.org,2002:seq': <function SafeConstructor.construct_yaml_seq>, 'tag:yaml.org,2002:set': <function SafeConstructor.construct_yaml_set>, 'tag:yaml.org,2002:str': <function SafeConstructor.construct_yaml_str>, 'tag:yaml.org,2002:timestamp': <function SafeConstructor.construct_yaml_timestamp>, None: <function SafeConstructor.construct_undefined>}
capellambse.decl.apply(model, file)

Apply a declarative modelling file to the given model.

Parameters:
Return type:

dict[Promise, ModelObject]

Notes

This function is not transactional: If an exception occurs during this function, the model will be left partially modified, with no reliable way to know how much of the YAML input has been consumed. It is therefore advised to reload or discard the model immediately in these cases, to avoid working with an inconsistent state.

Even though the YAML layout suggests linear execution from top to bottom, the actual order in which modifications are executed is implementation defined. This is necessary to support promises with !promise, but reorderings are still possible even if no promises are used in an input document.

capellambse.decl.dump(instructions)

Dump an instruction stream to YAML.

Parameters:

instructions (Sequence[Mapping[str, Any]])

Return type:

str

capellambse.decl.load(file)

Load an instruction stream from a YAML file.

Parameters:

file (IO[str] | str | PathLike[Any]) – An open file-like object, or a path or PathLike pointing to such a file. Files are expected to use UTF-8 encoding.

Return type:

list[dict[str, Any]]

capellambse.diagram_cache module

CLI for the diagram cache updating feature.

capellambse.helpers module

Miscellaneous utility functions used throughout the modules.

class capellambse.helpers.EverythingContainer

Bases: Container[Any]

A container that contains everything.

capellambse.helpers.escape_linked_text(loader, attr_text)

Transform simple HTML with object links into LinkedText.

This is the inverse operation of unescape_linked_text().

Parameters:
Return type:

str

capellambse.helpers.extent_func(text, fonttype='OpenSans-Regular.ttf', size=12)

Calculate the display size of the given text.

Parameters:
  • text (str) – Text to calculate pixel size on

  • fonttype (str) – The font type / face

  • size (int) – Font size (px)

Returns:

  • width – The calculated width of the text (px).

  • height – The calculated height of the text (px).

Return type:

tuple[float, float]

capellambse.helpers.flatten_html_string(text)

Convert an HTML-string to plain text.

Parameters:

text (str)

Return type:

str

capellambse.helpers.flock(file)
Parameters:

file (Path)

Return type:

Iterator[None]

capellambse.helpers.get_text_extent(text, width=inf, fonttype='OpenSans-Regular.ttf', fontsize=12)

Calculate the bounding box size of text after line wrapping.

Parameters:
  • text (str) – Text to calculate the size for.

  • width (float | int) – Maximum line length (px).

  • fonttype (str) – The font type / face

  • fontsize (int) – Font size (px)

Returns:

  • width – The width of the text after word wrapping (px).

  • height – The height of the text after word wrapping (px).

Return type:

tuple[float, float]

capellambse.helpers.get_transformation(class_, pos, size)

Calculate transformation for class.

The Scaling factor .725, translation constants (6, 5) are arbitrarily chosen to fit. Currently only ChoicePseudoState is tranformed.

Parameters:
Return type:

dict[str, str]

capellambse.helpers.is_uuid_string(string)

Validate that string is a valid UUID.

Parameters:

string (Any)

Return type:

TypeGuard[UUIDString]

capellambse.helpers.load_font(fonttype, size)
Parameters:
Return type:

FreeTypeFont

capellambse.helpers.make_short_html(clsname, uuid, name='', value='')
Parameters:
Return type:

Markup

capellambse.helpers.normalize_pure_path(path, *, base='/')

Make a PurePosixPath relative to base and collapse .. components.

Parameters:
  • path (str | PurePosixPath) – The input path to normalize.

  • base (str | PurePosixPath) – The base directory to which relative paths should be interpreted. Ignored if the input path is not relative.

Returns:

The normalized path.

Return type:

pathlib.PurePosixPath

capellambse.helpers.ntuples(num: int, iterable: Iterable[_T], *, pad: Literal[False] = False) Iterator[tuple[_T, ...]]
capellambse.helpers.ntuples(num: int, iterable: Iterable[_T], *, pad: Literal[True]) Iterator[tuple[_T | None, ...]]

Yield N items of iterable at once.

Parameters:
  • num – The number of items to yield at once.

  • iterable – An iterable.

  • pad – If the items in iterable are not evenly divisible by n, pad the last yielded tuple with Nones. If False, the last tuple will be discarded.

Yields:

items – A num long tuple of items from iterable.

capellambse.helpers.process_html_fragments(markup, node_callback)

Repair and modify HTML markup.

The original markup, which can be an HTML fragment (without a root element), is parsed and processed, and then reassembled into a Markup instance. If the original markup contained any errors or inconsistencies, these are repaired in the returned Markup instance.

Parameters:
  • markup (str) – The markup string to modify.

  • node_callback (Callable[[_Element], None]) –

    A callback function to process each node in the parsed markup. The function should accept a single lxml.etree._Element as argument; its return value is ignored.

    Note that, since the markup is parsed as fragments, more than the first element passed to the callback may have no parent.

    The callback will not be invoked for leading text, if there is any, and thus it has no ability to influence it.

Returns:

The processed markup.

Return type:

markupsafe.Markup

capellambse.helpers.relpath_pure(path, start)

Calculate the relative path between two pure paths.

Unlike pathlib.PurePath.relative_to(), this method can cope with path not being a subpath of start. And unlike the os.path.relpath() function, it does not involve any filesystem access.

Parameters:
Return type:

PurePosixPath

capellambse.helpers.repair_html(markup)

Try to repair broken HTML markup to prevent parse errors.

Parameters:

markup (str) – The markup to try and repair.

Returns:

The repaired markup.

Return type:

markupsafe.Markup

Replace hlink:// links with arbitrary other links.

Parameters:
  • markup (str) – The markup to process.

  • model (MelodyModel) – The model to use for resolving UUIDs.

  • make_href (Callable[[GenericElement], str | None]) – A function that maps objects to URLs. This function is called once for each link (possibly multiple times for the same object), and must return a URL to be inserted in place of the original hlink://... URL.

  • broken_link_css (str) – Broken links (links to objects that have been deleted, and links where the make_href callback returned None or an empty string) are indicated by a <span> element with this CSS style applied to it.

Return type:

Markup

capellambse.helpers.resolve_namespace(tag)

Resolve a ‘:’-delimited symbolic namespace to its canonical form.

Parameters:

tag (str) – Symbolic namespace delimited by ‘:’.

Returns:

Tag string in canonical form.

Return type:

str

Split a string containing intra- and inter-fragment links.

Intra-fragment links are simply “#UUID”, whereas inter-fragment links look like “xtype fragment#UUID”. Multiple such links are space-separated in a single long string to form a list. This function splits such a string back into its individual components (each being either an intra- or inter-fragment link), and yields them.

Yields:

str – A single link from the list.

Parameters:

links (str)

Return type:

Iterator[str]

capellambse.helpers.ssvparse(string, cast, *, parens=('', ''), sep=',', num=0)

Parse a string of sep-separated values wrapped in parens.

Parameters:
  • string (str) – The input string.

  • cast (Callable[[str], _T]) – A type to cast the values into.

  • parens (Sequence[str]) – The parentheses that must exist around the input. Either a two-character string or a 2-tuple of strings.

  • sep (str) – The separator between values.

  • num (int) – If non-zero, only accept exactly this many values.

Returns:

A list of values cast into the given type.

Return type:

list[_T]

Raises:

ValueError – If the parentheses are missing around the input string, or if the expected number of values doesn’t match the actual number.

capellambse.helpers.unescape_linked_text(loader, attr_text)

Transform the linkedText into regular HTML.

Parameters:
Return type:

Markup

capellambse.helpers.word_wrap(text, width)

Perform word wrapping for proportional fonts.

Whitespace at the beginning of input lines is preserved, but other whitespace is collapsed to single spaces. Words are kept as a whole, possibly leading to exceeding width bound.

Parameters:
  • text (str) – The text to wrap.

  • width (float | int) – The width in pixels to wrap to.

Returns:

A list of strings, one for each line, after wrapping.

Return type:

list[str]

capellambse.helpers.xpath_fetch_unique(xpath: str | XPath, tree: _Element, elm_name: str, elm_uid: str | None = None, *, optional: Literal[False] = False) _Element
capellambse.helpers.xpath_fetch_unique(xpath: str | XPath, tree: _Element, elm_name: str, elm_uid: str | None = None, *, optional: Literal[True]) _Element | None

Fetch an XPath result from the tree, ensuring that it’s unique.

Parameters:
  • xpath – The lxml.etree.XPath object to apply, or an XPath expression as str.

  • tree – The (sub-)tree to which the XPath will be applied.

  • elm_name – A human-readable element name for error messages.

  • elm_uid – UID of the element which triggered this lookup. Will be included in the error message if an error occured.

  • optional – True to return None in case the element is not found. Otherwise a ValueError will be raised.

Returns:

The Element found by given xpath.

Return type:

lxml.etree._Element | None

Raises:

ValueError – If more than one element was found matching the xpath, or if optional is False and no matching element was found.

capellambse.helpers.xtype_of(elem)

Return the xsi:type of the element.

If the element has an xsi:type attribute, its value is returned.

If the element does not have an xsi:type, this function resolves the tag’s namespace to the symbolic name and reconstructs the type with the namespace:tag template.

Parameters:

elem (_Element) – The lxml.etree._Element object to return the xsi:type for.

Raises:
  • capellambse.UnsupportedPluginError – If the plugin is unknown and therefore not supported.

  • capellambse.UnsupportedPluginVersionError – If the plugin’s version is not supported.

Returns:

The xsi:type string of the provided element or None if the type could not be determined.

Return type:

str | None