MedUX

OpenSource EMR

User Tools

Site Tools


en:dev:drafts:plugins

Plugin Drafts

As MedUX needs to be completely modular, we need a plugin framework that has some capabilities:

  • it must be easy to understand and use
  • it must be maintained. It must be a framework that will not vanish in half a year.

There are several plugin systems that are available for python, and could be possibly used as a base. A good overview is here. I'll leave out all the ones that do not fit here and just list the ones that are taken into consideration for MedUX:

  • GDAPS - our own plugin system
  • Yapsy - maybe too narrow
  • PyUtilib - Loosely derived from trac. I would use just the plugin framework core. Documentation of the “Component Architecture” is here

Old ones (not taken into consideration further):

Brainstorming:

  • Cryptographic (PGP, or at least SHA2) source authentication / integrity check / plugin signing.
  • Plugins as ZIP files or directories
  • Plugin class where plugins can derive from, or duck typing
  • python file for metadata too, or external JSON/XML file?
    • when plugin is a python file, (unknown) code must be run to determine the metadata of the plugin. But we have to trust the plugin anyway, as python has no sandbox possibility to run code in. So BestPractice would be:
      • audit the plugin
      • mark it as trusted, sign it
      • only run plugins that are signed.
  • How should plugin load order be determined?
    • plugin dependencies, and then determination by sorting algorithm?
    • hard coded “order” property of plugins and load by this order?

Here is a sample Python code for a plugin class:

class Plugin:
    """
    Plugin class to derive from
    """
 
    # name of the plugin
    name = "My Plugin"     
 
    # Version number
    # 3-tuple: major, minor, revision
    version = (1, 0, 0)    
 
    # Description of the plugin
    # long text, translatable
    description = ""       
 
    # Category to be listed in.
    category = "Base"
 
    # Author's name of the plugin
    autor = ""
 
    # Author's email of the plugin
    author_email = ""
 
    # Is this plugin configurable?
    # if True, method config_widget() should be implemented.
    configurable = False
 
    # Can this plugin be disabled by the user? Use with care.
    can_be_disabled = False
 
    def __init__(self):
        pass
 
    def setup(self):
        """
        Called once, when plugin gets installed.
        """
 
    def initialize(self):
        """
        Called at application start.
        Do all necessary things here to bring up the plugin.
        """
 
    def delayed_initialize(self):
        """
        Called after full start of the application, to set up other tasks 
        that are not that important. Can be called async.
        """
 
    def config_widget(self):
        """
        This method, if implemented, must return a QWidget, which then will get 
        loadedinto the config settings page of MedUX. The widget can have
        an optional method 'validate()' that takes no arguments and is called
        immediately after the user clicks OK. Changes are applied if
        (and only if) the validate method returns True.
        """
        raise NotImplementedError()
 
    def save_settings(self):
        """
        Save settings that are configured via the config_widget.
        This could be done individually, the preferred way is using
        the MedUX settings API.
        """
        raise NotImplementedError()

Some code ideas are taken from the calibre project, all code listed here is licensed under the GPLv3.

en/dev/drafts/plugins.txt · Last modified: 2019/09/15 16:23 by nerdoc