Module pluginconf.bind

Basic plugin loader implementation. Plugins are assumed to reside in a flat namespace (main difference to module imports). This 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(__package__)  # or "plugins" etc.

# preset core app settings / load from json, add plugin options
conf = {}
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 Package basename to later load plugins from
path str Bind directory or pyz/zip bundle to plugin_base.
Returns None -

Module should be a package, as in a directory and init plugins/__init__.py. Ideally this module was already imported in main. But parameter may be a string.

This could be invoked multiple times for the package name to append further path= arguments (=./contrib/, =/usr/share/app/extenstions/, or a .pyz). Which is functionally identical to declaring __path__ in the package/__init__.py.

def cache(state=True)

Reduce plugin_meta() lookup costs, suitable for repeat find() calls

def defaults(conf)

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

Parameters
conf dict ๐Ÿ” Expands the conf dict with preset values from any plugins.
Returns None -
def find(**kwargs)

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

Parameters
type str Search by type: in plugins
api str Matching api: designator
category str Or a menu/category or other attributes
Returns dict basename โ†’ PluginMeta dict of matches
def load(name)

Import individual plugin from any of the base paths ๐Ÿš (The whole namespace is assumed to be flat, and identifiers to be unique.)

Parameters
name str Plugin name in any of the registered plugin_baseยดs.
Returns module Imported module
def load_enabled(conf)

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

Parameters
conf dict Should contain conf["plugins"] activation states
Returns generator Of loaded modules

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 ๐Ÿš