How to add a new plugin entry point to edX platform

Background

Open edX is a very powerful platform and can be extended in many ways. This document describes the best practices that should be used to add new plugin entry points which allow any installed Python library to provide new capabilities.

Technical Details

Open edX uses Stevedore from Open Stack to provide support for plugins. There are a few steps necessary to declare your new entry point:

  • The first step is to implement a subclass of PluginManager which code will use to find instances of your plugins
  • Your new plugin manager class should specify the property NAMESPACE for your chosen entry point namespace
    • e.g. 

      MY_PLUGIN_NAMESPACE = 'my_organization.my_plugin'
      
      class MyPluginManager(PluginManager):
          """
          Manager for my plugins.
          """
      	NAMESPACE = MY_PLUGIN_NAMESPACE
  • In a Python library, a new plugin can be registered in setup.py

    • e.g. 

      from setuptools import setup
      
      setup(
          name="My Library",
          version="1.0",
          install_requires=["setuptools"],
          requires=[],
          entry_points={
              "my_organization.my_plugin": [
                  "first_plugin = my_organization.plugins:FirstPlugin",
          },
      )
  • The platform now can access the plugins in one of two ways:

    • MyPluginManager.get_available_plugins()
      • Returns the list of plugins registered by all the installed libraries.
    • MyPluginManager.get_plugin(plugin_name)
      • Returns the named plugin declared for the entry point (or raises an exception if one isn't found).
      • e.g. 

        my_plugin = MyPluginManager.get_plugin('first_plugin')
  • Typically the platform code will work with the full list of available plugins

    • This is because, by definition, installed plugins are not known by name to the platform

    • Instead, the platform should iterate the list of plugins and decide how to handle them
    • Foe example, an authoring UI could present the list of options to the author who could then pick one
      • The name of the chosen plugin would then be persisted
      • Then a learner-facing UI would request that plugin by name and then use it appropriately, e.g. render it as a view

Example 1: Block Transformers

The Course Blocks API provides a plugin mechanism to allow new transformers to be added. 

Example 2: Course Tabs

The tabs shown for a course are defined as plugins, so that features can introduce new ones.

For more details, see Adding a new course tab.