ModuleDescriptor Protocol

ModuleDescriptor is the plugin contract that every module must satisfy. It is a typing.Protocol, so no inheritance is required — any class with the right attributes and methods qualifies.

What a Module Must Provide

Attribute / Method Type Description
module_id str Unique snake_case identifier, e.g. "outline"
display_name str Human-readable label shown in menus and tabs
document_label_singular str Label used by the host for one module-owned document
document_label_plural str Label used by the host for many documents
graph_types tuple[GraphType, ...] Domain types provided by this module
primary_graph_type str Canonical graph type name for new documents
configure(settings) None Apply runtime settings from modules.yaml
supports_graph_type(type_name) bool Return whether the module can render a graph type
create_widget(graph_service, parent) QWidget Factory for the module's root UI widget
create_document(graph_service, workspace_id, name) Graph Create a new module-owned graph
list_documents(graph_service, workspace_id) list[Graph] List module-owned graphs in a workspace

Minimal Example

from knowledge_platform.modules.base import ModuleDescriptor
from knowledge_platform.domain.graph_type import GraphType
from knowledge_platform.services.interfaces import IGraphService
from PySide6.QtWidgets import QWidget, QLabel


class MyGraphType(GraphType):
    type_name = "my_type"
    node_schemas = {}
    edge_schemas = {}


class MyModule:
    module_id = "my_module"
    display_name = "My Module"
    document_label_singular = "My Document"
    document_label_plural = "My Documents"
    graph_types = (MyGraphType(),)
    primary_graph_type = "my_type"

    def configure(self, settings) -> None:
        pass

    def supports_graph_type(self, type_name: str) -> bool:
        return type_name == "my_type"

    def create_widget(
        self,
        graph_service: IGraphService,
        parent: QWidget | None = None,
    ) -> QWidget:
        return QLabel("Hello from MyModule!", parent)

    def create_document(self, graph_service, workspace_id, name):
        return graph_service.create_graph(workspace_id, "my_type", name)

    def list_documents(self, graph_service, workspace_id):
        return [g for g in graph_service.list_graphs(workspace_id) if g.type_name == "my_type"]

Registration

At startup, modules are usually loaded through ModuleLoader from modules.yaml. The loader then registers each module descriptor with ModuleRegistry and each provided graph type with TypeRegistry.

from knowledge_platform.modules.loader import ModuleLoader

loader = ModuleLoader()
loader.register_into(type_registry, module_registry)

API Reference

knowledge_platform.modules.base.ModuleDescriptor

Bases: Protocol

Protocol defining the contract for all platform modules (plugins).

A module encapsulates:

  • One or more :class:~knowledge_platform.domain.graph_type.GraphType definitions.
  • A factory for the module's primary UI widget.
  • Module-specific document lifecycle hooks used by the host UI.

Attributes:

Name Type Description
module_id str

Unique snake_case identifier (e.g. "outline").

display_name str

Human-readable label shown in menus/tabs.

document_label_singular str

Human-readable label for one document.

document_label_plural str

Human-readable label for many documents.

graph_types tuple[GraphType, ...]

Graph types provided by this module.

primary_graph_type str

The canonical graph type name for this module.

Source code in src/knowledge_platform/modules/base.py
@runtime_checkable
class ModuleDescriptor(Protocol):
    """Protocol defining the contract for all platform modules (plugins).

    A module encapsulates:

    * One or more :class:`~knowledge_platform.domain.graph_type.GraphType`
      definitions.
    * A factory for the module's primary UI widget.
    * Module-specific document lifecycle hooks used by the host UI.

    Attributes:
        module_id: Unique snake_case identifier (e.g. ``"outline"``).
        display_name: Human-readable label shown in menus/tabs.
        document_label_singular: Human-readable label for one document.
        document_label_plural: Human-readable label for many documents.
        graph_types: Graph types provided by this module.
        primary_graph_type: The canonical graph type name for this module.
    """

    module_id: str
    display_name: str
    document_label_singular: str
    document_label_plural: str
    graph_types: tuple[GraphType, ...]
    primary_graph_type: str

    def configure(self, settings: Mapping[str, Any]) -> None:
        """Apply config-provided module settings."""
        ...

    def supports_graph_type(self, type_name: str) -> bool:
        """Return ``True`` if this module can render the given graph type."""
        ...

    def create_widget(self, graph_service: IGraphService, parent: "QWidget | None" = None) -> "QWidget":
        """Construct and return the module's primary UI widget.

        The platform calls this method once per module activation.  The
        returned widget is embedded directly in the main window's content area.

        Args:
            graph_service: Application service for all graph operations.
            parent: Optional Qt parent widget.

        Returns:
            The module's root :class:`QWidget`.
        """
        ...

    def create_document(
        self,
        graph_service: IGraphService,
        workspace_id: WorkspaceId,
        name: str,
    ) -> Graph:
        """Create a new module-owned document graph."""
        ...

    def list_documents(
        self,
        graph_service: IGraphService,
        workspace_id: WorkspaceId,
    ) -> list[Graph]:
        """List module-owned document graphs in a workspace."""
        ...

Functions

configure
configure(settings: Mapping[str, Any]) -> None

Apply config-provided module settings.

Source code in src/knowledge_platform/modules/base.py
def configure(self, settings: Mapping[str, Any]) -> None:
    """Apply config-provided module settings."""
    ...
create_document
create_document(
    graph_service: IGraphService,
    workspace_id: WorkspaceId,
    name: str,
) -> Graph

Create a new module-owned document graph.

Source code in src/knowledge_platform/modules/base.py
def create_document(
    self,
    graph_service: IGraphService,
    workspace_id: WorkspaceId,
    name: str,
) -> Graph:
    """Create a new module-owned document graph."""
    ...
create_widget
create_widget(
    graph_service: IGraphService,
    parent: "QWidget | None" = None,
) -> "QWidget"

Construct and return the module's primary UI widget.

The platform calls this method once per module activation. The returned widget is embedded directly in the main window's content area.

Parameters:

Name Type Description Default
graph_service IGraphService

Application service for all graph operations.

required
parent 'QWidget | None'

Optional Qt parent widget.

None

Returns:

Type Description
'QWidget'

The module's root :class:QWidget.

Source code in src/knowledge_platform/modules/base.py
def create_widget(self, graph_service: IGraphService, parent: "QWidget | None" = None) -> "QWidget":
    """Construct and return the module's primary UI widget.

    The platform calls this method once per module activation.  The
    returned widget is embedded directly in the main window's content area.

    Args:
        graph_service: Application service for all graph operations.
        parent: Optional Qt parent widget.

    Returns:
        The module's root :class:`QWidget`.
    """
    ...
list_documents
list_documents(
    graph_service: IGraphService, workspace_id: WorkspaceId
) -> list[Graph]

List module-owned document graphs in a workspace.

Source code in src/knowledge_platform/modules/base.py
def list_documents(
    self,
    graph_service: IGraphService,
    workspace_id: WorkspaceId,
) -> list[Graph]:
    """List module-owned document graphs in a workspace."""
    ...
supports_graph_type
supports_graph_type(type_name: str) -> bool

Return True if this module can render the given graph type.

Source code in src/knowledge_platform/modules/base.py
def supports_graph_type(self, type_name: str) -> bool:
    """Return ``True`` if this module can render the given graph type."""
    ...

knowledge_platform.modules.base.GraphWidget

Bases: Protocol

Common runtime contract for module root widgets.

Source code in src/knowledge_platform/modules/base.py
@runtime_checkable
class GraphWidget(Protocol):
    """Common runtime contract for module root widgets."""

    def load_graph(self, graph_id: GraphId) -> None:
        """Load a graph into the widget."""
        ...

    def clear_graph(self) -> None:
        """Clear any active graph state from the widget."""
        ...

Functions

clear_graph
clear_graph() -> None

Clear any active graph state from the widget.

Source code in src/knowledge_platform/modules/base.py
def clear_graph(self) -> None:
    """Clear any active graph state from the widget."""
    ...
load_graph
load_graph(graph_id: GraphId) -> None

Load a graph into the widget.

Source code in src/knowledge_platform/modules/base.py
def load_graph(self, graph_id: GraphId) -> None:
    """Load a graph into the widget."""
    ...