Plugin handling system¶
version: | 0.1.1 |
---|---|
author: | Luca De Vitis <luca at monkeython.com> |
contact: | http://www.monkeython.com |
copyright: | Copyright (c) 2014, Luca De Vitis <luca at monkeython.com> |
All rights reserved.
Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
Overview¶
(Spelled like multiplug) The purpose of this module is to provide a dead simple plugin handler module. I wanted something:
- Capable of handling multiple plugins (and that’s pretty obvious)
- Capable of handling multiple implementation of the same plugin
- Capable of handling multiple
pkg_resources.WorkingSet
-s... by itself - Easy to initialize in your pluggable application/framework.
I wanted somthing like:
content_types = multipla.power_up('scriba.content_types')
def to_json(object):
content_type = content_types.get('application/json')
return content_type.format(ojbect)
def to_user_supplied_type(object, content_type):
return content_types.get(content_type).format(object)
or:
from loremipsum import generator
import multipla
samples = multipla.power_up('loremipsum.samples')
vaporware = generator.Generator(samples.get('vaporware'))
You can read more on Pythonhosted or Read the Docs. Since this package has en extensive docstring documentation as well as code comments, you can read more browsing the source code or in the python interactive shell.
Changes¶
- 0.1.0
- Added
RatedDict.ratings
method to read item ratings values.
- Added
- 0.0.4
- API refactoring.
- 0.0.2
- API refactoring.
- 0.0.1
- Pre-Alpha release.
Basic Usage¶
-
power_up
(name, *args)¶ Creates and returns a rated dictionary of plugins.
Parameters: - name (str) – The multi-plug name (i.e. entry point group).
- args – Variable argument list of
pkg_resources.WorkingSet
.
Return type: I meant to have just one
Multipla
instances for each group of entry points. They are powered up by subscribing (as perpkg_resources.WorkingSet.subscribe()
) to eachpkg_resources.WorkingSet
in the variable argument list. If no extra argument is provided, (default)pkg_resources.working_set
is used. Subscription causes theMultipla
instance to register any plugin in the givenpkg_resources.WorkingSet
, and let it be notified of any plugin that will be added in the future. Subscribing aMultipla
twice (or more) to the samepkg_resources.WorkingSet
neither add any overhead, nor makes the instance to register a give plugin more than once, so it’s safer to use this function as the only module interface.>>> import multipla >>> >>> multipla.power_up('plugin_group') <Multipla 'plugin_group'> >>> >>> plugin_group = multipla.power_up('plugin_group') >>> plugin_group is multipla.power_up('plugin_group') True >>> isinstance(plugin_group, multipla.Multipla) True
Advanced Usage¶
-
class
Multipla
(name)¶ The power strip to put yout plugs into.
Parameters: name – The name of the power strip (i.e. the entry point group). This class represents the plugin group. Since this class inherits from
RatedDict
, it’s possible to use it almost as a dictionary, and also rate your plugin names. Each item in an instance of this class is an instance ofMultiPlugAdapter
, actually, so you can use more implementation of a given plugin name. On the average you want to use the higest rated implementation trough theMultipla.get()
method, but you can also use the dictionary item access syntax to reach for all the implementations a achieve your goal.-
get
(name, default=None)¶ Get the higest rated
plug
for the given plugname
.Parameters: - name – The plugin name.
- default – The default value to return if lookup fails.
Returns: The highest rated plugin.
Raises: - KeyError – If
name
lookup fails. - ValueError – See
RatedDict.highest_rated
.
-
switch_on
(name)¶ Switch on a socket.
Parameters: name (str) – The socket (entry point) name. Returns: The MultiPlugAdapter
associated with thename
.If the specified
MultiPlugAdapter
already exists, it is returned. If there is noMultiPlugAdapter
for the specified plugin name, a new one is created and returned.
-
-
class
MultiPlugAdapter
(name)¶ The multi-plug adapter that holds all the plugin implementations.
Parameters: name – The name of the plug adapter (i.e. the name of the entry point). This class represents all the plugins that implement the give entry point name. Since this class inherit from
RatedDict
, it’s possible to rate each implementation. Thepkg_resources
classes allows each distribution to provide their own implementation of a given plugin name: for example, 2 distributions might provide the sameYAML
serialization functions, but each using a differentYAML
library.-
plug_in
(name, plug)¶ Try to plug an object in.
Parameters: - name (str) – The
plug
implementation name. - plug – The object to plug in.
Raises KeyError: If another object with the same
name
is already plugghed in.If you want to explicitly overrid a plug implementation, you must use dictionary item setting syntax.
- name (str) – The
-
-
class
RatedDict
¶ A
dict
-like class that lets you to rate its objects.This implementation is meant to be thread-safe. Actually, it only supports the following
dict
-like methods:__setitem__
,__getitem__
,__delitem__
__contains__
,__len__
__iter__
,__reversed__
__str__
update
-
rate
(updates=(), **args)¶ Rate the items into the dictionary.
Parameters: - updates – A
key: rating
dictionary or an iterable yielding(key, rating)
. - args (dict) – Anyway, variable keyword arguments
args
will be used to update the item ratings.
Raises KeyError: If unexpected keys are found.
This method behave like the
dict.update()
, but affects only items ratings. At the end of the update, dictionary keys are sorted by rating, from greater to lower rating value. Rating is supposed to be any kind of number equal or greater than 0. Default item rating is 0.- updates – A
-
top
(amount=None)¶ Returns the top rated items.
Parameters: amount (int) – The number of items to return. Defaults to all items. Returns: A list of key
-value
pairs, sorted by key ratings.Raises ValueError: If amount
is greater than the available items.
-
highest_rated
¶ The value of the highest rated item.
Raises ValueError: If container is empty.
-
ratings
¶ Iterator over
key
-rate
pairs, sorted byrate
.