<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, minimum-scale=1" />
<meta name="generator" content="pdoc 0.10.0" />
<title>pluginconf.bind API documentation</title>
<meta name="description" content="Basic plugin loader implementation for flat namespaces. Ties together
pluginconf lookups and config management for plugin loading in apps.
It's rather โฆ" />
<link rel="preload stylesheet" as="style" href="https://cdnjs.cloudflare.com/ajax/libs/10up-sanitize.css/11.0.1/sanitize.min.css" integrity="sha256-PK9q560IAAa6WVRRh76LtCaI8pjTJ2z11v0miyNNjrs=" crossorigin>
<link rel="preload stylesheet" as="style" href="https://cdnjs.cloudflare.com/ajax/libs/10up-sanitize.css/11.0.1/typography.min.css" integrity="sha256-7l/o7C8jubJiy74VsKTidCy1yBkRtiUGbVkYBylBqUg=" crossorigin>
<link rel="stylesheet preload" as="style" href="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/10.1.1/styles/github.min.css" crossorigin>
<style>:root{--highlight-color:#fe9}.flex{display:flex !important}body{line-height:1.5em}#content{padding:20px}#sidebar{padding:30px;overflow:hidden}#sidebar > *:last-child{margin-bottom:2cm}.http-server-breadcrumbs{font-size:130%;margin:0 0 15px 0}#footer{font-size:.75em;padding:5px 30px;border-top:1px solid #ddd;text-align:right}#footer p{margin:0 0 0 1em;display:inline-block}#footer p:last-child{margin-right:30px}h1,h2,h3,h4,h5{font-weight:300}h1{font-size:2.5em;line-height:1.1em}h2{font-size:1.75em;margin:1em 0 .50em 0}h3{font-size:1.4em;margin:25px 0 10px 0}h4{margin:0;font-size:105%}h1:target,h2:target,h3:target,h4:target,h5:target,h6:target{background:var(--highlight-color);padding:.2em 0}a{color:#058;text-decoration:none;transition:color .3s ease-in-out}a:hover{color:#e82}.title code{font-weight:bold}h2[id^="header-"]{margin-top:2em}.ident{color:#900}pre code{background:#f8f8f8;font-size:.8em;line-height:1.4em}code{background:#f2f2f1;padding:1px 4px;overflow-wrap:break-word}h1 code{background:transparent}pre{background:#f8f8f8;border:0;border-top:1px solid #ccc;border-bottom:1px solid #ccc;margin:1em 0;padding:1ex}#http-server-module-list{display:flex;flex-flow:column}#http-server-module-list div{display:flex}#http-server-module-list dt{min-width:10%}#http-server-module-list p{margin-top:0}.toc ul,#index{list-style-type:none;margin:0;padding:0}#index code{background:transparent}#index h3{border-bottom:1px solid #ddd}#index ul{padding:0}#index h4{margin-top:.6em;font-weight:bold}@media (min-width:200ex){#index .two-column{column-count:2}}@media (min-width:300ex){#index .two-column{column-count:3}}dl{margin-bottom:2em}dl dl:last-child{margin-bottom:4em}dd{margin:0 0 1em 3em}#header-classes + dl > dd{margin-bottom:3em}dd dd{margin-left:2em}dd p{margin:10px 0}.name{background:#eee;font-weight:bold;font-size:.85em;padding:5px 10px;display:inline-block;min-width:40%}.name:hover{background:#e0e0e0}dt:target .name{background:var(--highlight-color)}.name > span:first-child{white-space:nowrap}.name.class > span:nth-child(2){margin-left:.4em}.inherited{color:#999;border-left:5px solid #eee;padding-left:1em}.inheritance em{font-style:normal;font-weight:bold}.desc h2{font-weight:400;font-size:1.25em}.desc h3{font-size:1em}.desc dt code{background:inherit}.source summary,.git-link-div{color:#666;text-align:right;font-weight:400;font-size:.8em;text-transform:uppercase}.source summary > *{white-space:nowrap;cursor:pointer}.git-link{color:inherit;margin-left:1em}.source pre{max-height:500px;overflow:auto;margin:0}.source pre code{font-size:12px;overflow:visible}.hlist{list-style:none}.hlist li{display:inline}.hlist li:after{content:',\2002'}.hlist li:last-child:after{content:none}.hlist .hlist{display:inline;padding-left:1em}img{max-width:100%}td{padding:0 .5em}.admonition{padding:.1em .5em;margin-bottom:1em}.admonition-title{font-weight:bold}.admonition.note,.admonition.info,.admonition.important{background:#aef}.admonition.todo,.admonition.versionadded,.admonition.tip,.admonition.hint{background:#dfd}.admonition.warning,.admonition.versionchanged,.admonition.deprecated{background:#fd4}.admonition.error,.admonition.danger,.admonition.caution{background:lightpink}</style>
<style media="screen and (min-width: 700px)">@media screen and (min-width:700px){#sidebar{width:30%;height:100vh;overflow:auto;position:sticky;top:0}#content{width:70%;max-width:100ch;padding:3em 4em;border-left:1px solid #ddd}pre code{font-size:1em}.item .name{font-size:1em}main{display:flex;flex-direction:row-reverse;justify-content:flex-end}.toc ul ul,#index ul{padding-left:1.5em}.toc > ul > li{margin-top:.5em}}</style>
<style media="print">@media print{#sidebar h1{page-break-before:always}.source{display:none}}@media print{*{background:transparent !important;color:#000 !important;box-shadow:none !important;text-shadow:none !important}a[href]:after{content:" (" attr(href) ")";font-size:90%}a[href][title]:after{content:none}abbr[title]:after{content:" (" attr(title) ")"}.ir a:after,a[href^="javascript:"]:after,a[href^="#"]:after{content:""}pre,blockquote{border:1px solid #999;page-break-inside:avoid}thead{display:table-header-group}tr,img{page-break-inside:avoid}img{max-width:100% !important}@page{margin:0.5cm}p,h2,h3{orphans:3;widows:3}h1,h2,h3,h4,h5,h6{page-break-after:avoid}}</style>
<script defer src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/10.1.1/highlight.min.js" integrity="sha256-Uv3H6lx7dJmRfRvH8TH6kJD1TSK1aFcwgx+mdg3epi8=" crossorigin></script>
<script>window.addEventListener('DOMContentLoaded', () => hljs.initHighlighting())</script>
</head>
<body>
<main>
<article id="content">
<header>
<h1 class="title">Module <code>pluginconf.bind</code></h1>
</header>
<section id="section-intro">
<p>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.</p>
<h3 id="usage-example">Usage example</h3>
<pre><code># 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()
</code></pre>
<h3 id="find-by-type">Find by type</h3>
<pre><code>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)
</code></pre>
<p>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 <code><a title="pluginconf.gui.window" href="gui.html#pluginconf.gui.window">window()</a></code> usage.)</p>
<hr>
<p>Method interactions: ๐ = import, ๐งฉ = meta, ๐งพ = config, ๐
= setup</p>
</section>
<section>
</section>
<section>
</section>
<section>
<h2 class="section-title" id="header-functions">Functions</h2>
<dl>
<dt id="pluginconf.bind.base"><code class="name flex">
<span>def <span class="ident">base</span></span>(<span>module, path=None)</span>
</code></dt>
<dd>
<div class="desc"><p>Register module as package/plugin_base. Or expand its search path ๐ .</p>
<h2 id="parameters">Parameters</h2>
<dl>
<dt><strong><code>module</code></strong> : <code>module/str</code></dt>
<dd>The package basename to later load plugins from (must be a package,
like <code>plugins/__init__.py</code>, or be tied to a path= or zip). Ideally
this module was already imported in main. But parameter may be a string.</dd>
<dt><strong><code>path</code></strong> : <code>str</code></dt>
<dd>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 <code>__path__</code> in the
base <code>package/__init__.py</code>.)</dd>
</dl></div>
</dd>
<dt id="pluginconf.bind.defaults"><code class="name flex">
<span>def <span class="ident">defaults</span></span>(<span>conf)</span>
</code></dt>
<dd>
<div class="desc"><p>Traverse installed plugins and expand config dict with presets ๐งฉ ๐งพ</p>
<h2 id="parameters">Parameters</h2>
<dl>
<dt><strong><code>conf</code></strong> : <code>dict ๐</code></dt>
<dd>Expands the top-level config dict with preset values from any plugins.</dd>
</dl></div>
</dd>
<dt id="pluginconf.bind.find"><code class="name flex">
<span>def <span class="ident">find</span></span>(<span>**kwargs)</span>
</code></dt>
<dd>
<div class="desc"><p>Find plugins by e.g. type= or category= ๐งฉ</p>
<h2 id="parameters">Parameters</h2>
<dl>
<dt><strong><code>type</code></strong> : <code>str</code></dt>
<dd>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.)</dd>
</dl>
<h2 id="returns">Returns</h2>
<dl>
<dt><strong><code>dict</code></strong> : <code>basename โ PluginMeta dict</code></dt>
<dd> </dd>
</dl></div>
</dd>
<dt id="pluginconf.bind.load"><code class="name flex">
<span>def <span class="ident">load</span></span>(<span>name)</span>
</code></dt>
<dd>
<div class="desc"><p>Import individual plugin from any of the base paths ๐</p>
<h2 id="parameters">Parameters</h2>
<dl>
<dt><strong><code>name</code></strong> : <code>str</code></dt>
<dd>Plugin name in any of the registered plugin_baseยดs. (The whole
namespace is assumed to be flat, and identifiers to be unique.)</dd>
</dl></div>
</dd>
<dt id="pluginconf.bind.load_enabled"><code class="name flex">
<span>def <span class="ident">load_enabled</span></span>(<span>conf)</span>
</code></dt>
<dd>
<div class="desc"><p>Import modules that are enabled in conf[plugins]={name:True,โฆ} ๐งพ ๐</p>
<h2 id="parameters">Parameters</h2>
<dl>
<dt><strong><code>conf</code></strong> : <code>dict</code></dt>
<dd>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.</dd>
</dl></div>
</dd>
</dl>
</section>
<section>
<h2 class="section-title" id="header-classes">Classes</h2>
<dl>
<dt id="pluginconf.bind.isolated"><code class="flex name class">
<span>class <span class="ident">isolated</span></span>
<span>(</span><span>package)</span>
</code></dt>
<dd>
<div class="desc"><p>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.</p>
<pre><code>with pluginconf.bind.isolated("libplugins") as bound:
bound.modules2.init()
print(
bound.find(api="library")
)
</code></pre></div>
<h3>Static methods</h3>
<dl>
<dt id="pluginconf.bind.isolated.defaults"><code class="name flex">
<span>def <span class="ident">defaults</span></span>(<span>)</span>
</code></dt>
<dd>
<div class="desc"><p><em>return</em> defaults for isolated plugin structure ๐งฉ ๐งพ</p></div>
</dd>
<dt id="pluginconf.bind.isolated.find"><code class="name flex">
<span>def <span class="ident">find</span></span>(<span>**kwargs)</span>
</code></dt>
<dd>
<div class="desc"><p>find by meta attributes ๐งฉ</p></div>
</dd>
<dt id="pluginconf.bind.isolated.load"><code class="name flex">
<span>def <span class="ident">load</span></span>(<span>name)</span>
</code></dt>
<dd>
<div class="desc"><p>load module from wrapped package ๐</p></div>
</dd>
</dl>
<h3>Methods</h3>
<dl>
<dt id="pluginconf.bind.isolated.get_data"><code class="name flex">
<span>def <span class="ident">get_data</span></span>(<span>self, *args, **kwargs)</span>
</code></dt>
<dd>
<div class="desc"><p>get file relative to encapsulated plugins ๐</p></div>
</dd>
</dl>
</dd>
</dl>
</section>
</article>
<nav id="sidebar">
<h1>Index</h1>
<div class="toc">
<ul>
<li><a href="#usage-example">Usage example</a></li>
<li><a href="#find-by-type">Find by type</a></li>
</ul>
</div>
<ul id="index">
<li><h3>Super-module</h3>
<ul>
<li><code><a title="pluginconf" href="index.html">pluginconf</a></code></li>
</ul>
</li>
<li><h3><a href="#header-functions">Functions</a></h3>
<ul class="">
<li><code><a title="pluginconf.bind.base" href="#pluginconf.bind.base">base</a></code></li>
<li><code><a title="pluginconf.bind.defaults" href="#pluginconf.bind.defaults">defaults</a></code></li>
<li><code><a title="pluginconf.bind.find" href="#pluginconf.bind.find">find</a></code></li>
<li><code><a title="pluginconf.bind.load" href="#pluginconf.bind.load">load</a></code></li>
<li><code><a title="pluginconf.bind.load_enabled" href="#pluginconf.bind.load_enabled">load_enabled</a></code></li>
</ul>
</li>
<li><h3><a href="#header-classes">Classes</a></h3>
<ul>
<li>
<h4><code><a title="pluginconf.bind.isolated" href="#pluginconf.bind.isolated">isolated</a></code></h4>
<ul class="">
<li><code><a title="pluginconf.bind.isolated.defaults" href="#pluginconf.bind.isolated.defaults">defaults</a></code></li>
<li><code><a title="pluginconf.bind.isolated.find" href="#pluginconf.bind.isolated.find">find</a></code></li>
<li><code><a title="pluginconf.bind.isolated.get_data" href="#pluginconf.bind.isolated.get_data">get_data</a></code></li>
<li><code><a title="pluginconf.bind.isolated.load" href="#pluginconf.bind.isolated.load">load</a></code></li>
</ul>
</li>
</ul>
</li>
</ul>
</nav>
</main>
<footer id="footer">
<p>Generated by <a href="https://pdoc3.github.io/pdoc" title="pdoc: Python API documentation generator"><cite>pdoc</cite> 0.10.0</a>.</p>
</footer>
</body>
</html>