API¶
Interfaces/ExtensionPoints¶
-
class
gdaps.
Interface
¶ Base class for interface definitions.
Inherit from Interface and eventually add methods to that class:
class IMyInterface(Interface): def do_something(self): pass
You can choose whatever name you want for your interfaces, but we recommend you start the name with a capital “I”. Read more about interfaces in the The plugin AppConfig section.
-
gdaps.
implements
¶ alias of
gdaps.Implements
-
class
gdaps.
ExtensionPoint
(interface: Type[gdaps.Interface])¶ Marker class for Extension points in plugins.
You can iterate over ‘Extensionpoint’s via
for..in
:ep = ExtensionPoint(IMyInterface) for plugin in ep: plugin.do_something()
-
extensions
() → set¶ Returns a set of plugin instances that match the interface of this extension point.
-
-
class
gdaps.
Implements
(*interfaces)¶ Decorator class for implementing interfaces.
Just decorate a class with @implements to make it an implementation of an Interface:
@implements(IMyInterface) class PluginA: def do_something(self): print("Greetings from PluginA")
You can also implement more than one interface: @implements(InterfaceA, InterfaceB) and implement all their methods.
Read more about implementations in the Implementations section.
PluginManager¶
-
class
gdaps.pluginmanager.
PluginManager
¶ A Generic Django Plugin Manager that finds Django app plugins in a plugins folder or setuptools entry points and loads them dynamically.
It provides a couple of methods to interaft with plugins, load submodules of all available plugins dynamically, or get a list of enabled plugins. Don’t instantiate a
PluginManager
directly, just use its static and class methods directly.-
classmethod
find_plugins
(group: str) → List[str]¶ Finds plugins from setuptools entry points.
This function is supposed to be called in settings.py after the INSTALLED_APPS variable. Therefore it can not use global variables from settings, to prevent circle imports.
- Parameters
group – a dotted path where to find plugin apps. This is used as ‘group’ for setuptools’ entry points.
- Returns
A list of dotted app_names, which can be appended to INSTALLED_APPS.
-
classmethod
load_plugin_submodule
(submodule: str, mandatory=False) → list¶ Search plugin apps for specific submodules and load them.
- Parameters
submodule – the dotted name of the Django app’s submodule to import. This package must be a submodule of the plugin’s namespace, e.g. “schema” - then [“<main>.core.schema”, “<main>.laboratory.schema”] etc. will be found and imported.
mandatory – If set to True, each found plugin _must_ contain the given submodule. If any installed plugin doesn’t have it, a PluginError is raised.
- Returns
a list of module objects that have been successfully imported.
-
classmethod
plugin_path
()¶ Returns the absolute path where application plugins live.
This is basically the Django root + the dotted entry point. CAVE: this is not callable from within the settings.py file.
-
static
plugins
(skip_disabled: bool = False) → List[django.apps.AppConfig]¶ Returns a list of AppConfig classes that are GDAPS plugins.
This method basically checks for the presence of a
PluginMeta
class within the AppConfig of all apps and returns a list of them. :param skip_disabled: If True, skips disabled plugins and only returns enabled ones. Defaults toFalse
.
-
static
urlpatterns
() → list¶ Loads all plugins’ urls.py and collects their urlpatterns.
This is maybe not the best approach, but it allows plugins to have “global” URLs, and not only namespaced, and it is flexible
- Returns
a list of urlpatterns that can be merged with the global urls.urlpattern.
-
classmethod
Plugin configuration and metadata¶
Plugins need to have a special AppConfig class. GDAPS provides a convenience PluginConfig
class to inherit from:
-
class
gdaps.apps.
PluginConfig
(*args, **kwargs)¶ Base config class for GDAPS plugins.
All GDAPS plugin apps files need to have an AppConfig class which inherits from
PluginConfig
. It is a convenience class that checks for the existence of the PluginMeta inner class, and provides some basic methods that are needed when interacting with a plugin during its life cycle.from django.utils.translation import gettext_lazy as _ from gdaps.apps import PluginConfig class FooPluginConfig(PluginConfig): class PluginMeta: # the plugin machine "name" is taken from the Appconfig, so no name here verbose_name = _('Foo Plugin') author = 'Me Personally' description = _('A foo plugin') visible = True version = '1.0.0' compatibility = "myproject.core>=2.3.0"
If you are using signals in your plugin, we recommend to put them into a
signals
submodule. Import them from theAppConfig.ready()
method.def ready(self): # Import signals if necessary: from . import signals # NOQA
See also
Don’t overuse the
ready
method. Have a look at the Django documentation of ready().If your plugin needs to install some data into the database at the first run, you can provide a
initialize
method, which will be called using theinitializeplugins
management command:Do all necessary things there that need to be done when the plugin is available the first time, e.g. after installing a plugin using pip/pipenv.
def initialize(self): # install some fixtures, etc. pass