docs: add Open edX Events & Filters latest documentation
This commit is contained in:
@@ -140,6 +140,9 @@ Here are the different integration points that python plugins can use:
|
||||
* - 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`_.
|
||||
* - 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`_.
|
||||
|
||||
.. _Application: https://docs.djangoproject.com/en/3.0/ref/applications/
|
||||
.. _Django app plugin documentation: https://github.com/edx/edx-platform/blob/master/openedx/core/djangoapps/plugins/README.rst
|
||||
@@ -155,6 +158,7 @@ Here are the different integration points that python plugins can use:
|
||||
.. |pluggable_override docstring| replace:: ``pluggable_override`` docstring
|
||||
.. _pluggable_override docstring: https://github.com/edx/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/edx/edx-platform/blob/master/docs/guides/hooks/index.rst
|
||||
|
||||
Platform Look & Feel
|
||||
|
||||
179
docs/guides/hooks/events.rst
Normal file
179
docs/guides/hooks/events.rst
Normal file
@@ -0,0 +1,179 @@
|
||||
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
|
||||
and 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.
|
||||
|
||||
|
||||
.. 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/edx/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/edx/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/edx/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/edx/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/edx/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/edx/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/edx/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/edx/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/edx/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>`_
|
||||
183
docs/guides/hooks/filters.rst
Normal file
183
docs/guides/hooks/filters.rst
Normal file
@@ -0,0 +1,183 @@
|
||||
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/edx/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/edx/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>`_
|
||||
@@ -22,8 +22,8 @@ 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`_
|
||||
* `openedx events`_
|
||||
* `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
|
||||
@@ -36,8 +36,8 @@ 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
|
||||
.. _openedx filters: https://github.com/eduNEXT/openedx-filters
|
||||
.. _openedx events: https://github.com/eduNEXT/openedx-events
|
||||
.. _openedx-filters: https://github.com/eduNEXT/openedx-filters
|
||||
.. _openedx-events: https://github.com/eduNEXT/openedx-events
|
||||
|
||||
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
|
||||
@@ -45,176 +45,8 @@ 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.
|
||||
|
||||
|
||||
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
|
||||
and 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.
|
||||
|
||||
|
||||
.. 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#L18>`_
|
||||
- org.openedx.learning.student.registration.completed.v1
|
||||
- `2021-09-02 <https://github.com/edx/edx-platform/blob/master/openedx/core/djangoapps/user_authn/views/register.py#L258>`__
|
||||
|
||||
* - `SESSION_LOGIN_COMPLETED <https://github.com/eduNEXT/openedx-events/blob/main/openedx_events/learning/signals.py#L30>`_
|
||||
- org.openedx.learning.auth.session.login.completed.v1
|
||||
- `2021-09-02 <https://github.com/edx/edx-platform/blob/master/openedx/core/djangoapps/user_authn/views/login.py#L306>`__
|
||||
|
||||
* - `COURSE_ENROLLMENT_CREATED <https://github.com/eduNEXT/openedx-events/blob/main/openedx_events/learning/signals.py#L42>`_
|
||||
- org.openedx.learning.course.enrollment.created.v1
|
||||
- `2021-09-02 <https://github.com/edx/edx-platform/blob/master/common/djangoapps/student/models.py#L1675>`__
|
||||
|
||||
* - `COURSE_ENROLLMENT_CHANGED <https://github.com/eduNEXT/openedx-events/blob/main/openedx_events/learning/signals.py#L54>`_
|
||||
- org.openedx.learning.course.enrollment.changed.v1
|
||||
- `2021-09-22 <https://github.com/edx/edx-platform/blob/master/common/djangoapps/student/models.py#L1675>`__
|
||||
|
||||
* - `COURSE_UNENROLLMENT_COMPLETED <https://github.com/eduNEXT/openedx-events/blob/main/openedx_events/learning/signals.py#L66>`_
|
||||
- org.openedx.learning.course.unenrollment.completed.v1
|
||||
- `2021-09-22 <https://github.com/edx/edx-platform/blob/master/common/djangoapps/student/models.py#L1468>`__
|
||||
|
||||
* - `CERTIFICATE_CREATED <https://github.com/eduNEXT/openedx-events/blob/main/openedx_events/learning/signals.py#L78>`_
|
||||
- org.openedx.learning.certificate.created.v1
|
||||
- `2021-09-22 <https://github.com/edx/edx-platform/blob/master/lms/djangoapps/certificates/models.py#L506>`__
|
||||
|
||||
* - `CERTIFICATE_CHANGED <https://github.com/eduNEXT/openedx-events/blob/main/openedx_events/learning/signals.py#L90>`_
|
||||
- org.openedx.learning.certificate.changed.v1
|
||||
- `2021-09-22 <https://github.com/edx/edx-platform/blob/master/lms/djangoapps/certificates/models.py#L475>`__
|
||||
|
||||
* - `CERTIFICATE_REVOKED <https://github.com/eduNEXT/openedx-events/blob/main/openedx_events/learning/signals.py#L102>`_
|
||||
- org.openedx.learning.certificate.revoked.v1
|
||||
- `2021-09-22 <https://github.com/edx/edx-platform/blob/master/lms/djangoapps/certificates/models.py#L397>`__
|
||||
|
||||
* - `COHORT_MEMBERSHIP_CHANGED <https://github.com/eduNEXT/openedx-events/blob/main/openedx_events/learning/signals.py#L114>`_
|
||||
- org.openedx.learning.cohort_membership.changed.v1
|
||||
- `2021-09-22 <https://github.com/edx/edx-platform/blob/master/openedx/core/djangoapps/course_groups/models.py#L135>`__
|
||||
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.
|
||||
|
||||
Reference in New Issue
Block a user