Translation(s): none

(!) ?Discussion


Instructions on how to write a new DDE plugin.

When to write a plugin

Only write a plugin if you want to create an DDE export for databases like UDD or apt-xapian-index.

If you just periodically generate a small amount of static data, you can publish it by saving it in a format like yaml, json or pickle and put it in ~/.dde (see DDE/StaticData).

The plugin interface

Plugins are instances of an octofuss.Tree, which represent a subtree in the DDE information space; an octofuss.Tree is defined as an object which implements the following 4 methods:

Plugins get one parameter called path which the path of the requested subtree split into a list. [] means the node itself.

Some optional keyword arguments can be passed as hints for optimization purposes, and you should normally ignore them: this explains why every method also has a **kw parameter, but besides remembering to put it there, you should not worry about it.

Here is some annotated example plugin implementing a node with a value and no subtrees:

import octofuss

# Plugin interface
class Plugin(octofuss.Tree):
    def __init__(self):
        # The first parameter is the name of this node in the tree
        # The second parameter is the documentation for this node to use
        #   if the 'ldoc' method is missing
        super(Plugin, self).__init__("plugin", "Example plugin")

    def lhas(self, path, **kw):
        """
        Return True if the path exists, False if not.
        """
        # We are empty, so no subtrees exist:
        if path: return False
        # But we exist, so if path is [] return True:
        return True

    def lget(self, path, **kw):
        """
        Return the value of the node at path, or None if the path does not exist
        """
        # We are empty, so no subtrees exist:
        if path: return None
        # If path is [], return our value
        return "I am an example plugin"
        
    def llist(self, path, **kw):
        """
        Return a list with the names of the child nodes.
        
        If there are no child nodes or the path is invalid, return []
        """
        return []

    def ldoc(self, path, **kw):
        """
        Return the documentation for the given node.

        Return None if the node does not exist.
        """
        if path: return None
        return "Example plugin"

To allow DDE to instantiate the plugin, add to your module an 'init' function. It is passed optional information as keyword parameters (currently not really used, but planned for the future), and generates dictionaries with the octofuss.Tree objects and their mount point in the DDE tree:

def init(**kw):
    if os.environ.get("DDE_AVOID_CRUFT", None) is not None:
        return
    yield dict(
        tree = Plugin(),
        # Mount as /test/plugin
        root = "/test"
        )

The init function should only generate those plugins that are in a condition to be run (for example, ensuring that their data files exist, or that connections to their databases can be established).

Tips & Tricks


See also: