Plugin system

Dan Perl danperl at rogers.com
Sun Oct 31 19:56:10 CET 2004


"Dan Perl" <danperl at rogers.com> wrote in message 
news:CJ-dnanxkb5dUR7cRVn-1A at rogers.com...
>
> "Peter Hansen" <peter at engcorp.com> wrote in message 
> news:Rpudnd4nENKWMB7cRVn-rQ at powergate.ca...
>> Reinhold Birkenfeld wrote:
>>> Irmen de Jong wrote:
>>>>Reinhold Birkenfeld wrote:
>>>>
>>>>>How would you implement a plugin system (for a web-based application)?
>>>>
>>>>This is so general a question that I cannot think of anything concrete 
>>>>to answer.
>>>>Please ask again, with more detail about what you want/need/have in 
>>>>mind.
>>>
>>> Okay, the question is too open: My focus is on how you would structure
>>> the plugin code (directories, files) and how you would write code to
>>> load these plugins.
>>
>> And _this_ sounds like a combination of something that's more
>> a design issue (the structure) and a trivial implementation
>> detail (trivial in Python, anyway).
>>
>> I'll try anyway, as a first test case:  put all plugins in a
>> standard folder, with nothing else present in that folder.
>> They can be individual modules or packages as you will.
>> The code to load the plugin consists of an __import__...
>> and not much else.
>
> I have done something similar, with a few differences.  I am using a 
> convention that all the plugins are implemented as a class with a specific 
> name ("Handler" in my case), each plugin in its own module (so each 
> Handler class is scoped by its module).  I import all the modules in the 
> directory dedicated to plugins and I do the following checks: the module 
> contains a class Handler, the module is not the one implementing the base 
> class itself (bit of a hack, I admit), and the Handler class is a subclass 
> of the base class (use isinstance).  The checks allow to have also other 
> modules in the

I forgot what I'm doing in my own code.  I looked at it again and found that 
I'm not using isinstance(), instead I am doing a check for 
"baseClass.Handler in hndlrCls.__bases__", which is much better, because it 
doesn't need the creation of an instance.  Here is the actual code (my 
handlers are the equivalent of your plugins):
        # Build a list of the modules that contain a valid Handler class.
        hndlrList = []
        for hndlrFile in glob.glob(
            os.path.join(os.environ['zigzag_install_dir'], 'handlers', 
'*.py')):
            modName = os.path.split(os.path.splitext(hndlrFile)[0])[1]
            if modName == 'baseClass' or \
               modName == 'handlerTemplate':
                continue
            impMod = __import__('handlers.'+modName,
                                globals(),
                                locals(),
                                ['Handler'])
            if not vars(impMod).has_key('Handler'):
                continue
            hndlrCls = vars(impMod)['Handler']
            if not baseClass.Handler in hndlrCls.__bases__:
                continue
            hndlrList.append(modName)

baseClass.Handler is the base class for all my handlers.

> plugins directory that do not actually implement a plugin (for instance, I 
> have a mixin class in that same directory).
>
> Because you have both plugins and sub-plugins you may want to use some 
> checks like mine, so you have both plugins and sub-plugins in the same 
> directory, but you select only the plugin classes.  That's if I understand 
> your requirements correctly.
>
> Dan
>
>> Maybe this feedback will help you refine the question further...
>>
>> -Peter
>
> 





More information about the Python-list mailing list