chore: [FC-0074] drop hooks docs in favor of latest in docs.openedx.org (#35921)

This commit is contained in:
Maria Grimaldi
2024-12-11 19:22:57 +01:00
committed by GitHub
parent 3e9158e9a8
commit f96f92677f
6 changed files with 21 additions and 508 deletions

View File

@@ -139,10 +139,10 @@ Here are the different integration points that python plugins can use:
- This decorator allows overriding any function or method by pointing to an alternative implementation in settings. Read the |pluggable_override docstring|_ to learn more.
* - Open edX Events
- Adopt, Stable
- Events are part of the greater Hooks Extension Framework for open extension of edx-platform. Events are a stable way for plugin developers to react to learner or author events. They are defined by a `separate events library`_ that developers can include in their requirements to develop and test the code without creating a dependency on this large repo. For more information see the `hooks guide`_.
- Events are part of the greater Hooks Extension Framework for open extension of edx-platform. Events are a stable way for plugin developers to react to learner or author events. They are defined by a `separate events library`_ that developers can include in their requirements to develop and test the code without creating a dependency on this large repo. For more information see the `Hooks Extension Framework docs`_ or for more detailed documentation about Open edX Events, see the `Open edX Events documentation`_.
* - Open edX Filters
- Adopt, Stable
- Filters are also part of Hooks Extension Framework for open extension of edx-platform. Filters are a flexible way for plugin developers to modify learner or author application flows. They are defined by a `separate filters library`_ that developers can include in their requirements to develop and test the code without creating a dependency on this large repo. For more information see the `hooks guide`_.
- Filters are also part of Hooks Extension Framework for open extension of edx-platform. Filters are a flexible way for plugin developers to modify learner or author application flows. They are defined by a `separate filters library`_ that developers can include in their requirements to develop and test the code without creating a dependency on this large repo. For more information see the `Hooks Extension Framework docs`_ or for more detailed documentation about Open edX Filters, see the `Open edX Filters documentation`_.
.. _Application: https://docs.djangoproject.com/en/3.0/ref/applications/
.. _Django app plugin documentation: https://github.com/openedx/edx-platform/blob/master/openedx/core/djangoapps/plugins/README.rst
@@ -159,7 +159,9 @@ Here are the different integration points that python plugins can use:
.. _pluggable_override docstring: https://github.com/openedx/edx-django-utils/blob/master/edx_django_utils/plugins/pluggable_override.py
.. _separate events library: https://github.com/eduNEXT/openedx-events/
.. _separate filters library: https://github.com/eduNEXT/openedx-filters/
.. _hooks guide: https://github.com/openedx/edx-platform/blob/master/docs/guides/hooks/index.rst
.. _Hooks Extension Framework docs: https://docs.openedx.org/en/latest/developers/concepts/hooks_extension_framework.html
.. _Open edX Events documentation: https://docs.openedx.org/projects/openedx-events/en/latest/
.. _Open edX Filters documentation: https://docs.openedx.org/projects/openedx-filters/en/latest/
Platform Look & Feel
====================

View File

@@ -68,6 +68,7 @@ extensions = [
'code_annotations.contrib.sphinx.extensions.featuretoggles',
'code_annotations.contrib.sphinx.extensions.settings',
# 'autoapi.extension', # Temporarily disabled
'sphinx_reredirects',
]
# Temporarily disabling autoapi_dirs and the AutoAPI extension due to performance issues.
@@ -304,6 +305,16 @@ modules = {
# 'xmodule': 'references/docstrings/xmodule',
}
# Mapping permanently moved pages to appropriate new location outside of edx-platform
# with by sphinx-reredirects extension redirects.
# More information: https://documatt.com/sphinx-reredirects/usage.html
redirects = {
'hooks/events': 'https://docs.openedx.org/projects/openedx-events/en/latest/',
'hooks/filters': 'https://docs.openedx.org/projects/openedx-filters/en/latest/',
'hooks/index': 'https://docs.openedx.org/en/latest/developers/concepts/hooks_extension_framework.html',
}
def update_settings_module(service='lms'):
"""

View File

@@ -1,261 +0,0 @@
Open edX Events
===============
How to use
----------
Using openedx-events in your code is very straight forward. We can consider the
two possible cases, sending or receiving an event.
Receiving events
^^^^^^^^^^^^^^^^
This is one of the most common use cases for plugins. The edx-platform will send
an event and you want to react to it in your plugin.
For this you need to:
1. Include openedx-events in your dependencies.
2. Connect your receiver functions to the signals being sent.
Connecting signals can be done using regular django syntax:
.. code-block:: python
from openedx_events.learning.signals import SESSION_LOGIN_COMPLETED
@receiver(SESSION_LOGIN_COMPLETED)
# your receiver function here
Or at the apps.py
.. code-block:: python
"signals_config": {
"lms.djangoapp": {
"relative_path": "your_module_name",
"receivers": [
{
"receiver_func_name": "your_receiver_function",
"signal_path": "openedx_events.learning.signals.SESSION_LOGIN_COMPLETED",
},
],
}
},
In case you are listening to an event in the edx-platform repo, you can directly
use the django syntax since the apps.py method will not be available without the
plugin.
Sending events
^^^^^^^^^^^^^^
Sending events requires you to import both the event definition as well as the
attr data classes that encapsulate the event data.
.. code-block:: python
from openedx_events.learning.data import UserData, UserPersonalData
from openedx_events.learning.signals import STUDENT_REGISTRATION_COMPLETED
STUDENT_REGISTRATION_COMPLETED.send_event(
user=UserData(
pii=UserPersonalData(
username=user.username,
email=user.email,
name=user.profile.name,
),
id=user.id,
is_active=user.is_active,
),
)
You can do this both from the edx-platform code as well as from an openedx
plugin.
Testing events
^^^^^^^^^^^^^^
Testing your code in CI, specially for plugins is now possible without having to
import the complete edx-platform as a dependency.
To test your functions you need to include the openedx-events library in your
testing dependencies and make the signal connection in your test case.
.. code-block:: python
from openedx_events.learning.signals import STUDENT_REGISTRATION_COMPLETED
def test_your_receiver(self):
STUDENT_REGISTRATION_COMPLETED.connect(your_function)
STUDENT_REGISTRATION_COMPLETED.send_event(
user=UserData(
pii=UserPersonalData(
username='test_username',
email='test_email@example.com',
name='test_name',
),
id=1,
is_active=True,
),
)
# run your assertions
Changes in the openedx-events library that are not compatible with your code
should break this kind of test in CI and let you know you need to upgrade your
code.
Live example
^^^^^^^^^^^^
For a complete and detailed example you can see the `openedx-events-2-zapier`_
plugin. This is a fully functional plugin that connects to
``STUDENT_REGISTRATION_COMPLETED`` and ``COURSE_ENROLLMENT_CREATED`` and sends
the relevant information to zapier.com using a webhook.
.. _openedx-events-2-zapier: https://github.com/eduNEXT/openedx-events-2-zapier
Index of Events
-----------------
This list contains the events currently being sent by edx-platform. The provided
links target both the definition of the event in the openedx-events library as
well as the trigger location in this same repository.
Learning Events
^^^^^^^^^^^^^^^
.. list-table::
:widths: 35 50 20
* - *Name*
- *Type*
- *Date added*
* - `STUDENT_REGISTRATION_COMPLETED <https://github.com/eduNEXT/openedx-events/blob/main/openedx_events/learning/signals.py#L24>`_
- org.openedx.learning.student.registration.completed.v1
- `2022-06-14 <https://github.com/openedx/edx-platform/blob/master/openedx/core/djangoapps/user_authn/views/register.py#L262>`_
* - `SESSION_LOGIN_COMPLETED <https://github.com/eduNEXT/openedx-events/blob/main/openedx_events/learning/signals.py#L36>`_
- org.openedx.learning.auth.session.login.completed.v1
- `2022-06-14 <https://github.com/openedx/edx-platform/blob/master/openedx/core/djangoapps/user_authn/views/login.py#L320>`_
* - `COURSE_ENROLLMENT_CREATED <https://github.com/eduNEXT/openedx-events/blob/main/openedx_events/learning/signals.py#L48>`_
- org.openedx.learning.course.enrollment.created.v1
- `2022-06-14 <https://github.com/openedx/edx-platform/blob/master/common/djangoapps/student/models.py#L1671>`_
* - `COURSE_ENROLLMENT_CHANGED <https://github.com/eduNEXT/openedx-events/blob/main/openedx_events/learning/signals.py#L60>`_
- org.openedx.learning.course.enrollment.changed.v1
- `2022-06-14 <https://github.com/openedx/edx-platform/blob/master/common/djangoapps/student/models.py#L1430>`_
* - `COURSE_UNENROLLMENT_COMPLETED <https://github.com/eduNEXT/openedx-events/blob/main/openedx_events/learning/signals.py#L72>`_
- org.openedx.learning.course.unenrollment.completed.v1
- `2022-06-14 <https://github.com/openedx/edx-platform/blob/master/common/djangoapps/student/models.py#L1457>`_
* - `CERTIFICATE_CREATED <https://github.com/eduNEXT/openedx-events/blob/main/openedx_events/learning/signals.py#L84>`_
- org.openedx.learning.certificate.created.v1
- `2022-06-14 <https://github.com/openedx/edx-platform/blob/master/lms/djangoapps/certificates/models.py#L514>`_
* - `CERTIFICATE_CHANGED <https://github.com/eduNEXT/openedx-events/blob/main/openedx_events/learning/signals.py#L94>`_
- org.openedx.learning.certificate.changed.v1
- `2022-06-14 <https://github.com/openedx/edx-platform/blob/master/lms/djangoapps/certificates/models.py#L482>`_
* - `CERTIFICATE_REVOKED <https://github.com/eduNEXT/openedx-events/blob/main/openedx_events/learning/signals.py#L108>`_
- org.openedx.learning.certificate.revoked.v1
- `2022-06-14 <https://github.com/openedx/edx-platform/blob/master/lms/djangoapps/certificates/models.py#L402>`_
* - `COHORT_MEMBERSHIP_CHANGED <https://github.com/eduNEXT/openedx-events/blob/main/openedx_events/learning/signals.py#L120>`_
- org.openedx.learning.cohort_membership.changed.v1
- `2022-06-14 <https://github.com/openedx/edx-platform/blob/master/openedx/core/djangoapps/course_groups/models.py#L166>`_
* - `COURSE_DISCUSSIONS_CHANGED <https://github.com/eduNEXT/openedx-events/blob/main/openedx_events/learning/signals.py#L132>`_
- org.openedx.learning.discussions.configuration.changed.v1
- `2022-06-14 <https://github.com/openedx/edx-platform/blob/master/openedx/core/djangoapps/discussions/tasks.py#L30>`_
Content Authoring Events
^^^^^^^^^^^^^^^^^^^^^^^^
.. list-table::
:widths: 35 50 20
* - *Name*
- *Type*
- *Date added*
* - `COURSE_CATALOG_INFO_CHANGED <https://github.com/openedx/openedx-events/blob/c0eb4ba1a3d7d066d58e5c87920b8ccb0645f769/openedx_events/content_authoring/signals.py#L25>`_
- org.openedx.content_authoring.course.catalog_info.changed.v1
- `2022-08-24 <https://github.com/openedx/edx-platform/blob/a8598fa1fac5e26ac212aa588e8527e727581742/cms/djangoapps/contentstore/signals/handlers.py#L111>`_
* - `XBLOCK_PUBLISHED <https://github.com/openedx/openedx-events/blob/c0eb4ba1a3d7d066d58e5c87920b8ccb0645f769/openedx_events/content_authoring/signals.py#L63>`_
- org.openedx.content_authoring.xblock.published.v1
- `2022-12-06 <https://github.com/openedx/edx-platform/blob/master/xmodule/modulestore/mixed.py#L926>`_
* - `XBLOCK_DELETED <https://github.com/openedx/openedx-events/blob/c0eb4ba1a3d7d066d58e5c87920b8ccb0645f769/openedx_events/content_authoring/signals.py#L75>`_
- org.openedx.content_authoring.xblock.deleted.v1
- `2022-12-06 <https://github.com/openedx/edx-platform/blob/master/xmodule/modulestore/mixed.py#L804>`_
* - `XBLOCK_DUPLICATED <https://github.com/openedx/openedx-events/blob/c0eb4ba1a3d7d066d58e5c87920b8ccb0645f769/openedx_events/content_authoring/signals.py#L87>`_
- org.openedx.content_authoring.xblock.duplicated.v1
- `2022-12-06 <https://github.com/openedx/edx-platform/blob/master/cms/djangoapps/contentstore/views/item.py#L965>`_
* - `XBLOCK_CREATED <https://github.com/openedx/openedx-events/blob/c0eb4ba1a3d7d066d58e5c87920b8ccb0645f769/openedx_events/content_authoring/signals.py#L36>`_
- org.openedx.content_authoring.xblock.created.v1
- 2023-07-20
* - `XBLOCK_UPDATED <https://github.com/openedx/openedx-events/blob/c0eb4ba1a3d7d066d58e5c87920b8ccb0645f769/openedx_events/content_authoring/signals.py#L47>`_
- org.openedx.content_authoring.xblock.updated.v1
- 2023-07-20
* - `COURSE_CREATED <https://github.com/openedx/openedx-events/blob/c0eb4ba1a3d7d066d58e5c87920b8ccb0645f769/openedx_events/content_authoring/signals.py#L123>`_
- org.openedx.content_authoring.course.created.v1
- 2023-07-20
* - `CONTENT_LIBRARY_CREATED <https://github.com/openedx/openedx-events/blob/c0eb4ba1a3d7d066d58e5c87920b8ccb0645f769/openedx_events/content_authoring/signals.py#L134>`_
- org.openedx.content_authoring.content_library.created.v1
- 2023-07-20
* - `CONTENT_LIBRARY_UPDATED <https://github.com/openedx/openedx-events/blob/c0eb4ba1a3d7d066d58e5c87920b8ccb0645f769/openedx_events/content_authoring/signals.py#L145>`_
- org.openedx.content_authoring.content_library.updated.v1
- 2023-07-20
* - `CONTENT_LIBRARY_DELETED <https://github.com/openedx/openedx-events/blob/c0eb4ba1a3d7d066d58e5c87920b8ccb0645f769/openedx_events/content_authoring/signals.py#L156>`_
- org.openedx.content_authoring.content_library.deleted.v1
- 2023-07-20
* - `LIBRARY_BLOCK_CREATED <https://github.com/openedx/openedx-events/blob/c0eb4ba1a3d7d066d58e5c87920b8ccb0645f769/openedx_events/content_authoring/signals.py#L167>`_
- org.openedx.content_authoring.library_block.created.v1
- 2023-07-20
* - `LIBRARY_BLOCK_UPDATED <https://github.com/openedx/openedx-events/blob/c0eb4ba1a3d7d066d58e5c87920b8ccb0645f769/openedx_events/content_authoring/signals.py#L178>`_
- org.openedx.content_authoring.library_block.updated.v1
- 2023-07-20
* - `LIBRARY_BLOCK_DELETED <https://github.com/openedx/openedx-events/blob/c0eb4ba1a3d7d066d58e5c87920b8ccb0645f769/openedx_events/content_authoring/signals.py#L189>`_
- org.openedx.content_authoring.library_block.deleted.v1
- 2023-07-20
* - `LIBRARY_COLLECTION_CREATED <https://github.com/openedx/openedx-events/blob/main/openedx_events/content_authoring/signals.py#L219>`_
- org.openedx.content_authoring.content_library.collection.created.v1
- 2024-08-23
* - `LIBRARY_COLLECTION_UPDATED <https://github.com/openedx/openedx-events/blob/main/openedx_events/content_authoring/signals.py#L230>`_
- org.openedx.content_authoring.content_library.collection.updated.v1
- 2024-08-23
* - `LIBRARY_COLLECTION_DELETED <https://github.com/openedx/openedx-events/blob/main/openedx_events/content_authoring/signals.py#L241>`_
- org.openedx.content_authoring.content_library.collection.deleted.v1
- 2024-08-23
* - `CONTENT_OBJECT_ASSOCIATIONS_CHANGED <https://github.com/openedx/openedx-events/blob/eb17e03f075b272ad8a29e8435d6a514f8884131/openedx_events/content_authoring/signals.py#L205-L214>`_
- org.openedx.content_authoring.content.object.associations.changed.v1
- 2024-09-06

View File

@@ -1,191 +0,0 @@
Open edX Filters
================
How to use
----------
Using openedx-filters in your code is very straight forward. We can consider the
two possible cases:
Configuring a filter
^^^^^^^^^^^^^^^^^^^^
Implement pipeline steps
************************
Let's say you want to consult student's information with a third party service
before generating the students certificate. This is a common use case for filters,
where the functions part of the filter's pipeline will perform the consulting tasks and
decide the execution flow for the application. These functions are the pipeline steps,
and can be implemented in an installable Python library:
.. code-block:: python
# Step implementation taken from openedx-filters-samples plugin
from openedx_filters import PipelineStep
from openedx_filters.learning.filters import CertificateCreationRequested
class StopCertificateCreation(PipelineStep):
def run_filter(self, user, course_id, mode, status):
# Consult third party service and check if continue
# ...
# User not in third party service, denied certificate generation
raise CertificateCreationRequested.PreventCertificateCreation(
"You can't generate a certificate from this site."
)
There's two key components to the implementation:
1. The filter step must be a subclass of ``PipelineStep``.
2. The ``run_filter`` signature must match the filters definition, eg.,
the previous step matches the method's definition in CertificateCreationRequested.
Attach/hook pipeline to filter
******************************
After implementing the pipeline steps, we have to tell the certificate creation
filter to execute our pipeline.
.. code-block:: python
OPEN_EDX_FILTERS_CONFIG = {
"org.openedx.learning.certificate.creation.requested.v1": {
"fail_silently": False,
"pipeline": [
"openedx_filters_samples.samples.pipeline.StopCertificateCreation"
]
},
}
Triggering a filter
^^^^^^^^^^^^^^^^^^^
In order to execute a filter in your own plugin/library, you must install the
plugin where the steps are implemented and also, ``openedx-filters``.
.. code-block:: python
# Code taken from lms/djangoapps/certificates/generation_handler.py
from openedx_filters.learning.filters import CertificateCreationRequested
try:
self.user, self.course_id, self.mode, self.status = CertificateCreationRequested.run_filter(
user=self.user, course_id=self.course_id, mode=self.mode, status=self.status,
)
except CertificateCreationRequested.PreventCertificateCreation as exc:
raise CertificateGenerationNotAllowed(str(exc)) from exc
Testing filters' steps
^^^^^^^^^^^^^^^^^^^^^^
It's pretty straightforward to test your pipeline steps, you'll need to include the
``openedx-filters`` library in your testing dependencies and configure them in your test case.
.. code-block:: python
from openedx_filters.learning.filters import CertificateCreationRequested
@override_settings(
OPEN_EDX_FILTERS_CONFIG={
"org.openedx.learning.certificate.creation.requested.v1": {
"fail_silently": False,
"pipeline": [
"openedx_filters_samples.samples.pipeline.StopCertificateCreation"
]
}
}
)
def test_certificate_creation_requested_filter(self):
"""
Test filter triggered before the certificate creation process starts.
Expected results:
- The pipeline step configured for the filter raises PreventCertificateCreation
when the conditions are met.
"""
with self.assertRaises(CertificateCreationRequested.PreventCertificateCreation):
CertificateCreationRequested.run_filter(
user=self.user, course_key=self.course_key, mode="audit",
)
# run your assertions
Changes in the ``openedx-filters`` library that are not compatible with your code
should break this kind of test in CI and let you know you need to upgrade your code.
The main limitation while testing filters' steps it's their arguments, as they are edxapp
memory objects, but that can be solved in CI using Python mocks.
Live example
^^^^^^^^^^^^
For filter steps samples you can visit the `openedx-filters-samples`_ plugin, where
you can find minimal steps exemplifying the different ways on how to use
``openedx-filters``.
.. _openedx-filters-samples: https://github.com/eduNEXT/openedx-filters-samples
Index of Filters
-----------------
This list contains the filters currently being executed by edx-platform. The provided
links target both the definition of the filter in the openedx-filters library as
well as the trigger location in this same repository.
.. list-table::
:widths: 35 50 20
* - *Name*
- *Type*
- *Date added*
* - `StudentRegistrationRequested <https://github.com/eduNEXT/openedx-filters/blob/main/openedx_filters/learning/filters.py#L9>`_
- org.openedx.learning.student.registration.requested.v1
- `2022-06-14 <https://github.com/openedx/edx-platform/blob/master/openedx/core/djangoapps/user_authn/views/register.py#L261>`_
* - `StudentLoginRequested <https://github.com/eduNEXT/openedx-filters/blob/main/openedx_filters/learning/filters.py#L40>`_
- org.openedx.learning.student.login.requested.v1
- `2022-06-14 <https://github.com/openedx/edx-platform/blob/master/openedx/core/djangoapps/user_authn/views/login.py#L569>`_
* - `CourseEnrollmentStarted <https://github.com/eduNEXT/openedx-filters/blob/main/openedx_filters/learning/filters.py#L70>`_
- org.openedx.learning.course.enrollment.started.v1
- `2022-06-14 <https://github.com/openedx/edx-platform/blob/master/common/djangoapps/student/models.py#L1675>`_
* - `CourseUnenrollmentStarted <https://github.com/eduNEXT/openedx-filters/blob/main/openedx_filters/learning/filters.py#L98>`_
- org.openedx.learning.course.unenrollment.started.v1
- `2022-06-14 <https://github.com/eduNEXT/edx-platform/blob/master/common/djangoapps/student/models.py#L1752>`_
* - `CertificateCreationRequested <https://github.com/openedx/openedx-filters/blob/main/openedx_filters/learning/filters.py#L142>`_
- org.openedx.learning.certificate.creation.requested.v1
- `2022-06-14 <https://github.com/eduNEXT/edx-platform/blob/master/lms/djangoapps/certificates/generation_handler.py#L119>`_
* - `CertificateRenderStarted <https://github.com/openedx/openedx-filters/blob/main/openedx_filters/learning/filters.py#L161>`_
- org.openedx.learning.certificate.render.started.v1
- `2022-06-14 <https://github.com/eduNEXT/edx-platform/blob/master/lms/djangoapps/certificates/views/webview.py#L649>`_
* - `CohortChangeRequested <https://github.com/openedx/openedx-filters/blob/main/openedx_filters/learning/filters.py#L230>`_
- org.openedx.learning.cohort.change.requested.v1
- `2022-06-14 <https://github.com/eduNEXT/edx-platform/blob/master/openedx/core/djangoapps/course_groups/models.py#L138>`_
* - `CohortAssignmentRequested <https://github.com/openedx/openedx-filters/blob/main/openedx_filters/learning/filters.py#L256>`_
- org.openedx.learning.cohort.assignment.requested.v1
- `2022-06-14 <https://github.com/eduNEXT/edx-platform/blob/master/openedx/core/djangoapps/course_groups/models.py#L149>`_
* - `CourseAboutRenderStarted <https://github.com/openedx/openedx-filters/blob/main/openedx_filters/learning/filters.py#L281>`_
- org.openedx.learning.course_about.render.started.v1
- `2022-06-14 <https://github.com/eduNEXT/edx-platform/blob/master/lms/djangoapps/courseware/views/views.py#L1015>`_
* - `DashboardRenderStarted <https://github.com/openedx/openedx-filters/blob/main/openedx_filters/learning/filters.py#L354>`_
- org.openedx.learning.dashboard.render.started.v1
- `2022-06-14 <https://github.com/eduNEXT/edx-platform/blob/master/common/djangoapps/student/views/dashboard.py#L878>`_
* - `VerticalBlockChildRenderStarted <https://github.com/openedx/openedx-filters/blob/main/openedx_filters/learning/filters.py#L427>`_
- org.openedx.learning.veritical_block_child.render.started.v1
- `2022-08-18 <https://github.com/openedx/edx-platform/blob/master/xmodule/vertical_block.py#L170>`_
* - `VerticalBlockRenderCompleted <https://github.com/openedx/openedx-filters/blob/main/openedx_filters/learning/filters.py#L476>`_
- org.openedx.learning.veritical_block.render.completed.v1
- `2022-02-18 <https://github.com/openedx/edx-platform/blob/master/xmodule/vertical_block.py#L121>`_

View File

@@ -1,50 +0,0 @@
Open edX Hooks Extension Framework
==================================
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.
Context
-------
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, 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.
* openedx-filters (`guide <./filters.rst>`_, `source code <https://github.com/openedx/openedx-filters>`_)
* openedx-events (`guide <./events.rst>`_, `source code <https://github.com/openedx/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 the events, this is 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`_.
.. _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
On the technical side events are implemented through django signals which makes
them run in the same python process as the lms or cms. Furthermore, events block
the running process. Listeners of an event are encouraged to monitor the
performance or use alternative arch patterns such as receiving the event and
defer to launching async tasks than do the slow processing.
On the other hand, 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, process it and returns an output. During
this process, they can alter the application execution flow by halting the process
or modifying their input arguments.

View File

@@ -20,6 +20,7 @@ locations.
.. _Developer Documentation Index: https://openedx.atlassian.net/wiki/spaces/DOC/overview
.. _Open edX Development space: https://openedx.atlassian.net/wiki/spaces/COMM/overview
.. _Open edX ReadTheDocs: http://docs.edx.org/
.. _Hooks Extensions Framework: https://docs.openedx.org/en/latest/developers/concepts/hooks_extension_framework.html
.. toctree::
:maxdepth: 1
@@ -32,7 +33,6 @@ locations.
how-tos/index
references/index
concepts/index
hooks/index
extensions/tinymce_plugins
.. grid:: 1 2 2 2
@@ -80,14 +80,16 @@ locations.
:class-card: sd-shadow-md sd-p-2
:class-footer: sd-border-0
* :doc:`hooks/index`
* `Hooks Extensions Framework`_
* :doc:`extensions/tinymce_plugins`
+++
.. button-ref:: hooks/index
.. button-link:: https://docs.openedx.org/en/latest/developers/concepts/hooks_extension_framework.html
:color: primary
:outline:
:expand:
Hooks Extensions Framework
Change History
**************