Support for Django App Plugins

This commit is contained in:
Nimisha Asthagiri
2018-01-08 21:07:15 -05:00
parent 11794c8384
commit c2fc546db9
2 changed files with 362 additions and 14 deletions

View File

@@ -1,45 +1,46 @@
"""
Adds support for first class features that can be added to the edX platform.
Adds support for first class plugins that can be added to the edX platform.
"""
from collections import OrderedDict
from stevedore.extension import ExtensionManager
from openedx.core.lib.cache_utils import memoized
class PluginError(Exception):
"""
Base Exception for when an error was found regarding features.
Base Exception for when an error was found regarding plugins.
"""
pass
class PluginManager(object):
"""
Base class that manages plugins to the edX platform.
Base class that manages plugins for the edX platform.
"""
@classmethod
def get_available_plugins(cls):
@memoized
def get_available_plugins(cls, namespace=None):
"""
Returns a dict of all the plugins that have been made available through the platform.
"""
# Note: we're creating the extension manager lazily to ensure that the Python path
# has been correctly set up. Trying to create this statically will fail, unfortunately.
if not hasattr(cls, "_plugins"):
plugins = {}
extension_manager = ExtensionManager(namespace=cls.NAMESPACE) # pylint: disable=no-member
for plugin_name in extension_manager.names():
plugins[plugin_name] = extension_manager[plugin_name].plugin
cls._plugins = plugins
return cls._plugins
plugins = OrderedDict()
extension_manager = ExtensionManager(namespace=namespace or cls.NAMESPACE) # pylint: disable=no-member
for plugin_name in extension_manager.names():
plugins[plugin_name] = extension_manager[plugin_name].plugin
return plugins
@classmethod
def get_plugin(cls, name):
def get_plugin(cls, name, namespace=None):
"""
Returns the plugin with the given name.
"""
plugins = cls.get_available_plugins()
plugins = cls.get_available_plugins(namespace)
if name not in plugins:
raise PluginError("No such plugin {name} for entry point {namespace}".format(
name=name,
namespace=cls.NAMESPACE # pylint: disable=no-member
namespace=namespace or cls.NAMESPACE, # pylint: disable=no-member
))
return plugins[name]