Python Extension Folder

Wed 29 August 2012
By balrok

This is a Class which will allows you to create a folder and autoload all classes in it based on their name or regex. Maybe it can also be called Plugin System.

Examples

Since I don't know how to describe it best without confusing anyone I think examples are the best to begin with: This is the basefile, which will start registering and then loading the classes via name and then via regex:

from extension import ExtensionRegistrator
ext = ExtensionRegistrator()
ext.loadFolder('example/') # should end with a /
print "get Extension by name:"
for i in ['test1', 'another_test1', 'test2', 'generic']:
    print "%s -> %s" % (i, str(ext.getExtensionByName(i)))
print "get Extension by regex:"
for i in ['http://www.google.com/?q=123', 'http://www.amazon.com', 'amazon', 'nothing']:
    print "%s -> %s" % (i, str(ext.getExtensionByRegexStringMatch(i)))

Now each file inside the example folder: test1.py

from extension import Extension
I want to show here, that you easily can add a extension to your existing classes without changing their code
class Test1(object):
    def somestuff(self):
        pass
but it works only if you don't have too much public methods
class ExtensionTest1(Test1, Extension):
    eregex = '^(http://)?(www.)?google.com(.*)'
    ename = "test1"
    def somestuff(self):
        return Test1.somestuff(self)
another possibility is to have multiple extensions in one file:
class AnotherExtensionTest1(Test1, Extension):
    eregex = '^(http://)?(www.)?example.com(.*)'
    ename = "another_test1"
    def somestuff(self):
        return Test1.somestuff(self)

test2.py

from extension import Extension
class Test2(Extension):
    # just in case you don't know how to add multiple strings into a regex:
    eregex = '(^(http://)?(www.)?amazon.com(.*))|(amazon)'
    ename = "test2"

generic.py

from extension import Extension
class Generic(Extension):
    eregex = '.*'
    ename = "generic"
    # this will match for every regex, but we don't want that this will block others from being found
    # so give it the lowest priority with the following flag
    elowestPriority = True

The Code

I don't post the code here since it is too long.. it works like this: Iterate all .py files in the specified directory, iterate all classes inside these files, look if they inherit from Extension and then register them in a list with their name and regex.

When loading the extension just iterate that list and look for matches and return the class - which then can be instantiated.

Use cases

I think everywhere, where loose coupling via extension points makes sense.. For example I had a tool which would crawl some websites and one could append new websites just by creating a new pythonclass which wrapped the logic.. Those classes were loaded by the url-regex.

And as another use case I came up with: one gets a string which defines a serialization type and serialized data.. Then the program looks if an extension with this name of serialization-type exists and starts the deserialization.. so you can easily add more methods without changing existing code.

Another Example I came up with is as eventhandler: You write a bot and crawl some pages. On each page where the url doesn't contain "?ajax=true" you want to extract a particular part of the page..

Github

here

Commentaires: