Skip to content

teff.graph.render

teff.graph.render

Graph serialization: Mermaid diagrams and YAML topology.

Functions:

Name Description
to_mermaid

Render graph as a Mermaid flowchart diagram.

to_mermaid

to_mermaid(graph, show_conditions=True)

Render graph as a Mermaid flowchart diagram.

Produces a flowchart TD definition: every node becomes a box labelled node_id[node.type] and every edge an arrow. The entry point is filled blue, __error__ edges are dashed and red, and conditional edges carry their condition as an edge label (when show_conditions is true).

Parameters:

Name Type Description Default
graph

The graph to render (exposes nodes, edges, entry_point).

required
show_conditions bool

Annotate conditional edges with their condition.

True

Returns:

Type Description
str

The Mermaid diagram as a string (no code fence).

Source code in teff/graph/render.py
26
27
28
29
30
31
32
33
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
def to_mermaid(graph, show_conditions: bool = True) -> str:
    """Render *graph* as a Mermaid flowchart diagram.

    Produces a ``flowchart TD`` definition: every node becomes a box
    labelled ``node_id[node.type]`` and every edge an arrow.  The entry
    point is filled blue, ``__error__`` edges are dashed and red, and
    conditional edges carry their condition as an edge label (when
    *show_conditions* is true).

    Args:
        graph: The graph to render (exposes ``nodes``, ``edges``,
            ``entry_point``).
        show_conditions: Annotate conditional edges with their condition.

    Returns:
        The Mermaid diagram as a string (no code fence).
    """
    lines = ["flowchart TD"]
    for node_id, node in graph.nodes.items():
        label = f"{node_id}[{node.type}]"
        lines.append(f'    {_mmq(node_id)}["{_mme(label)}"]')
    lines.append(f"    class {_mmq(graph.entry_point)} entry;")
    for edge in graph.edges:
        src = _mmq(edge.source_id)
        dst = _mmq(edge.target_id)
        if edge.condition == _ERROR_CONDITION:
            lines.append(f"    {src} -.->|error| {dst}")
        elif edge.condition and show_conditions:
            label = _condition_label(edge.condition)
            lines.append(f'    {src} -->|"{_mme(label)}"| {dst}')
        else:
            lines.append(f"    {src} --> {dst}")
    lines.append("    classDef entry fill:#bde0fe;")
    lines.append("    classDef error stroke:#ff5252,stroke-width:2px;")
    return "\n".join(lines)