Plugins API#

class xblock.plugin.Plugin#

Base class for a system that uses entry_points to load plugins.

Implementing classes are expected to have the following attributes:

entry_point: The name of the entry point to load plugins from.

classmethod load_class(identifier, default=None, select=None)#

Load a single class specified by identifier.

If identifier specifies more than a single class, and select is not None, then call select on the list of entry_points. Otherwise, choose the first one and log a warning.

If default is provided, return it if no entry_point matching identifier is found. Otherwise, will raise a PluginMissingError

If select is provided, it should be a callable of the form:

def select(identifier, all_entry_points):
    # ...
    return an_entry_point

The all_entry_points argument will be a list of all entry_points matching identifier that were found, and select should return one of those entry_points to be loaded. select should raise PluginMissingError if no plugin is found, or AmbiguousPluginError if too many plugins are found

classmethod load_classes(fail_silently=True)#

Load all the classes for a plugin.

Produces a sequence containing the identifiers and their corresponding classes for all of the available instances of this plugin.

fail_silently causes the code to simply log warnings if a plugin cannot import. The goal is to be able to use part of libraries from an XBlock (and thus have it installed), even if the overall XBlock cannot be used (e.g. depends on Django in a non-Django application). There is disagreement about whether this is a good idea, or whether we should see failures early (e.g. on startup or first page load), and in what contexts. Hence, the flag.

classmethod register_temp_plugin(class_, identifier=None, dist='xblock')#

Decorate a function to run with a temporary plugin available.

Use it like this in tests:

@register_temp_plugin(MyXBlockClass):
def test_the_thing():
    # Here I can load MyXBlockClass by name.
class xblock.reference.plugins.Filesystem(help=None, default=fields.UNSET, scope=ScopeBase(user=UserScope.NONE, block=BlockScope.DEFINITION, name='content'), display_name=None, values=None, enforce_type=False, xml_node=False, force_export=False, **kwargs)#

An enhanced pyfilesystem.

This returns a file system provided by the runtime. The file system has two additional methods over a normal pyfilesytem:

  • get_url allows it to return a URL for a file

  • expire allows it to create files which may be garbage collected after a preset period. edx-platform and xblock-sdk do not currently garbage collect them, however.

More information can be found at: openedx/django-pyfs

The major use cases for this are storage of large binary objects, pregenerating per-student data (e.g. pylab plots), and storing data which should be downloadable (for example, serving <img src=…> will typically be faster through this than serving that up through XBlocks views.