-
-
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)
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/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() |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# -*- 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) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# -*- 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') | |
''' |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
@dwich see my gitter explanation.
Or, you can use the setuptools entry points system natively supported in
pluggy
.Hope that helps 👍