HiveBrain v1.2.0
Get Started
← Back to all entries
patternpythonMinor

Plugin Pattern for Generic Python Application

Submitted by: @import:stackexchange-codereview··
0
Viewed 0 times
genericapplicationpluginpythonforpattern

Problem

Summary

I am experimenting with a plugin pattern for a generic Python application (not necessarily web, desktop, or console) which would allow packages dropped into a plugin folder to be used according to the contract they would need to follow. In my case, this contract is simply to have a function called do_plugin_stuff(). I'd like the pattern to make sense for a system that sells plugins like the plugin store in Wordpress.

Minimal Python plugin mechanism is a decent question (despite being 4 years old) with some very good discussion about Django (which I haven't used) and how it allows for a plugin to be installed anywhere via pip. I'd see that as a phase two, because it seems like a pip-based plugin pattern is (sweeping generalization probably not always true) most valuable for purely free (as in money) plugin store. If free (as in open source) plugins are sold for money in a store, if seems that pip would be a poor choice for installation because which people might pay for something they're about to get the source code for and use freely / redistribute, they might be unlikely to pay / donate for something they've already installed.

Project Structure

Code

It's also on GitHub under my same username (PaluMacil) and I made a release tag of v1.0.0 to freeze the the repo at the code shown below.

app/plugins/blog/__init__.py

def do_plugin_stuff():
    print("I'm a blog!")


app/plugins/toaster/__init__.py

def do_plugin_stuff():
    print("I'm a toaster!")


app/plugins/__init__.py

(empty)


app/__init__.py

```
from importlib import import_module
from os import path, listdir

def create_app():
app = Application()
plugin_dir = path.join(path.dirname(__file__), 'plugins')

import_string_list = [''.join(['.plugins.', d]) for d
in listdir(plugin_dir)
if path.isdir(path.join(plugin_dir, d))
and not d.startswith('__')]

print(str(len(import_string_lis

Solution

You shouldn't call str on the int returned from len, instead use str.format.

"{} plugins in the app".format(len(app.plugins))


Format will coerce the int to a string implicitly and is neater to read.

Also you're calling repr backwards. The whole point of an object having a __repr__ function is that it allows an object to be passed to repr(). So you could change app.plugins.__repr__() to repr(app.plugins).

Code Snippets

"{} plugins in the app".format(len(app.plugins))

Context

StackExchange Code Review Q#103786, answer score: 2

Revisions (0)

No revisions yet.