Plugins through Entry Points
This approach is based on Advertising Behavior from setuptools. A good example of
this plug-in behavior can be seen in pytest plugins, where pytest is a test framework
that allows other libraries to extend or modify its functionality through the pytest11
entry point.
Understanding the API
Let’s look at an example of listing the console script entry points for all installed Python packages.
"""List console_scripts entry points for all installed packages"""
from importlib import metadata
for ep in metadata.entry_points()['console_scripts']:
print(f"name='{ep.name}', value='{ep.value}'")
Functionality is provided by the entry_points() function from importlib.metadata library
introduced in Python 3.8.
The entry_points() function returns a collection of entry points. Entry points
are represented by EntryPoint instances; each EntryPoint has a .name, .group,
and .value attributes and a .load() method to resolve the value. There are also
.module, .attr, and .extras attributes for getting the components of the .value attribute.
For earlier versions of Python, you could use the pkg_resources package:
"""List console_scripts entry points for all installed packages using pkg_resources"""
import pkg_resources
for ep in pkg_resources.iter_entry_points(group='console_scripts'):
print(f"name='{ep.name}', module='{ep.module_name}', attr='{ep.attrs}'")
Plugin Example
In this example we will create a script which can be extended via pygems.demoplugin plugins.
The plugin should register entry points in the pygems.demoplugin group:
# setup.cfg
[options.entry_points]
pygems.demoplugin =
hello-world = pygems.demo.helloworld:hi
Our sample plugin is doing simple print of the “Hi. It is me!” message to the console:
def hi():
print("Hi. It is me!")
The application or script that needs to use the plugin filters the entry points by group, loads the plugins and executes them.
import pkg_resources
for ep in pkg_resources.iter_entry_points(group='pygems.demoplugin'):
plugin = ep.load()
plugin()
Conclusion
Package entry points give us a mechanism for implementing plugin architecture using loosely coupled plugins and consumers.
On the cons side the architecture depends on package entry points advertised by setuptools. If the feature is dropped from Python, plugins will stop working.