Plug-ins

General

Plug-ins form the base for openmatDB’s functionality. Even basic functions like returning the collections in the data base are provided by plug-ins. I.e. although the openmatDB user interfaces can run without any plug-in, they are of no real use without them.

In order to allow users to easily extend the data base functionality the plug-in concept is kept as simple as possible.

The concept is based on these principles:

  • Each plug-in has to have two mandatory functions - run and register
  • The run function is called when a plug-in is launched. It has only one mandatory argument - the session argument - which is a representation of the server that runs it (i.e. in case of the python plug-in server a PythonPluginServer class object - see API documentation
  • Further arguments to the run function could be a collection name, a record ID, an attribute in a record,…
  • The register function is used to inform a GUI how to handle the plug-in’s input and output - e.g.:
  • it provides the GUI with UI element definitions and data types required to define each of its parameter’s values (e.g. we would like to have a line edit to receive a collection name as a string or a spin box returning an integer to filter records based on a numeric attribute value)
  • it also proves information about the return type of the plug-in, so that the GUI knows how to render the results (e.g. as plain text, as a table or a plot chart)
  • additional information about the plug-in is provided in order to eventually render a help string, author names, license info, etc.
  • plug-ins are able call other plug-ins. This way complex functions can be realized with a small code base in the actual openmatDB modules
  • plug-ins can be written in different languages. Currently only a python interface is available, but since the plug-ins communicate with other plug-ins by exchanging information as JSON objects new language bindings (e.g. R, C++) can be created with relatively low effort.
  • plug-ins shall work without modification on both the desktop UI and the web-interface (which is given because the plug-ins do not directly communicate with the GUI layer. The GUI only needs to support methods to render the different input and return types of the plug-ins)
  • plug-ins shall also be usable without any GUI - e.g. allow batch processing

Structure of a plug-in

As mentioned above a plug-in can consist of only two mandatory functions - run and register. In the example below the code for a simple plug-in, which gets a specific record from the data base by its ID is shown:

def run(session, collection=None, recordID=None):
    record = session.db_client.get_record_by_ID(collection=collection, record_ID=recordID)

    return record


def register():
    return {
        'name': 'Get record by ID',
        'UI_elements': [
            {'type': 'TextInput',
             'label': 'Collection',
             'default_value': '',
             'data_type': 'str'},
            {'type': 'TextInput',
             'label': 'Record ID',
             'default_value': '',
             'data_type': 'str'},
        ],
        'help': 'Returns a dictionary representation of record identified by its ID',
        'return_type': 'text'
    }

As can be seen the run function takes three arguments: the session object, the name of the collection the record belongs to and the record’s ID.

In the run function the get_record_by_ID method of the session’s db_client is used to communicate with the data base. For data base functions provided by the - have a look at API for creating plug-ins in python.

The register function does nothing except returning a dictionary with the plug-in config info.

When the plug-in is selected in the GUI’s plug-in browser the plug-in’s name (defined in ‘name’), the help string (defined ‘help’) and two labelled text input fields (as defined in ‘UI_elements’) will be created - one for the collection and the other for the record ID. See Defined UI element types for details on the usage of the UI element entries.

The help string should clearly state, what the plug-in is doing, so that the users understand its functionality and can eventually use it in combination with their own plug-ins.

The return type (defined by ‘return_type’) is important for the GUI to correctly render the output of the plug-in. In this case (return type ‘text’) the output will just be rendered as plain text in a text box. See Defined return types for details.

As mentioned before plug-ins can also call other plug-ins. To illustrate this - the run function of a more complex plug-in (which returns a tree representation of the data base) is shown:

def run(session):
    collections = session.run_plugin('get_collections')

    tree = {}
    for collection in collections:
        records = session.run_plugin('get_records', *[collection, {}])
        record_ids = [record['_id'] for record in records]
        tree[collection] = record_ids

    return tree

The you can see this plug-in uses the session’s run_plugin method to launch other plug-ins and process their return values. In this case both the ‘get_collections’ and the ‘get_records’ plug-ins are used.

Defined UI element types

Besides the ‘type’ key all UI elements support the keys: ‘label’, ‘default_value’ and ‘data_type’.

Some UI elements may allow/require additional keys. The following UI element types are currently supported:

TextInput
A line edit

Note

This list is work in progress and will be extended in future releases.

Defined return types

The return type defines how the data shall be rendered in the GUI. Following return types are currently supported:

text
The returned results will be rendered as a text string a text box
pyplot
The returned results have to be rendered as a plot chart.

Note

This list is work in progress and will be extended in future releases.