plugin_sliderTo create a simple plugin framework in python we will be using the following features in Python

  • Abstract Base Class : abc
  • Dynamic module import : __import__

Use case: Create a plugin framework for loading dynamic model classes that will be deployed in a directory while the server is running. Here in the example we have created a standalone module instead of a server for invoking the dynamic models loaded. This kind of dynamic loading is required where the classes are required to be dynamically loaded with out changing your core implementation.

Abstract Class: ModelAbstract.py

This is the Abstract class used for define the structure of your derived model classes. The plugin framework should state the interfaces that needs to be defined by the derived classes which needs to be loaded dynamically. Every derived class should inherit & implement all the abstract methods in Abstract class

import abc

class ModelAbstract(object):
    __metaclass__ = abc.ABCMeta

    def __init__( self ):
        print "Model abstract"

    @abc.abstractmethod
    def get_range(self,no_of_elements=1) :


    @abc.abstractmethod
    def get_resource(self, no_of_elements=1):

Derived Class : modela.py

This is the class which extends & implements all the abstract methods of ModelAbstract class

from . import ModelAbstract

class modela(ModelAbstract.ModelAbstract):
    RESOURCE_CONSTANT = 10
    def get_range(self,no_of_elements=1):
        return range(no_of_elements)

    def get_resource(self, resource_id=1) :
        return self.RESOURCE_CONSTANT * resource_id

Derived Class : modelb.py

from . import ModelAbstract

class modelb(ModelAbstract.ModelAbstract):
    RESOURCE_CONSTANT = 100
    def get_range(self,no_of_elements=1):
        return range(no_of_elements*2)

    def get_resource(self, resource_id=1) :
        return self.RESOURCE_CONSTANT * resource_id

Dynamic Model Loader : loader.py

This is the dynamic loader module which is used for dynamically loading the modules from the models directory.

import os

def fetch_model_files() :
    lst = os.listdir("models")
    models = list()
    for fil in lst :
        if fil.find("__") == -1 and fil.find(".pyc") == -1 :
            print fil
            pos = fil.find(".py")
            models.append(fil[:pos])
    return models

def load_model(type):
    try:
        modname = type
        #TODO check if already loaded
        module = __import__(modname, globals(), locals(), [type], -1)
        class_ = getattr(module, type)

        print "Dynamically loaded model :"+type
        classObj = class_()
        return classObj
    except Exception as e :
        print("No Model : "+type+", Error : "+e.message)
        raise e

Dynamic Model Class Invoker: invoker.py

This is the piece of code which is used for executing the dynamic loader & invoking the methods in the models.

import loader

def invoke_models(model_name)
    model_module_obj = loader.load_model(model_name.lower())

    range_val = model_module_obj.get_range(2)
    print range_val

invoke_model("modela")
invoke_model("modelb")
$ python invoker.py
$ [0,1]
$ [0, 1, 2, 3]