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 basepackage/__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 ๐