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
Fly DCS without a joystick

Intro Usage Delete all mouse view axis Install DCSEasyControlExports to your "Saved Games/DCS/" Path python DCSEasyControl/main.py Set DCS to F12 view

XuHao 36 Dec 27, 2022
A compiler for ARM, X86, MSP430, xtensa and more implemented in pure Python

Introduction The PPCI (Pure Python Compiler Infrastructure) project is a compiler written entirely in the Python programming language. It contains fro

Windel Bouwman 277 Dec 26, 2022
peace-performance (Rust) binding for python. To calculate star ratings and performance points for all osu! gamemodes

peace-performance-python Fast, To calculate star ratings and performance points for all osu! gamemodes peace-performance (Rust) binding for python bas

9 Sep 19, 2022
Graphene Metanode is a locally hosted node for one account and several trading pairs, which uses minimal RAM resources.

Graphene Metanode is a locally hosted node for one account and several trading pairs, which uses minimal RAM resources. It provides the necessary user stream data and order book data for trading in a

litepresence 5 May 08, 2022
Web App for University Project

University Project About I made this web app to finish a project assigned by my teacher. It is written entirely in Python, thanks to streamlit to make

15 Nov 27, 2022
Zotero references script (and app)

A little script (and PyInstaller build) for a very specific, somewhat hack-ish purpose: managing and exporting project references with Zotero and its API.

Marius Rödder 0 Dec 05, 2021
This Python script can enumerate all URLs present in robots.txt files, and test whether they can be accessed or not.

Robots.txt tester With this script, you can enumerate all URLs present in robots.txt files, and test whether you can access them or not. Setup Clone t

Podalirius 32 Oct 10, 2022
HiQ - A Modern Observability System

🦉 A Modern Observability System HiQ is a declarative, non-intrusive, dynamic and transparent tracking system for both monolithic application and dist

Oracle Sample Code 40 Aug 21, 2022
Pokemon catch events project to demonstrate data pipeline on AWS

Pokemon Catches Data Pipeline This is a sample project to practice end-to-end data project; Terraform is used to deploy infrastructure; Kafka is the t

Vitor Carra 4 Sep 03, 2021
Scrapper For Paste.pics

PrntScScrapper Scrapper for Paste.pics If you are bored you can find some random screenshots from prnt.sc Features Saving screenshots Open in Browser

Fareusz 1 Dec 29, 2021
A complex language with high level programming and moderate syntax.

zsq a complex language with high level programming and moderate syntax.

an aspirin 6 Jun 25, 2022
In this project, we are going to display the battery notification and the time left for the battery to drain out using the battery capacity value.

In this project, we are going to display the battery notification and the time left for the battery to drain out using the battery capacity value.

Ritoban Biswas 1 Dec 20, 2021
Audio-analytics for music-producers! Automate tedious tasks such as musical scale detection, BPM rate classification and audio file conversion.

Click here to be re-directed to the Beat Inspect Streamlit Web-App You are a music producer? Let's get in touch via LinkedIn Fundamental Analytics for

Stefan Rummer 11 Dec 27, 2022
You'll learn about Iterators, Generators, Closure, Decorators, Property, and RegEx in detail with examples.

07_Python_Advanced_Topics Introduction 👋 In this tutorial, you will learn about: Python Iterators: They are objects that can be iterated upon. In thi

Milaan Parmar / Милан пармар / _米兰 帕尔马 252 Dec 23, 2022
Simple python code for compile brainfuck program.

py-brainf*ck Just a basic compiled that compiles your brainf*ck codes and gives you informations about memory, used cells, dumped version, logs etc...

4 Jun 13, 2021
Freeze your objects in python

gelidum Freeze your objects in python. Latin English Caelum est hieme frigidum et gelidum; myrtos oleas quaeque alia assiduo tepore laetantur, asperna

Diego J. 51 Dec 22, 2022
nbsafety adds a layer of protection to computational notebooks by solving the stale dependency problem when executing cells out-of-order

nbsafety adds a layer of protection to computational notebooks by solving the stale dependency problem when executing cells out-of-order

150 Jan 07, 2023
A Powerful Tool For Making Combo List(All possible modes)

ComboMaker A Powerful Tool For Making Combo List Introduction Check out all possible Combo list build modes with this tool =) How to Install Open the

MasterBurnt 7 Jan 07, 2023
To check my COVID-19 vaccine appointment, I wrote an infinite loop that sends me a Whatsapp message hourly using Twilio and Selenium. It works on my Raspberry Pi computer.

COVID-19_vaccine_appointment To check my COVID-19 vaccine appointment, I wrote an infinite loop that sends me a Whatsapp message hourly using Twilio a

Ayyuce Demirbas 24 Dec 17, 2022
An animal facts python module

An animal facts python module

Fayas Noushad 3 Dec 19, 2021