Skip to content

Instantly share code, notes, and snippets.

@dwich

dwich/app.py Secret

Last active May 18, 2019 22:12
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save dwich/401e76aec27b832b1b1fe30f83816e11 to your computer and use it in GitHub Desktop.
Save dwich/401e76aec27b832b1b1fe30f83816e11 to your computer and use it in GitHub Desktop.
Using pluggy without importing anything from host application (the one I'm extending)
#!/usr/bin/env python
# -*- coding: UTF-8 -*-
'''
My application uses authentication from my framework
My application also extends framework using a plugin defined in plug.py
Everything works fine. But the plugin needs to import the host app (framework)
or maybe I'm missing something.
'''
import framework
import plug
if __name__ == '__main__':
plug.setup_plugin()
auth = framework.Authenticate()
auth.authenticate()
# -*- coding: UTF-8 -*-
'''
Framework provides simple functionality - authentication
which has one hook point - before_authenticate()
'''
import pluggy
plug_name = 'myapp'
hookspec = pluggy.HookspecMarker(plug_name)
hookimpl = pluggy.HookimplMarker(plug_name)
plug_mgr = pluggy.PluginManager(plug_name)
class PluginSpec(object):
@hookspec
def before_authenticate(self, param1):
'''Hook that can be customized.'''
plug_mgr.add_hookspecs(PluginSpec())
class Authenticate(object):
def authenticate(self):
print('APP: calling plugins before_authenticate()')
results = plug_mgr.hook.before_authenticate(param1='value1')
print('APP: results from plugins:', results)
# -*- coding: UTF-8 -*-
import framework
class AuthPlugin1(object):
@framework.hookimpl
def before_authenticate(self, param1):
print('PLUGIN 1: before_authenticate(), param: {}'.format(param1))
return 'before_1'
def setup_plugin():
# To register a plugin, I need a direct access to PluginManager instance.
# Therefore I need to import it from framework:
pm = framework.plug_mgr
# However, if there was a way to get PluginManager instance for example
# like python logging returns loggers: mylog = logging.getLogger('mylog')
# then I could do something like:
# import pluggy
# pm = pluggy.get_pluggin_manager('myapp')
# without importing framework I'm extending
# and then:
pm.register(AuthPlugin1())
'''
This also leads me to thoughts - if I want to write a plugin without importing
the host application (the framework in my case), I need a PluginManager
instance and hookimpl decorator as well.
To define a plugin something like these functions would be needed:
plug_mgr = pluggy.get_pluggin_manager('myapp')
and
hookimpl = pluggy.get_hookimpl_marker('myapp')
'''
@goodboy
Copy link

goodboy commented May 18, 2019

@dwich see my gitter explanation.

if I want to write a plugin without importing
the host application (the framework in my case), I need a PluginManager
instance and hookimpl decorator as well.

Or, you can use the setuptools entry points system natively supported in pluggy.

Hope that helps 👍

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment