Skip to content

Commit

Permalink
docs: add more detailed documentation under the concepts section
Browse files Browse the repository at this point in the history
  • Loading branch information
mariajgrimaldi committed Oct 15, 2024
1 parent 29d7bb4 commit 14ddd14
Show file tree
Hide file tree
Showing 3 changed files with 156 additions and 29 deletions.
73 changes: 73 additions & 0 deletions docs/concepts/events-vs-filters.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
Events vs Filters
=================

Open edX Events and Filters are two types of hooks that allow developers to extend the functionality of the Open edX platform. They are defined in the `openedx-events`_ and `openedx-filters`_ libraries respectively.

.. _openedx-events: https://github.com/openedx/openedx-events
.. _openedx-filters: https://github.com/openedx/openedx-filters

Events
------

Events are Open edX-specific Django signals sent in specific places in the Open edX platform. Signal handlers can then be hooked into these signals to perform additional processing based on the event data.

For a more detailed explanation of Open edX Events, see the rest of the Open edX Events documentation.

Filters
-------

Filters are functions that can modify the application's behavior by altering input data or halting execution based on specific conditions. They allow developers to implement application flow control based on their business logic or requirements without directly modifying the application code.

For a more detailed explanation of Open edX Filters, see the `Open edX Filters`_ documentation.

.. _Open edX Filters: https://docs.openedx.org/projects/openedx-filters/en/latest/

Differences between Events and Filters
--------------------------------------

Here are some key differences between Open edX Events and Filters:

+--------------------+------------------------------------------------------------------------+-------------------------------------------------------------+
| | Events | Filters |
+====================+========================================================================+=============================================================+
| **Purpose** | Notify when an action occurs in a specific part of the | Alter the application flow control. |
| | application. | |
+--------------------+------------------------------------------------------------------------+-------------------------------------------------------------+
| **Usage** | Used to **extend** functionality via signal handlers when an event is | Used to intercept and **modify** the data used within a |
| | triggered. | component without directly modifying the application |
| | | itself. |
+--------------------+------------------------------------------------------------------------+-------------------------------------------------------------+
| **Definition** | Defined using the `OpenEdxPublicSignal` class, which | Defined using the `OpenEdxFilter` class, which provides a |
| | provides a structured way to define the data and | way to define the filter function and the parameters it |
| | metadata associated with the event. | should receive. |
+--------------------+------------------------------------------------------------------------+-------------------------------------------------------------+
| **Implementation** | Implemented using Django signals, which allow | Implemented using an accumulative pipeline mechanism which |
| | developers to send and receive notifications within | takes a set of arguments and returns a modified set |
| | a Django application. | to the caller or raises exceptions during |
| | | processing. |
+--------------------+------------------------------------------------------------------------+-------------------------------------------------------------+
| **Example** | A custom event that triggers an email notification | A filter that modifies the data returned by a specific |
| | when a user enrolls in a course. | API endpoint to include additional information. |
+--------------------+------------------------------------------------------------------------+-------------------------------------------------------------+

When to use an Open edX Event?
------------------------------

Use an Open edX Event when you need to:

- Trigger custom logic or processing in response to specific actions within the platform, e.g., updating a search index after a course block is modified.
- Communicate, synchronize, or coordinate with other components or services based on specific events or actions, e.g., send certificate data from LMS to credentials service to keep models up to date.
- Integrate with external systems or services based on specific events or actions within the platform, e.g., send user data to third-party services upon registration for marketing purposes.

In summary, events can be used to integrate application components with each other or with external services, allowing them to communicate, synchronize, and perform additional actions when specific triggers occur.

When to use an Open edX Filter?
-------------------------------

Use an Open edX Filter when:

- Enrich the data or parameters passed to a specific component, e.g., fetch reusable LTI configurations from external plugins.
- Intercept and modify the input of a specific component, e.g., modify block structure so it renders additional data.
- Enforce specific constraints or business rules on the input or output of a specific function or method, e.g., prevent enrollment for non-authorized users.

In summary, filters can be used when implementing application flow control that modifies the application's behavior, navigation, or user interaction flow during runtime.
59 changes: 30 additions & 29 deletions docs/concepts/hooks-extension-framework.rst
Original file line number Diff line number Diff line change
@@ -1,43 +1,44 @@
Extending Open edX with the Hooks Extensions Framework
######################################################
Hooks Extension Framework
=========================

Overview
--------

To sustain the growth of the Open edX ecosystem, the business rules of the
platform must be open for extension following the open-closed principle. This
framework allows developers to do just that without needing to fork and modify
the main edx-platform repository.
Open edX platform.

Hooks: Open edX Events and Filters
----------------------------------

Context
*******
Hooks are predefined places in the Open edX project core where externally defined
functions can take place. These functions may alter what the user
sees or experiences on the platform, while in other cases, they are purely informative. All
hooks are designed to be extended through Open edX plugins and configurations.

Hooks are predefined places in the edx-platform core where externally defined
functions can take place. In some cases, those functions can alter what the user
sees or experiences in the platform. Other cases are informative only. All cases
are meant to be extended using Open edX plugins and configuration.
Hooks can be of two types, events and filters. Events are, in essence, signals
sent in specific places whose listeners can extend functionality. While filters
are functions that can modify the behavior of the application.

Hooks can be of two types, events and filters. Events are in essence Django signals, in
that they are sent in specific application places and whose listeners can extend
functionality. On the other hand Filters are passed data and can act on it
before this data is put back in the original application flow. In order to allow
extension developers to use the Events and Filters definitions on their plugins,
both kinds of hooks are defined in lightweight external libraries.
To allow extension developers to use the framework's definitions in their
implementations, both kinds of hooks are defined in lightweight external
libraries:

* `openedx-filters`_
* `openedx-events`_

Hooks are designed with stability in mind. The main goal is that developers can
use them to change the functionality of the platform as needed and still be able
to migrate to newer open releases with very little to no development effort. In
the case of filters, this is detailed in the `naming and versioning ADR`_.
The main goal of the framework is that developers can use them to change the
functionality of the platform as needed and still be able to migrate to newer
open releases with very little to no development effort, so they're designed
with stability in mind, meaning that they are versioned and backward compatible
as much as possible. In the case of the events, this approach is further
detailed in the `versioning ADR`_ and the `payload ADR`_.

A longer description of the framework and it's history can be found in `OEP 50`_.
A longer description of the framework and its history can be found in `OEP 50`_.

.. _OEP 50: https://open-edx-proposals.readthedocs.io/en/latest/oep-0050-hooks-extension-framework.html
.. _naming and versioning ADR: https://github.com/openedx/openedx-filters/blob/main/docs/decisions/0004-filters-naming-and-versioning.rst
.. _openedx-filters: https://github.com/openedx/openedx-filters
.. _openedx-events: https://github.com/openedx/openedx-events

On the technical side, filters are implemented using a pipeline mechanism, that executes
a list of functions called ``steps`` configured through Django settings. Each
pipeline step receives a dictionary with data, processes it and returns an output. During
this process, they can alter the application execution flow by halting the process
or modifying their input arguments.
.. _versioning ADR: https://github.com/eduNEXT/openedx-events/blob/main/docs/decisions/0002-events-naming-and-versioning.rst
.. _payload ADR: https://github.com/eduNEXT/openedx-events/blob/main/docs/decisions/0003-events-payload.rst
.. _openedx-filters: https://github.com/eduNEXT/openedx-filters
.. _openedx-events: https://github.com/eduNEXT/openedx-events
53 changes: 53 additions & 0 deletions docs/concepts/openedx-filters.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
Open edX Filters
================

Overview
--------

In the context of Open edX, filters provide a mechanism for modifying the platform's behavior by altering runtime data or halting execution based on specific conditions. Filters allow developers to implement application flow control based on their business logic or requirements without directly modifying the application code.

What are Open edX Filters?
-------------------------

An Open edX Filter is a pipeline mechanism that executes a series of functions in a specific order, allowing each function to modify the input data or halt execution based on specific conditions. Filters are used to intercept and modify the data used within a component without directly modifying the application itself. Filters are defined using the ``OpenEdxFilter`` class, which provides a structured way to define the filter function and the parameters it should receive.

Why are Open edX Filters important?
-----------------------------------

Open edX Filters are a key component of the Hooks Extension Framework, which allow developers to implement their own functions to alter the functionality of the platform without directly modifying the core codebase saving time, effort and decreasing maintainability costs. This enables a wide range of use cases, from modifying the behavior of existing components to dynamically adding new functionality to the platform.

How are Open edX Filters used?
------------------------------

Developers can implement pipeline functions that take a set of arguments and return a modified set to the caller or raise exceptions during processing. In this functions, developers can implement their business logic or requirements that modify the application's behavior based on specific conditions.

These pipeline functions are configured by using the ``OPEN_EDX_FILTERS_CONFIG`` setting in the Django settings file. This setting allows developers to specify the functions that should run when invoking a specific filter.

For more information on how to use Open edX Filters, refer to the `Using Open edX Filters`_ how-to guide.

How do Open edX Filters work?
----------------------------

Open edX Filters are implemented using an accumulative pipeline mechanism, which executes a series of functions in a specific order. Each function in the pipeline receives the output of the previous function as input, allowing developers to build complex processing logic by chaining multiple functions together. The pipeline ensures that the order of execution is maintained and that the result of a previous function is available to the current one in the form of a pipeline.

The lifecycle of an Open edX Filter can be summarized as follows:

1. A service invokes calls a filter by invoking ``run_filter()`` method with the initial arguments.
2. The filter's tooling gets the pipeline functions to execute based on the filter configuration ``OPEN_EDX_FILTERS_CONFIG``.
3. The tooling executes a series of functions in a specific order, passing the output of the previous function as input to the next one.
4. Each function in the pipeline can modify the input data or halt execution based on specific conditions.
5. The filter returns the final output of the pipeline to the caller.
6. The filter is considered complete once all functions in the pipeline have executed.

Here is an example of how that might look like with an existing filter:

1. A user enrolls in a course, `triggering the CourseEnrollmentStarted filter`_. This filter includes information about the user, course, and enrollment details.
2. The filter tooling executes a series of functions in a specific order, such as checking if the user is eligible for enrollment, updating the user's enrollment status, and sending a notification to the user.
3. Each function in the pipeline can modify the input data or halt execution based on specific conditions, such as denying enrollment if the user is not eligible.
4. The filter returns the final output of the pipeline to the caller, which may include updated enrollment details or a raising an exception if the user is not eligible.
5. The filter is considered complete once all functions in the pipeline have executed.

.. _Using Open edX Filters: ../how-tos/using-filters.html
.. _Hooks Extension Framework: https://open-edx-proposals.readthedocs.io/en/latest/oep-0050-hooks-extension-framework.html
.. _Django Signals Documentation: https://docs.djangoproject.com/en/4.2/topics/signals/
.. _triggering the CourseEnrollmentStarted filter: https://github.com/openedx/edx-platform/blob/master/common/djangoapps/student/models/course_enrollment.py#L719-L724

0 comments on commit 14ddd14

Please sign in to comment.