Module pluginconf.bind

Basic plugin loader implementation for flat namespaces. Ties together pluginconf lookups and config management for plugin loading in apps. It's rather basic, and subject to change. Does impose a config dict format, but no storage still.

Usage example

# designate a plugins/*.py package as plugin_base
import plugins
import pluginconf.bind
pluginconf.bind.base(plugins)

# preset core app settings / load from json, add plugin options
conf = {
    "plugins": {
    }
}
pluginconf.bind.defaults(conf)

# load conf-enabled plugins, and register modules somehow
for mod in pluginconf.bind.load_enabled(conf):
    mod.init()

Find by type

for name, pmd in pluginconf.bind.find(type="effect").items():
    mod = pluginconf.bind.load(name)
    if pmd.category == "menu":
        main_win.add_menu(mod.menu)

Note that this uses meta data extraction, so should best be confined for app setup/initialization, not used recurringly. The config state usage is the preferred method. (Only requires property loading once, for installation or with window() usage.)


Method interactions: ๐Ÿš = import, ๐Ÿงฉ = meta, ๐Ÿงพ = config, ๐Ÿ›  = setup

Functions

def base(module, path=None)

Register module as package/plugin_base. Or expand its search path ๐Ÿ›  .

Parameters

module : module/str
The package basename to later load plugins from (must be a package, like plugins/__init__.py, or be tied to a path= or zip). Ideally this module was already imported in main. But parameter may be a string.
path : str
Add a directory or pyz/zip bundle to registered plugin_base. Could be invoked multiple times =./contrib/, =/usr/share/app/extenstions/, =~/.config/app/userplug/ (same as declaring the __path__ in the base package/__init__.py.)
def defaults(conf)

Traverse installed plugins and expand config dict with presets ๐Ÿงฉ ๐Ÿงพ

Parameters

conf : dict ๐Ÿ”
Expands the top-level config dict with preset values from any plugins.
def find(**kwargs)

Find plugins by e.g. type= or category= ๐Ÿงฉ

Parameters

type : str
Usually you'd search on a designated plugin categorization, like type= and api=, or slot=, or class= or whatever is most consistent. Multiple attributes can be filtered on. (Version/title probably not useful here.)

Returns

dict : basename โ†’ PluginMeta dict
 
def load(name)

Import individual plugin from any of the base paths ๐Ÿš

Parameters

name : str
Plugin name in any of the registered plugin_baseยดs. (The whole namespace is assumed to be flat, and identifiers to be unique.)
def load_enabled(conf)

Import modules that are enabled in conf[plugins]={name:True,โ€ฆ} ๐Ÿงพ ๐Ÿš

Parameters

conf : dict
Simple options-value dictionary, but with one conf["plugins"] = {} subdict, which holds plugin activation states. The config dict doesn't have to match the available plugin options (defaults can be added), but should focus on essential presets. Differentiation only might become relevant for storage.

Classes

class isolated (package)

Context manager for isolated plugin structures. ๐Ÿ›  This is a shallow alternative to pluginbase and library-level plugins. Temporarily swaps global settings, thus maps most static functions.

with pluginconf.bind.isolated("libplugins") as bound:
    bound.modules2.init()
    print(
        bound.find(api="library")
    )

Static methods

def defaults()

return defaults for isolated plugin structure ๐Ÿงฉ ๐Ÿงพ

def find(**kwargs)

find by meta attributes ๐Ÿงฉ

def load(name)

load module from wrapped package ๐Ÿš

Methods

def get_data(self, *args, **kwargs)

get file relative to encapsulated plugins ๐Ÿš