From c0a9cc9409ebaf15dfeb0a8abfb7813c82fcf54c Mon Sep 17 00:00:00 2001 From: Maria Grimaldi Date: Tue, 15 Oct 2024 13:52:22 +0200 Subject: [PATCH 01/15] docs: add more detailed documentation under the concepts section --- docs/concepts/events-vs-filters.rst | 73 +++++++++++++++++++++ docs/concepts/hooks-extension-framework.rst | 59 +++++++++-------- docs/concepts/openedx-filters.rst | 53 +++++++++++++++ 3 files changed, 156 insertions(+), 29 deletions(-) create mode 100644 docs/concepts/events-vs-filters.rst create mode 100644 docs/concepts/openedx-filters.rst diff --git a/docs/concepts/events-vs-filters.rst b/docs/concepts/events-vs-filters.rst new file mode 100644 index 00000000..63e7b475 --- /dev/null +++ b/docs/concepts/events-vs-filters.rst @@ -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. diff --git a/docs/concepts/hooks-extension-framework.rst b/docs/concepts/hooks-extension-framework.rst index 0e724e85..044272bf 100644 --- a/docs/concepts/hooks-extension-framework.rst +++ b/docs/concepts/hooks-extension-framework.rst @@ -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 diff --git a/docs/concepts/openedx-filters.rst b/docs/concepts/openedx-filters.rst new file mode 100644 index 00000000..5ce69250 --- /dev/null +++ b/docs/concepts/openedx-filters.rst @@ -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 From f7f8ca663f9e66c08f4ae39be889c463eb4d5840 Mon Sep 17 00:00:00 2001 From: Maria Grimaldi Date: Tue, 15 Oct 2024 13:57:58 +0200 Subject: [PATCH 02/15] fix: add missing hyphen to avoid title underline too short --- docs/concepts/openedx-filters.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/concepts/openedx-filters.rst b/docs/concepts/openedx-filters.rst index 5ce69250..6b9e923d 100644 --- a/docs/concepts/openedx-filters.rst +++ b/docs/concepts/openedx-filters.rst @@ -7,7 +7,7 @@ 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. @@ -26,7 +26,7 @@ These pipeline functions are configured by using the ``OPEN_EDX_FILTERS_CONFIG`` 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. From b192bc0aefcfcb282e6e0c4cb12a9cd361738e4a Mon Sep 17 00:00:00 2001 From: Maria Grimaldi Date: Tue, 15 Oct 2024 08:10:21 -0400 Subject: [PATCH 03/15] docs: clarify openedx-filters.rst --- docs/concepts/openedx-filters.rst | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/docs/concepts/openedx-filters.rst b/docs/concepts/openedx-filters.rst index 6b9e923d..6a3a191d 100644 --- a/docs/concepts/openedx-filters.rst +++ b/docs/concepts/openedx-filters.rst @@ -9,19 +9,17 @@ In the context of Open edX, filters provide a mechanism for modifying the platfo 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. +An Open edX Filter is a pipeline mechanism that executes a series of functions specified in a configuration setting. Each function can modify the input data or halt execution, altering the application's behavior during runtime. 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. +Open edX Filters are a key component of the Hooks Extension Framework. Filters allow developers to implement their own functions to alter the platform's functionality 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. +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 these functions, developers can implement 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. @@ -33,10 +31,10 @@ Open edX Filters are implemented using an accumulative pipeline mechanism, which 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. +2. The filter's tooling gets the pipeline functions to execute from the filter configuration ``OPEN_EDX_FILTERS_CONFIG``. +3. The tooling executes the 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. +5. The filter returns the final output of the pipeline to the caller to be used by the rest of the process. 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: From 96ae66f5423509d5b54f05ad4b32c66ce1397910 Mon Sep 17 00:00:00 2001 From: Maria Grimaldi Date: Mon, 28 Oct 2024 09:21:28 -0400 Subject: [PATCH 04/15] docs: Update openedx-filters.rst --- docs/concepts/openedx-filters.rst | 57 +++++++++++++++++-------------- 1 file changed, 31 insertions(+), 26 deletions(-) diff --git a/docs/concepts/openedx-filters.rst b/docs/concepts/openedx-filters.rst index 6a3a191d..ee02426f 100644 --- a/docs/concepts/openedx-filters.rst +++ b/docs/concepts/openedx-filters.rst @@ -4,48 +4,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. +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. + +Throughout this document, we will refer to Open edX Filters as filters interchangeably. What are Open edX Filters? -------------------------- -An Open edX Filter is a pipeline mechanism that executes a series of functions specified in a configuration setting. Each function can modify the input data or halt execution, altering the application's behavior during runtime. Filters are defined using the ``OpenEdxFilter`` class, which provides a structured way to define the filter function and the parameters it should receive. +An Open edX Filter is a pipeline mechanism that executes a series of functions when configured. Each function receives input arguments, which are data used by the process in execution, and returns the same arguments, possibly modified. Given this design, filters can modify the application flow according to the specified configuration, altering or adding new behaviors during execution time. -Why are Open edX Filters important? ------------------------------------ +The pipeline mechanism is implemented by a class called ``OpenEdxPublicFilter``, which provides the necessary tools to fulfill the Open edX Filters requirements, such as ordered execution, configurability, interchangeable functions, argument definition, and cumulative behavior. This enables filters to modify the flow of the application dynamically during runtime based on predefined business logic or conditions. -Open edX Filters are a key component of the Hooks Extension Framework. Filters allow developers to implement their own functions to alter the platform's functionality 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 do Open edX Filters work? +----------------------------- -How are Open edX Filters used? ------------------------------- +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 filter execution process follows these steps: -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 these functions, developers can implement 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. +1. A function or method (caller) invokes the filter by calling the ``run_filter()`` method provided by the ``OpenEdxPublicFilter`` class, passing initial input arguments. +2. The filter's tooling retrieves the configuration from ``OPEN_EDX_FILTERS_CONFIG``, which defines a list of N functions (f0, f1, …, fn-1) that will be executed. +3. The tooling then executes each function in the pipeline sequentially, starting with f0, which processes the input arguments ``args`` and applies the developer’s operations, returning potentially modified arguments. +4. The next function (f1) receives the potentially modified arguments and applies further operations, returning another modified set of arguments. This process continues through the list of functions. +5. Each subsequent function (fi+1) receives the output from the previous function and returns its modified output until all functions have been executed. -For more information on how to use Open edX Filters, refer to the `Using Open edX Filters`_ how-to guide. +Additionally, at any point in the pipeline, a developer can halt execution by raising an exception, based on conditions defined in the processing logic, to stop further modifications. -How do Open edX Filters work? ------------------------------ +6. Once the final function (fn-1) has been executed, the final modified arguments are returned to the caller, which may use them for the remaining part of its execution. -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. +Each function in the pipeline has the ability to modify the input data, add new data, or halt execution based on specific conditions, such as raising exceptions if certain criteria are not met. This pipeline structure ensures that complex business logic can be applied during runtime without directly altering the application code. -The lifecycle of an Open edX Filter can be summarized as follows: +Here’s an example of a filter in action: -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 from the filter configuration ``OPEN_EDX_FILTERS_CONFIG``. -3. The tooling executes the 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 to be used by the rest of the process. -6. The filter is considered complete once all functions in the pipeline have executed. +1. A user enrolls in a course, `triggering the CourseEnrollmentStarted filter`_. This filter processes information about the user, course, and enrollment details. +2. The filter tooling executes a series of functions, such as checking user eligibility for enrollment, updating the enrollment status, and notifying the user about the enrollment. +3. Each function can modify the input data or halt the process based on business logic (e.g., denying enrollment if the user is ineligible). +4. The final output of the pipeline, such as the updated enrollment details, is returned to the caller, or an exception is raised if the user is not eligible. +5. The process is 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. +By organizing this workflow through a pipeline, Open edX Filters allow developers to extend platform functionality in a flexible and maintainable way. .. _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 +.. _Python Social Auth: https://python-social-auth.readthedocs.io/en/latest/pipeline.html + +How are Open edX Filters used? +------------------------------ + +Developers can implement functions in a plugin, configure them for a particular filter in the ``OPEN_EDX_FILTERS_CONFIG`` setting, midifying the application flow when a the filter in question is invoked by the process in execution. These functions can the application's behavior by altering data, adding new data, or stopping execution by raising exceptions. For example, a filter can stop a student’s enrollment if certain conditions, such as business rules, are not met. + +For more information on how to use Open edX Filters, refer to the `Using Open edX Filters`_ how-to guide. From 70f62582acca7e482a128b42ea51b6489f71965f Mon Sep 17 00:00:00 2001 From: Maria Grimaldi Date: Mon, 28 Oct 2024 09:22:09 -0400 Subject: [PATCH 05/15] docs: improve hooks framework reference --- docs/concepts/hooks-extension-framework.rst | 59 +++++++++++++-------- 1 file changed, 37 insertions(+), 22 deletions(-) diff --git a/docs/concepts/hooks-extension-framework.rst b/docs/concepts/hooks-extension-framework.rst index 044272bf..3a36af49 100644 --- a/docs/concepts/hooks-extension-framework.rst +++ b/docs/concepts/hooks-extension-framework.rst @@ -4,41 +4,56 @@ 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 -Open edX platform. +Based on the `open-closed principle`_, this framework aims to extend the platform in a maintainable way without modifying its core. The main goal is to leverage the existing extension capabilities provided by the plugin architecture, allowing developers to implement new features to fit customer needs while reducing the need for core modifications and minimizing maintenance efforts. Hooks: Open edX Events and Filters ---------------------------------- -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 a list of places in the Open edX platform 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 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 signals sent in specific places whose receivers can extend functionality, while filters are functions that can modify the application's behavior. -To allow extension developers to use the framework's definitions in their -implementations, 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`_ -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`_. +The main goal of the framework is that developers can use it to change the platform's functionality as needed and still migrate to newer Open edX releases with little to no development effort. So, the framework is designed with stability in mind, meaning it is versioned and backward compatible as much as possible. A longer description of the framework and its history can be found in `OEP 50`_. +Why use Open edX Hooks? +-------------------------------------- + +#. Stable and Maintainable Extensions + +The Hooks Extension Framework allows developers to extend the platform's functionality in a stable, maintainable, and decoupled way ensuring easier upgrades and long-term stability by removing the need to modify the core in an significant way. + +#. Contained Solution Implementation + +By avoiding core modifications, the framework promotes self-contained solutions, eliminating the need for custom code to coexist with core logic which lowers maintenance costs for extension developers. + +#. Leveraging the Open edX Plugin Extension Mechanism + +The framework allows developers to implement custom business logic and integrations directly in plugins. This keeps core modifications minimal, focusing maintenance and development efforts on plugins, where solutions can be built and maintained independently of the core platform. + +#. Standardization + +Both filters and events implementations implement an approach for adding additional features, such as communication between components or services, or backend flow control. With these standards in place, it’s easy to identify when and how to use the framework as a solution, ensuring a consistent and predictable approach to extending the platform. + +#. Reduce Fork Modifications + +The need to modify logic in forks is minimized, as most extensions can now be implementing using the framework, keeping forks closer to the core and easier to manage. + +#. Community Compatibility + +The framework allows for shorter and more agile contribution cycles. By adding standardized extension points, contributors avoid creating customer-specific logic, making development more community-friendly. + +#. Backward Compatibility + +Hooks are designed to be backward compatible, guaranteeing stability across releases and making it easier to upgrade without breaking existing functionality. + .. _OEP 50: https://open-edx-proposals.readthedocs.io/en/latest/oep-0050-hooks-extension-framework.html -.. _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 +.. _open-closed principle: https://docs.openedx.org/projects/edx-platform/en/open-release-quince.master/concepts/extension_points.html From d316623c00d90ad44a642c666d2dd4e7d693fdb1 Mon Sep 17 00:00:00 2001 From: Maria Grimaldi Date: Mon, 28 Oct 2024 09:22:59 -0400 Subject: [PATCH 06/15] docs: match events-vs-filters.rst in openedx-events --- docs/concepts/events-vs-filters.rst | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/docs/concepts/events-vs-filters.rst b/docs/concepts/events-vs-filters.rst index 63e7b475..7804830a 100644 --- a/docs/concepts/events-vs-filters.rst +++ b/docs/concepts/events-vs-filters.rst @@ -9,7 +9,7 @@ Open edX Events and Filters are two types of hooks that allow developers to exte 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. +Events are Open edX-specific Django signals sent in specific places on the Open edX platform. They allow developers to listen to these signals and 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. @@ -37,17 +37,17 @@ Here are some key differences between Open edX Events and Filters: | | 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. | +| **Definition** | Defined using the `OpenEdxPublicSignal` class, which | Defined using the ``OpenEdxPublicFilter`` class, | +| | provides a structured way to define the data and | which provides a way to define the filter function | +| | metadata associated with the event. | and the parameters it 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 | +| | developers to send and receive notifications that an action happened | takes a set of arguments and returns a modified set | +| | within 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. | +| **Use cases** | Send an email notification when a user enrolls in a course. | Include additional information in an API endpoint response.| +| | an email notification. | | +--------------------+------------------------------------------------------------------------+-------------------------------------------------------------+ When to use an Open edX Event? @@ -67,7 +67,7 @@ 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. +- Intercept and modify the input of a specific component, e.g., include "Edit" link to an HTML block if certain conditions are met. - 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. From 96691701520f64b384a2def47dc43c2a1a7ac031 Mon Sep 17 00:00:00 2001 From: Maria Grimaldi Date: Mon, 28 Oct 2024 09:26:35 -0400 Subject: [PATCH 07/15] docs: be consistent with framework name --- docs/concepts/hooks-extension-framework.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/concepts/hooks-extension-framework.rst b/docs/concepts/hooks-extension-framework.rst index 3a36af49..d90353ca 100644 --- a/docs/concepts/hooks-extension-framework.rst +++ b/docs/concepts/hooks-extension-framework.rst @@ -22,8 +22,8 @@ The main goal of the framework is that developers can use it to change the platf A longer description of the framework and its history can be found in `OEP 50`_. -Why use Open edX Hooks? --------------------------------------- +Why adopt the Hooks Extension Framework? +------------------------------------------- #. Stable and Maintainable Extensions From 6b62b04735140d0628dca3a832e445afc2cd1724 Mon Sep 17 00:00:00 2001 From: Maria Grimaldi Date: Thu, 31 Oct 2024 13:45:59 +0100 Subject: [PATCH 08/15] refactor!: drop duplicated documentation in favor of centralized docs --- docs/concepts/events-vs-filters.rst | 73 --------------------- docs/concepts/hooks-extension-framework.rst | 59 ----------------- docs/concepts/index.rst | 3 +- 3 files changed, 1 insertion(+), 134 deletions(-) delete mode 100644 docs/concepts/events-vs-filters.rst delete mode 100644 docs/concepts/hooks-extension-framework.rst diff --git a/docs/concepts/events-vs-filters.rst b/docs/concepts/events-vs-filters.rst deleted file mode 100644 index 7804830a..00000000 --- a/docs/concepts/events-vs-filters.rst +++ /dev/null @@ -1,73 +0,0 @@ -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 on the Open edX platform. They allow developers to listen to these signals and 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 ``OpenEdxPublicFilter`` class, | -| | provides a structured way to define the data and | which provides a way to define the filter function | -| | metadata associated with the event. | and the parameters it should receive. | -+--------------------+------------------------------------------------------------------------+-------------------------------------------------------------+ -| **Implementation** | Implemented using Django signals, which allow | Implemented using an accumulative pipeline mechanism which | -| | developers to send and receive notifications that an action happened | takes a set of arguments and returns a modified set | -| | within a Django application. | to the caller or raises exceptions during | -| | | processing. | -+--------------------+------------------------------------------------------------------------+-------------------------------------------------------------+ -| **Use cases** | Send an email notification when a user enrolls in a course. | Include additional information in an API endpoint response.| -| | an email notification. | | -+--------------------+------------------------------------------------------------------------+-------------------------------------------------------------+ - -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., include "Edit" link to an HTML block if certain conditions are met. -- 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. diff --git a/docs/concepts/hooks-extension-framework.rst b/docs/concepts/hooks-extension-framework.rst deleted file mode 100644 index d90353ca..00000000 --- a/docs/concepts/hooks-extension-framework.rst +++ /dev/null @@ -1,59 +0,0 @@ -Hooks Extension Framework -========================= - -Overview --------- - -Based on the `open-closed principle`_, this framework aims to extend the platform in a maintainable way without modifying its core. The main goal is to leverage the existing extension capabilities provided by the plugin architecture, allowing developers to implement new features to fit customer needs while reducing the need for core modifications and minimizing maintenance efforts. - -Hooks: Open edX Events and Filters ----------------------------------- - -Hooks are a list of places in the Open edX platform 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 can be of two types: events and filters. Events are signals sent in specific places whose receivers can extend functionality, while filters are functions that can modify the application's behavior. - -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`_ - -The main goal of the framework is that developers can use it to change the platform's functionality as needed and still migrate to newer Open edX releases with little to no development effort. So, the framework is designed with stability in mind, meaning it is versioned and backward compatible as much as possible. - -A longer description of the framework and its history can be found in `OEP 50`_. - -Why adopt the Hooks Extension Framework? -------------------------------------------- - -#. Stable and Maintainable Extensions - -The Hooks Extension Framework allows developers to extend the platform's functionality in a stable, maintainable, and decoupled way ensuring easier upgrades and long-term stability by removing the need to modify the core in an significant way. - -#. Contained Solution Implementation - -By avoiding core modifications, the framework promotes self-contained solutions, eliminating the need for custom code to coexist with core logic which lowers maintenance costs for extension developers. - -#. Leveraging the Open edX Plugin Extension Mechanism - -The framework allows developers to implement custom business logic and integrations directly in plugins. This keeps core modifications minimal, focusing maintenance and development efforts on plugins, where solutions can be built and maintained independently of the core platform. - -#. Standardization - -Both filters and events implementations implement an approach for adding additional features, such as communication between components or services, or backend flow control. With these standards in place, it’s easy to identify when and how to use the framework as a solution, ensuring a consistent and predictable approach to extending the platform. - -#. Reduce Fork Modifications - -The need to modify logic in forks is minimized, as most extensions can now be implementing using the framework, keeping forks closer to the core and easier to manage. - -#. Community Compatibility - -The framework allows for shorter and more agile contribution cycles. By adding standardized extension points, contributors avoid creating customer-specific logic, making development more community-friendly. - -#. Backward Compatibility - -Hooks are designed to be backward compatible, guaranteeing stability across releases and making it easier to upgrade without breaking existing functionality. - -.. _OEP 50: https://open-edx-proposals.readthedocs.io/en/latest/oep-0050-hooks-extension-framework.html -.. _openedx-filters: https://github.com/eduNEXT/openedx-filters -.. _openedx-events: https://github.com/eduNEXT/openedx-events -.. _open-closed principle: https://docs.openedx.org/projects/edx-platform/en/open-release-quince.master/concepts/extension_points.html diff --git a/docs/concepts/index.rst b/docs/concepts/index.rst index e3f391ea..647ea9a2 100644 --- a/docs/concepts/index.rst +++ b/docs/concepts/index.rst @@ -5,5 +5,4 @@ Concepts :maxdepth: 1 :caption: Contents: - hooks-extension-framework - glossary + openedx-filters From d596f2757fabf67231ff5eb9a8fd6d30edd183a1 Mon Sep 17 00:00:00 2001 From: Maria Grimaldi Date: Mon, 4 Nov 2024 20:10:40 +0100 Subject: [PATCH 09/15] refactor: apply PR suggestions --- docs/concepts/openedx-filters.rst | 55 ++++++++++++++++++------------- 1 file changed, 33 insertions(+), 22 deletions(-) diff --git a/docs/concepts/openedx-filters.rst b/docs/concepts/openedx-filters.rst index ee02426f..31934258 100644 --- a/docs/concepts/openedx-filters.rst +++ b/docs/concepts/openedx-filters.rst @@ -13,44 +13,55 @@ What are Open edX Filters? An Open edX Filter is a pipeline mechanism that executes a series of functions when configured. Each function receives input arguments, which are data used by the process in execution, and returns the same arguments, possibly modified. Given this design, filters can modify the application flow according to the specified configuration, altering or adding new behaviors during execution time. -The pipeline mechanism is implemented by a class called ``OpenEdxPublicFilter``, which provides the necessary tools to fulfill the Open edX Filters requirements, such as ordered execution, configurability, interchangeable functions, argument definition, and cumulative behavior. This enables filters to modify the flow of the application dynamically during runtime based on predefined business logic or conditions. +The pipeline mechanism is implemented by a class called `OpenEdxPublicFilter`_, which provides the necessary tools to fulfill the Open edX Filters requirements, such as ordered execution, configurability, interchangeable functions, argument definition, and cumulative behavior. This enables filters to modify the flow of the application dynamically during runtime based on predefined business logic or conditions. 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 filter execution process follows these steps: -1. A function or method (caller) invokes the filter by calling the ``run_filter()`` method provided by the ``OpenEdxPublicFilter`` class, passing initial input arguments. -2. The filter's tooling retrieves the configuration from ``OPEN_EDX_FILTERS_CONFIG``, which defines a list of N functions (f0, f1, …, fn-1) that will be executed. -3. The tooling then executes each function in the pipeline sequentially, starting with f0, which processes the input arguments ``args`` and applies the developer’s operations, returning potentially modified arguments. -4. The next function (f1) receives the potentially modified arguments and applies further operations, returning another modified set of arguments. This process continues through the list of functions. -5. Each subsequent function (fi+1) receives the output from the previous function and returns its modified output until all functions have been executed. +#. An application component (caller) invokes the filter by calling the ``run_filter()`` method implemented by the filter definition. -Additionally, at any point in the pipeline, a developer can halt execution by raising an exception, based on conditions defined in the processing logic, to stop further modifications. +#. The ``run_filter`` method calls the pipeline tooling under the hood, which manages the execution of the filter's pipeline. -6. Once the final function (fn-1) has been executed, the final modified arguments are returned to the caller, which may use them for the remaining part of its execution. +#. The filter's tooling retrieves the configuration from ``OPEN_EDX_FILTERS_CONFIG``, which defines a list of N functions (f0, f1, …, fn-1) that will be executed. -Each function in the pipeline has the ability to modify the input data, add new data, or halt execution based on specific conditions, such as raising exceptions if certain criteria are not met. This pipeline structure ensures that complex business logic can be applied during runtime without directly altering the application code. +#. The tooling then executes each function in the pipeline sequentially, starting with ``f0``, which processes the input arguments ``args`` and applies the developer's operations, returning potentially modified arguments. -Here’s an example of a filter in action: +#. The next function ``f1`` receives the potentially modified arguments and applies further operations, returning another modified set of arguments. This process continues through the list of functions. -1. A user enrolls in a course, `triggering the CourseEnrollmentStarted filter`_. This filter processes information about the user, course, and enrollment details. -2. The filter tooling executes a series of functions, such as checking user eligibility for enrollment, updating the enrollment status, and notifying the user about the enrollment. -3. Each function can modify the input data or halt the process based on business logic (e.g., denying enrollment if the user is ineligible). -4. The final output of the pipeline, such as the updated enrollment details, is returned to the caller, or an exception is raised if the user is not eligible. -5. The process is complete once all functions in the pipeline have executed. +#. Each subsequent function ``fi+1`` receives the output from the previous function and returns its modified output until all functions have been executed. -By organizing this workflow through a pipeline, Open edX Filters allow developers to extend platform functionality in a flexible and maintainable way. +#. Additionally, at any point in the pipeline, a developer can halt execution by raising an exception, based on conditions defined in the processing logic, to stop further modifications. -.. _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 -.. _Python Social Auth: https://python-social-auth.readthedocs.io/en/latest/pipeline.html +#. Once the final function ``fn-1`` has been executed, the final modified arguments are returned to the caller, which may use them for the remaining part of its execution. + +Each function in the pipeline has the ability to modify the input data, add new data, or halt execution based on specific conditions, such as raising exceptions if certain criteria is not met. This pipeline structure ensures that complex business logic can be applied during runtime without directly altering the application code. + +Here's an example of a filter in action: + +#. A user enrolls in a course, `triggering the CourseEnrollmentStarted filter`_ by calling the ``run_filter`` method with the enrollment details. This filter processes information about the user, course, and enrollment details. + +#. The filter tooling executes a series of functions configured in ``OPEN_EDX_FILTERS_CONFIG``, e.g. checking user eligibility for enrollment, updating the enrollment status, and notifying the user about the enrollment. + +#. Each function can modify the input data or halt the process based on business logic, e.g. denying enrollment if the user is ineligible. + +#. The final output of the pipeline, such as the updated enrollment details, is returned to the caller, or an exception is raised if the user is not eligible. + +#. The process is complete once all functions in the pipeline have executed, and the application continues its execution based on the final output. + +By organizing this workflow through a pipeline, Open edX Filters allow developers to extend platform functionality in a flexible and maintainable way. How are Open edX Filters used? ------------------------------ -Developers can implement functions in a plugin, configure them for a particular filter in the ``OPEN_EDX_FILTERS_CONFIG`` setting, midifying the application flow when a the filter in question is invoked by the process in execution. These functions can the application's behavior by altering data, adding new data, or stopping execution by raising exceptions. For example, a filter can stop a student’s enrollment if certain conditions, such as business rules, are not met. +Developers can implement functions in a plugin, configure them for a particular filter in the ``OPEN_EDX_FILTERS_CONFIG`` setting, modifying the application flow when a the filter in question is invoked by the process in execution. These functions can the application's behavior by altering data, adding new data, or stopping execution by raising exceptions. For example, a filter can stop a student's enrollment if certain conditions, such as business rules, are not met. For more information on how to use Open edX Filters, refer to the `Using Open edX Filters`_ how-to guide. + +.. _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 +.. _Python Social Auth: https://python-social-auth.readthedocs.io/en/latest/pipeline.html +.. _OpenEdxPublicFilter: https://github.com/openedx/openedx-filters/blob/main/openedx_filters/tooling.py#L14-L15 From e64b725adf04c79e67f105e9c956116b21b310b0 Mon Sep 17 00:00:00 2001 From: Maria Grimaldi Date: Mon, 4 Nov 2024 20:25:02 +0100 Subject: [PATCH 10/15] refactor: use math directive to reference pipeline functions --- docs/concepts/openedx-filters.rst | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/docs/concepts/openedx-filters.rst b/docs/concepts/openedx-filters.rst index 31934258..9502475b 100644 --- a/docs/concepts/openedx-filters.rst +++ b/docs/concepts/openedx-filters.rst @@ -24,17 +24,17 @@ Open edX Filters are implemented using an accumulative pipeline mechanism, which #. The ``run_filter`` method calls the pipeline tooling under the hood, which manages the execution of the filter's pipeline. -#. The filter's tooling retrieves the configuration from ``OPEN_EDX_FILTERS_CONFIG``, which defines a list of N functions (f0, f1, …, fn-1) that will be executed. +#. The filter's tooling retrieves the configuration from ``OPEN_EDX_FILTERS_CONFIG``, which defines a list of N functions :math:`f_0, f_1, \ldots, f_{n-1}` that will be executed. -#. The tooling then executes each function in the pipeline sequentially, starting with ``f0``, which processes the input arguments ``args`` and applies the developer's operations, returning potentially modified arguments. +#. The tooling then executes each function in the pipeline sequentially, starting with :math:`f_0`, which processes the input arguments ``args`` and applies the developer's operations, returning potentially modified arguments. -#. The next function ``f1`` receives the potentially modified arguments and applies further operations, returning another modified set of arguments. This process continues through the list of functions. +#. The next function :math:`f_0` receives the potentially modified arguments and applies further operations, returning another modified set of arguments. This process continues through the list of functions. -#. Each subsequent function ``fi+1`` receives the output from the previous function and returns its modified output until all functions have been executed. +#. Each subsequent function :math:`f_{i+1}` receives the output from the previous function and returns its modified output until all functions have been executed. #. Additionally, at any point in the pipeline, a developer can halt execution by raising an exception, based on conditions defined in the processing logic, to stop further modifications. -#. Once the final function ``fn-1`` has been executed, the final modified arguments are returned to the caller, which may use them for the remaining part of its execution. +#. Once the final function :math:`f_{n-1}` has been executed, the final modified arguments are returned to the caller, which may use them for the remaining part of its execution. Each function in the pipeline has the ability to modify the input data, add new data, or halt execution based on specific conditions, such as raising exceptions if certain criteria is not met. This pipeline structure ensures that complex business logic can be applied during runtime without directly altering the application code. From f0f3e5c0427354341d542ad1b2c867b43a4c8c43 Mon Sep 17 00:00:00 2001 From: Maria Grimaldi Date: Mon, 4 Nov 2024 20:29:16 +0100 Subject: [PATCH 11/15] refactor: improve wording --- docs/concepts/openedx-filters.rst | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/docs/concepts/openedx-filters.rst b/docs/concepts/openedx-filters.rst index 9502475b..3985f213 100644 --- a/docs/concepts/openedx-filters.rst +++ b/docs/concepts/openedx-filters.rst @@ -32,7 +32,7 @@ Open edX Filters are implemented using an accumulative pipeline mechanism, which #. Each subsequent function :math:`f_{i+1}` receives the output from the previous function and returns its modified output until all functions have been executed. -#. Additionally, at any point in the pipeline, a developer can halt execution by raising an exception, based on conditions defined in the processing logic, to stop further modifications. +#. Additionally, at any point in the pipeline, a developer can halt execution by raising an exception, based on conditions defined in the processing logic, to stop the application flow. #. Once the final function :math:`f_{n-1}` has been executed, the final modified arguments are returned to the caller, which may use them for the remaining part of its execution. @@ -40,7 +40,7 @@ Each function in the pipeline has the ability to modify the input data, add new Here's an example of a filter in action: -#. A user enrolls in a course, `triggering the CourseEnrollmentStarted filter`_ by calling the ``run_filter`` method with the enrollment details. This filter processes information about the user, course, and enrollment details. +#. A user enrolls in a course, triggering the `CourseEnrollmentStarted filter`_ by calling the ``run_filter`` method with the enrollment details. This filter processes information about the user, course, and enrollment details. #. The filter tooling executes a series of functions configured in ``OPEN_EDX_FILTERS_CONFIG``, e.g. checking user eligibility for enrollment, updating the enrollment status, and notifying the user about the enrollment. @@ -48,7 +48,7 @@ Here's an example of a filter in action: #. The final output of the pipeline, such as the updated enrollment details, is returned to the caller, or an exception is raised if the user is not eligible. -#. The process is complete once all functions in the pipeline have executed, and the application continues its execution based on the final output. +#. The process is complete once all functions in the pipeline have executed, and the enrollment process continues based on the final output. By organizing this workflow through a pipeline, Open edX Filters allow developers to extend platform functionality in a flexible and maintainable way. @@ -62,6 +62,6 @@ For more information on how to use Open edX Filters, refer to the `Using Open ed .. _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 +.. _CourseEnrollmentStarted filter: https://github.com/openedx/edx-platform/blob/master/common/djangoapps/student/models/course_enrollment.py#L719-L724 .. _Python Social Auth: https://python-social-auth.readthedocs.io/en/latest/pipeline.html .. _OpenEdxPublicFilter: https://github.com/openedx/openedx-filters/blob/main/openedx_filters/tooling.py#L14-L15 From 2f63edf5bb05d8d991f93f4ebab2104c7308ff83 Mon Sep 17 00:00:00 2001 From: Maria Grimaldi Date: Mon, 4 Nov 2024 20:43:14 +0100 Subject: [PATCH 12/15] refactor: add reference to django plugins --- docs/concepts/openedx-filters.rst | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/docs/concepts/openedx-filters.rst b/docs/concepts/openedx-filters.rst index 3985f213..1de8bbcc 100644 --- a/docs/concepts/openedx-filters.rst +++ b/docs/concepts/openedx-filters.rst @@ -55,7 +55,7 @@ By organizing this workflow through a pipeline, Open edX Filters allow developer How are Open edX Filters used? ------------------------------ -Developers can implement functions in a plugin, configure them for a particular filter in the ``OPEN_EDX_FILTERS_CONFIG`` setting, modifying the application flow when a the filter in question is invoked by the process in execution. These functions can the application's behavior by altering data, adding new data, or stopping execution by raising exceptions. For example, a filter can stop a student's enrollment if certain conditions, such as business rules, are not met. +Developers can implement functions in an `Open edX Django plugin`_, configure them for a particular filter in the ``OPEN_EDX_FILTERS_CONFIG`` setting, modifying the application flow when a the filter in question is invoked by the process in execution. These functions can the application's behavior by altering data, adding new data, or stopping execution by raising exceptions. For example, a filter can stop a student's enrollment if certain conditions, such as business rules, are not met. For more information on how to use Open edX Filters, refer to the `Using Open edX Filters`_ how-to guide. @@ -65,3 +65,4 @@ For more information on how to use Open edX Filters, refer to the `Using Open ed .. _CourseEnrollmentStarted filter: https://github.com/openedx/edx-platform/blob/master/common/djangoapps/student/models/course_enrollment.py#L719-L724 .. _Python Social Auth: https://python-social-auth.readthedocs.io/en/latest/pipeline.html .. _OpenEdxPublicFilter: https://github.com/openedx/openedx-filters/blob/main/openedx_filters/tooling.py#L14-L15 +.. _Open edX Django plugin: https://edx.readthedocs.io/projects/edx-django-utils/en/latest/plugins/readme.html From 3b5f4231d9d7bdf5f44559161e7adb1b32a1caec Mon Sep 17 00:00:00 2001 From: Maria Grimaldi Date: Mon, 18 Nov 2024 21:15:24 +0100 Subject: [PATCH 13/15] refactor: address PR reviews --- docs/concepts/openedx-filters.rst | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/docs/concepts/openedx-filters.rst b/docs/concepts/openedx-filters.rst index 1de8bbcc..4ab1b0af 100644 --- a/docs/concepts/openedx-filters.rst +++ b/docs/concepts/openedx-filters.rst @@ -13,7 +13,7 @@ What are Open edX Filters? An Open edX Filter is a pipeline mechanism that executes a series of functions when configured. Each function receives input arguments, which are data used by the process in execution, and returns the same arguments, possibly modified. Given this design, filters can modify the application flow according to the specified configuration, altering or adding new behaviors during execution time. -The pipeline mechanism is implemented by a class called `OpenEdxPublicFilter`_, which provides the necessary tools to fulfill the Open edX Filters requirements, such as ordered execution, configurability, interchangeable functions, argument definition, and cumulative behavior. This enables filters to modify the flow of the application dynamically during runtime based on predefined business logic or conditions. +The pipeline mechanism is implemented by a class called `OpenEdxPublicFilter`_, which provides the necessary tools to fulfill the Open edX Filters requirements, such as ordered execution, configurability, interchangeable functions, argument definition, and cumulative behavior. This enables filters to modify the flow of the application dynamically during runtime based on predefined business logic or conditions. We refer to the pipeline mechanism as the **Pipeline Tooling** throughout this document. How do Open edX Filters work? ----------------------------- @@ -22,15 +22,15 @@ Open edX Filters are implemented using an accumulative pipeline mechanism, which #. An application component (caller) invokes the filter by calling the ``run_filter()`` method implemented by the filter definition. -#. The ``run_filter`` method calls the pipeline tooling under the hood, which manages the execution of the filter's pipeline. +#. The ``run_filter`` method calls the **Pipeline Tooling** under the hood, which manages the execution of the filter's pipeline. -#. The filter's tooling retrieves the configuration from ``OPEN_EDX_FILTERS_CONFIG``, which defines a list of N functions :math:`f_0, f_1, \ldots, f_{n-1}` that will be executed. +#. The filter's tooling retrieves the configuration from ``OPEN_EDX_FILTERS_CONFIG``, which defines a list of N functions :math::math:`f_0, f_1, \ldots, f_{n-1}` that will be executed. -#. The tooling then executes each function in the pipeline sequentially, starting with :math:`f_0`, which processes the input arguments ``args`` and applies the developer's operations, returning potentially modified arguments. +#. The tooling then executes each function in the pipeline sequentially, starting with :math:`f_0`, which processes the input arguments and applies the developer's operations, returning potentially modified arguments. -#. The next function :math:`f_0` receives the potentially modified arguments and applies further operations, returning another modified set of arguments. This process continues through the list of functions. +#. The next function (if there are more than one) :math:`f_1` receives the potentially modified arguments and applies further operations, returning another modified set of arguments. This process continues through the list of functions. -#. Each subsequent function :math:`f_{i+1}` receives the output from the previous function and returns its modified output until all functions have been executed. +#. Each subsequent function receives the output from the previous function and returns its modified output until all functions have been executed. #. Additionally, at any point in the pipeline, a developer can halt execution by raising an exception, based on conditions defined in the processing logic, to stop the application flow. @@ -55,7 +55,7 @@ By organizing this workflow through a pipeline, Open edX Filters allow developer How are Open edX Filters used? ------------------------------ -Developers can implement functions in an `Open edX Django plugin`_, configure them for a particular filter in the ``OPEN_EDX_FILTERS_CONFIG`` setting, modifying the application flow when a the filter in question is invoked by the process in execution. These functions can the application's behavior by altering data, adding new data, or stopping execution by raising exceptions. For example, a filter can stop a student's enrollment if certain conditions, such as business rules, are not met. +Developers can implement functions in an `Open edX Django plugin`_, configure them for a particular filter in the ``OPEN_EDX_FILTERS_CONFIG`` setting, and modify the application flow when a the filter in question is invoked by the process in execution. These functions can the application's behavior by altering data, adding new data, or stopping execution by raising exceptions. For example, a filter can stop a student's enrollment if certain conditions, such as business rules, are not met. For more information on how to use Open edX Filters, refer to the `Using Open edX Filters`_ how-to guide. From 22e3382c32f5de445f734f171669d76494d8d9ad Mon Sep 17 00:00:00 2001 From: Maria Grimaldi Date: Mon, 18 Nov 2024 21:21:10 +0100 Subject: [PATCH 14/15] refactor: address PR reviews --- docs/concepts/openedx-filters.rst | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/docs/concepts/openedx-filters.rst b/docs/concepts/openedx-filters.rst index 4ab1b0af..20631261 100644 --- a/docs/concepts/openedx-filters.rst +++ b/docs/concepts/openedx-filters.rst @@ -24,17 +24,17 @@ Open edX Filters are implemented using an accumulative pipeline mechanism, which #. The ``run_filter`` method calls the **Pipeline Tooling** under the hood, which manages the execution of the filter's pipeline. -#. The filter's tooling retrieves the configuration from ``OPEN_EDX_FILTERS_CONFIG``, which defines a list of N functions :math::math:`f_0, f_1, \ldots, f_{n-1}` that will be executed. +#. The filter's tooling retrieves the configuration from ``OPEN_EDX_FILTERS_CONFIG``, which defines a list of N functions :math::math:`f_1, f_2, \ldots, f_{n}` that will be executed. -#. The tooling then executes each function in the pipeline sequentially, starting with :math:`f_0`, which processes the input arguments and applies the developer's operations, returning potentially modified arguments. +#. The tooling then executes each function in the pipeline sequentially, starting with :math:`f_1`, which processes the input arguments and applies the developer's operations, returning potentially modified arguments. -#. The next function (if there are more than one) :math:`f_1` receives the potentially modified arguments and applies further operations, returning another modified set of arguments. This process continues through the list of functions. +#. The next function (if there are more than one) :math:`f_2` receives the potentially modified arguments and applies further operations, returning another modified set of arguments. This process continues through the list of functions. #. Each subsequent function receives the output from the previous function and returns its modified output until all functions have been executed. #. Additionally, at any point in the pipeline, a developer can halt execution by raising an exception, based on conditions defined in the processing logic, to stop the application flow. -#. Once the final function :math:`f_{n-1}` has been executed, the final modified arguments are returned to the caller, which may use them for the remaining part of its execution. +#. Once the final function :math:`f_{n}` has been executed, the final modified arguments are returned to the caller, which may use them for the remaining part of its execution. Each function in the pipeline has the ability to modify the input data, add new data, or halt execution based on specific conditions, such as raising exceptions if certain criteria is not met. This pipeline structure ensures that complex business logic can be applied during runtime without directly altering the application code. From 64f6c5cc17f793648e7a7135121f4fb683b4645b Mon Sep 17 00:00:00 2001 From: Maria Grimaldi Date: Mon, 18 Nov 2024 21:21:59 +0100 Subject: [PATCH 15/15] fix: remove unnecessary math directive --- docs/concepts/openedx-filters.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/concepts/openedx-filters.rst b/docs/concepts/openedx-filters.rst index 20631261..2f319df8 100644 --- a/docs/concepts/openedx-filters.rst +++ b/docs/concepts/openedx-filters.rst @@ -24,7 +24,7 @@ Open edX Filters are implemented using an accumulative pipeline mechanism, which #. The ``run_filter`` method calls the **Pipeline Tooling** under the hood, which manages the execution of the filter's pipeline. -#. The filter's tooling retrieves the configuration from ``OPEN_EDX_FILTERS_CONFIG``, which defines a list of N functions :math::math:`f_1, f_2, \ldots, f_{n}` that will be executed. +#. The filter's tooling retrieves the configuration from ``OPEN_EDX_FILTERS_CONFIG``, which defines a list of N functions :math:`f_1, f_2, \ldots, f_{n}` that will be executed. #. The tooling then executes each function in the pipeline sequentially, starting with :math:`f_1`, which processes the input arguments and applies the developer's operations, returning potentially modified arguments.