A simple but flexible plugin system for Python.

Overview

PluginBase

PluginBase is a module for Python that enables the development of flexible plugin systems in Python.

Step 1:

from pluginbase import PluginBase
plugin_base = PluginBase(package='yourapplication.plugins')

Step 2:

plugin_source = plugin_base.make_plugin_source(
    searchpath=['./path/to/plugins', './path/to/more/plugins'])

Step 3:

with plugin_source:
    from yourapplication.plugins import my_plugin
my_plugin.do_something_cool()

Or alternatively:

my_plugin = plugin_source.load_plugin('my_plugin')
my_plugin.do_something_cool()
Comments
  • PluginBase causes ImportError in PyYAML

    PluginBase causes ImportError in PyYAML

    PluginBase seems to break PyYAML, causing ImportErrors on import.
    I'm using the latest version of PyYAML (3.11) and PluginBase.
    Tested on OS X and Linux.

    Importing PluginBase first causes errors:

    Python 2.7.3 (default, Mar 18 2014, 05:13:23) 
    [GCC 4.6.3] on linux2
    Type "help", "copyright", "credits" or "license" for more information.
    >>> import pluginbase
    >>> import yaml
    Traceback (most recent call last):
      File "<stdin>", line 1, in <module>
      File "/usr/local/lib/python2.7/dist-packages/pluginbase.py", line 404, in plugin_import
        fromlist, level)
      File "/usr/local/lib/python2.7/dist-packages/yaml/__init__.py", line 2, in <module>
        from error import *
      File "/usr/local/lib/python2.7/dist-packages/pluginbase.py", line 404, in plugin_import
        fromlist, level)
    ImportError: No module named error
    

    Importing YAML first works fine:

    Python 2.7.3 (default, Mar 18 2014, 05:13:23) 
    [GCC 4.6.3] on linux2
    Type "help", "copyright", "credits" or "license" for more information.
    >>> import yaml
    >>> import pluginbase
    
    bug 
    opened by cesarvandevelde 13
  • Error when exiting a program

    Error when exiting a program

    Exception ignored in: <bound method PluginSource.__del__ of <pluginbase.PluginSource object at 0x7f1a4e229be0>>
    Traceback (most recent call last):
      File "/usr/lib/python3.4/site-packages/pluginbase.py", line 247, in __del__
      File "/usr/lib/python3.4/site-packages/pluginbase.py", line 303, in cleanup
      File "/usr/lib/python3.4/site-packages/pluginbase.py", line 318, in __cleanup
    TypeError: unsupported operand type(s) for +: 'NoneType' and 'str'
    
    bug 
    opened by garncarz 9
  • KeyError warning when sys.modules is empty as PluginSource.cleanup is called

    KeyError warning when sys.modules is empty as PluginSource.cleanup is called

    Not sure of the exact cause yet, but running the following source on python 3.4:

    from pluginbase import PluginBase
    a_base = PluginBase('some')
    a_source = a_base.make_plugin_source(searchpath=['.'])
    
    import asyncio
    
    @asyncio.coroutine
    def what():
        return
    

    results in the following warning being displayed:

    Exception ignored in: <bound method PluginSource.__del__ of <pluginbase.PluginSource object at 0x021F0AF0>>
    Traceback (most recent call last):
      File "d:\python34\lib\site-packages\pluginbase.py", line 247, in __del__
      File "d:\python34\lib\site-packages\pluginbase.py", line 303, in cleanup
      File "d:\python34\lib\site-packages\pluginbase.py", line 319, in __cleanup
    KeyError: ('pluginbase._internalspace._spf57aab93650650e4c1433e9cb9bd5a38',)
    

    Could potentially be fixed by adding a default None to the _sys.modules.pop() call causing the KeyError.

    bug 
    opened by htoothrot 6
  • Loading recursion depth

    Loading recursion depth

    Would it be possible to add a recursion depth for the search path?

    my_program.py
    plugins
        - plugin 1
            - foo.py
            - bar.py
        - plugin 2
            - foobar.py
    

    Currently I am scanning plugins with os.listdir, and searchpathing each. Having a recursion depth would be great.

    question 
    opened by Kamik423 4
  • conflict fix with random module

    conflict fix with random module

    Raises "AttributeError: 'module' object has no attribute 'choice'" on python2 (2.7.10) because module name (of random plugin) conflicts with python's random module.

    bug 
    opened by talhasch 4
  • pluginbase cause import error in pyvirtualdisplay: ImportError: No module named display

    pluginbase cause import error in pyvirtualdisplay: ImportError: No module named display

    from pyvirtualdisplay import Display
      File "/Users/dev/.virtualenvs/kraken-32/lib/python2.7/site-packages/pluginbase.py", line 404, in plugin_import
        fromlist, level)
      File "/Users/dev/.virtualenvs/kraken-32/lib/python2.7/site-packages/pyvirtualdisplay/__init__.py", line 1, in <module>
        from display import Display
      File "/Users/dev/.virtualenvs/kraken-32/lib/python2.7/site-packages/pluginbase.py", line 404, in plugin_import
        fromlist, level)
    ImportError: No module named display
    
    bug duplicate 
    opened by garywu 4
  • list_plugins method drops the modules with same name from different plugin directory

    list_plugins method drops the modules with same name from different plugin directory

    The modules with same names in different plugin directory won't be returned in list_plugins.

    Here is my case, I have a plugins directory structure like this,

    plugins
    ├── __init__.py
    ├── builtin
    │   ├── __init__.py
    │   ├── logger
    │   │   ├── __init__.py
    │       ├── setup.py
    │   │   └── logger.py
    ├── device
    │   ├── __init__.py
    │   ├── setup.py
    

    Expect

    The list_plugins returns all the module names including those with the same name and could be load_plugin correctly. ['logger', 'setup', 'setup']

    Actual

    The list_plugins returns all the unique names only and could be load_plugin correctly. ['logger', 'setup']

    Code

    plugin_base = PluginBase(package='app.plugins',
                                searchpath=[get_path('plugins/builtin')])
    
    source = plugin_base.make_plugin_source(
        searchpath=[get_path('./plugins/%s/' % name)],
        identifier=self.name)
    print source.list_plugins()
    
    opened by xingheng 3
  • DeprecationWarning in pluginbase.py line 439

    DeprecationWarning in pluginbase.py line 439

    c:\python\python37\lib\site-packages\pluginbase.py:439: DeprecationWarning: the imp module is deprecated in favour of importlib; see the module's documentation for alternative uses

    bug invalid 
    opened by awlosnie 2
  • get_searchpath function corrected for recursive directories retrieval

    get_searchpath function corrected for recursive directories retrieval

    get_searchpath method(in pluginbase.py) is not returning all the sub-directories in the given path.This fix gives the subdirectories as well. For example , for the below directory structure, the current code in get_searchpath is not returning all the sub-directories. app1

    • app2 -test2.py
    • test1.py app3 -app4
      • test4.py
    • test3.py

    It has been fixed in this commit.

    bug 
    opened by avinashraghuthu 2
  • list_plugins() displaying each plugin twice, but I'm probably mistaken about something

    list_plugins() displaying each plugin twice, but I'm probably mistaken about something

    $ tree -I 'venv|.git|__pycache__'
    .
    ├── app.py
    └── sources
        ├── one.py
        └── two.py
    
    from pluginbase import PluginBase
    
    plugin_base = PluginBase(package='app.sources')
    plugin_source = plugin_base.make_plugin_source(searchpath=['./sources'])
    
    for plugin_name in plugin_source.list_plugins():
        print(plugin_name)
    

    And when running app.py, I see:

    :!/usr/bin/env python app.py
    one
    two
    one
    two
    

    If you could kindly point out the error I'm most definitely making, that'd be cool.

    question 
    opened by shmup 2
  • importerror: util

    importerror: util

    when I have:

    from pluginbase import PluginBase
    from pyechonest import config
    from pyechonest import song
    

    I get

    Traceback (most recent call last):
      File "partyled.py", line 9, in <module>
        from pyechonest import song
      File "/usr/local/lib/python2.7/site-packages/pluginbase.py", line 404, in plugin_import
        fromlist, level)
      File "build/bdist.macosx-10.10-x86_64/egg/pyechonest/song.py", line 12, in <module>
      File "/usr/local/lib/python2.7/site-packages/pluginbase.py", line 404, in plugin_import
        fromlist, level)
    ImportError: No module named util
    

    however if I change the order to

    from pyechonest import config
    from pyechonest import song
    from pluginbase import PluginBase
    

    things work fine. Given the order in which things override, I'm inclined to suspect of PluginBase of doing something weird here.

    bug duplicate 
    opened by tacoe 2
Releases(1.0.0)
Owner
Armin Ronacher
Software developer and Open Source nut. Creator of the Flask framework. Engineering at @getsentry. Other things of interest: @pallets and @rust-lang
Armin Ronacher
This repository can help you made a PocketMine-MP Server with Termux apps!

Hello This GitHub repository can made you a Server PocketMine-MP On development! How to Install Open Termux Type "pkg install git && python" If python

1 Mar 04, 2022
Tugas kelompok Struktur Data

Binary-Tree Tugas kelompok Struktur Data Silahkan jika ingin mengubah tipe data pada operasi binary tree *Boleh juga semua program kelompok bisa disat

Usmar manalu 2 Nov 28, 2022
Randomly distribute members by groups making sure that every sector is represented

Generate Groups Randomly distribute members by groups making sure that every sector is represented The Scenario Imagine that you have a large group of

Jorge Gomes 1 Oct 22, 2021
RISE allows you to instantly turn your Jupyter Notebooks into a slideshow

RISE RISE allows you to instantly turn your Jupyter Notebooks into a slideshow. No out-of-band conversion is needed, switch from jupyter notebook to a

Damian Avila 3.4k Jan 04, 2023
Ingest openldap data into bloodhound

Bloodhound for Linux Ingest a dumped OpenLDAP ldif into neo4j to be visualized in Bloodhound. Usage: ./ldif_to_neo4j.py ./sample.ldif | cypher-shell -

Guillaume Quéré 71 Nov 09, 2022
The goal of this program was to find the most common color in my living room.

The goal of this program was to find the most common color in my living room. I found a dataset online with colors names and their corr

1 Nov 09, 2021
This is a pretty basic but relatively nice looking Python Pomodoro Timer.

Python Pomodoro-Timer This is a pretty basic but relatively nice looking Pomodoro Timer. Currently its set to a very basic mode, but the funcationalit

EmmHarris 2 Oct 18, 2021
Customisable coding font with alternates, ligatures and contextual positioning

Guide Ligature Support Links Log License Guide Live Preview + Download larsenwork.com/monoid Install Quit your editor/program. Unzip and open the fold

Andreas Larsen 7.6k Dec 30, 2022
Dotfiles & list of programs

dotfiles & list of programs So I wanted to just backup my most used files. I have a bad habit, sometimes I get tired of a distro and do a wipe and sta

2 Sep 04, 2022
Unofficial Python Library to communicate with SESAME 3 series products from CANDY HOUSE, Inc.

pysesame3 Unofficial Python Library to communicate with SESAME 3 series products from CANDY HOUSE, Inc. This project aims to control SESAME 3 series d

Masaki Tagawa 18 Dec 12, 2022
The learning agent learns firstly approaching to the football and then kicking the football to the target position

Football Court This project utilized Pytorch and Tensorflow so that the learning agent learns firstly approaching to the football and then kicking the

1 Nov 19, 2021
Metal Gear Rising: Revengeance's DAT archive (un)packer

DOOMP Metal Gear Rising: Revengeance's DAT archive (un)packer

Christopher Holzmann Pérez 5 Sep 02, 2022
Snakemake worflow to process and filter long read data from Oxford Nanopore Technologies.

Nanopore-Workflow Snakemake workflow to process and filter long read data from Oxford Nanopore Technologies. It is designed to compare whole human gen

5 May 13, 2022
This is a practice on Airflow, which is building virtual env, installing Airflow and constructing data pipeline (DAGs)

airflow-test This is a practice on Airflow, which is Builing virtualbox env and setting Airflow on that env Installing Airflow using python virtual en

Jaeyoung 1 Nov 01, 2021
Terrible sudoku solver with spaghetti code and performance issues

SudokuSolver Terrible sudoku solver with spaghetti code and performance issues - if it's unable to figure out next step it will stop working, it never

Kamil Bizoń 1 Dec 05, 2021
Project aims to map out common user behavior on the computer

User-Behavior-Mapping-Tool Project aims to map out common user behavior on the computer. Most of the code is based on the research by kacos2000 found

trustedsec 136 Dec 23, 2022
Multi View Stereo on Internet Images

Evaluating MVS in a CPC Scenario This repository contains the set of artficats used for the ENGN8601/8602 research project. The thesis emphasizes on t

Namas Bhandari 1 Nov 10, 2021
Cute study buddy that helps you study with the Pomodoro technique!

study-buddy Cute study buddy that helps you study with the Pomodoro (or Animedoro) technique! Kirby The Kirby folder has a Kirby, pink-themed Pomodoro

Ethan Emmanuel 1 Jan 19, 2022
pythonOS: An operating system kernel made in python and assembly

pythonOS An operating system kernel made in python and assembly Wait what? It uses a custom compiler called snek that implements a part of python3.9 (

Abbix 69 Dec 23, 2022
Type Persian without confusing words for yourself and others, in Adobe Connect

About In the Adobe Connect chat section, to type in Persian or Arabic, the written words will be confused and will be written and sent illegibly (This

Matin Najafi 23 Nov 26, 2021