HTML Rendering

Classes for rendering Viper data as HTML in web and desktop applications.

When to use: Use DocumentNode to traverse nested Viper documents with full metadata. Use Html to generate styled HTML output for Flask web apps or Qt desktop apps (via QTextEdit.setHtml()).

Quick Start

from flask import Flask, render_template
from dsviper import CommitDatabase, DocumentNode, Html, ValueKey

app = Flask(__name__)

@app.get("/document/<uuid:instance_id>")
def document_view(instance_id):
    db = CommitDatabase.open("model.cdb")
    db.definitions().inject()

    # Create key and get document accessor
    key = ValueKey.create(MYAPP_C_Entity, str(instance_id))
    attachment_getting = db.state(db.last_commit_id()).attachment_getting()

    # Build document tree for all attachments
    nodes = DocumentNode.create_documents(key, attachment_getting)

    # Render as collapsible HTML details
    content = Html.documents_details(nodes, show_type=True)
    return render_template("document.html", content=content)

DocumentNode Tree

DocumentNode provides a recursive tree structure for navigating Viper documents:

from dsviper import DocumentNode

# Create tree from a key
nodes = DocumentNode.create_documents(key, attachment_getting)

for node in nodes:
    print(f"{node.string_component()}: {node.string_value()}")

    # Type introspection for conditional rendering
    if node.is_editable():
        if node.is_boolean():
            render_checkbox(node)
        elif node.is_string():
            render_text_input(node)
        elif node.is_enumeration():
            render_select(node)

    # Recursive traversal
    if node.is_expandable():
        for child in node.children():
            render_node(child)

Custom HTML Rendering

Build custom renderers using DocumentNode metadata:

from dsviper import DocumentNode, ValueKey, ValueEnumeration

def render_node(node: DocumentNode, level: int = 0) -> str:
    indent = "  " * level
    html = ""

    if node.is_expandable():
        # Collapsible container
        html += f'{indent}<details open>'
        html += f'<summary>{node.string_component()}</summary>'
        for child in node.children():
            html += render_node(child, level + 1)
        html += f'{indent}</details>'
    else:
        # Leaf value
        html += f'{indent}<div>{node.string_component()} = '

        if node.is_editable():
            # Editable field with form input
            html += f'<input name="{node.uuid().encoded()}" '
            html += f'value="{node.string_value()}"/>'
        else:
            html += node.string_value()

        html += '</div>'

    return html

Node metadata available:

Method

Description

path()

Path to this node (for update() mutations)

key()

Document key (for identifying the document)

attachment()

Attachment containing this document

uuid()

Unique ID for this node (useful for HTML element IDs)

is_editable()

Whether this field can be modified

is_expandable()

Whether this node has children

children()

Child nodes for containers/structures

Html Helpers

The Html class provides ready-to-use rendering:

from dsviper import Html, DocumentNode

# Render documents as collapsible details
nodes = DocumentNode.create_documents(key, attachment_getting)
content = Html.documents_details(nodes, show_type=True)

# Render a single value with syntax highlighting
html = Html.value(my_structure)

# Pretty-print with indentation
html = Html.value_pretty(my_structure, show_type=True)

# Render DSM schema as HTML
html = Html.dsm_definitions(dsm_defs, show_documentation=True)

# Build complete HTML document
page = Html.document(
    title="My Document",
    style=Html.style(),
    body=Html.body(content)
)

Qt Desktop Integration

The same Html helpers work in Qt/PySide6 applications via QTextEdit:

from PySide6.QtWidgets import QTextEdit
from dsviper import Html, CommitDatabase

# In a Qt dialog or widget
class InspectDialog:
    def __init__(self):
        self.text_edit = QTextEdit()

    def show_definitions(self, db: CommitDatabase):
        # Get DSM definitions with HTML formatting
        dsm_defs = db.definitions().to_dsm_definitions()
        content = Html.dsm_definitions(dsm_defs, show_documentation=True)

        # Build complete HTML document
        style = Html.style()
        body = Html.body(content)
        document = Html.document("DSM Definitions", style, body)

        # Display in QTextEdit
        self.text_edit.setHtml(document)

    def show_value(self, value):
        content = Html.value(value, use_description=True)
        document = Html.document("Value", Html.style(), Html.body(content))
        self.text_edit.setHtml(document)

This pattern is used by cdbe.py (CDB Editor) and dbe.py (Database Editor) to display definitions and values with syntax highlighting.

Choosing the Right Approach

Use Case

API

Note

Quick document display

Html.documents_details()

Ready-to-use collapsible view

Custom form builder

DocumentNode traversal

Full control over rendering

Value debugging

Html.value_pretty()

Syntax-highlighted output

Schema documentation

Html.dsm_definitions()

Display DSM structure

Qt desktop display

Html.document() + setHtml()

Works with QTextEdit

DocumentNode

dsviper.DocumentNode

A class used to represent a node in the tree representation of a value.

Html

dsviper.Html

A class used to generate HTML representation.