From 0aeb2c514b6e45a503dae588f66ddafc6863430c Mon Sep 17 00:00:00 2001 From: Maria Grimaldi Date: Wed, 18 Jan 2023 14:50:24 -0400 Subject: [PATCH 01/23] fix: remove sphinx-book-theme incompatible requirement --- requirements/doc.in | 1 - requirements/doc.txt | 1 - 2 files changed, 2 deletions(-) diff --git a/requirements/doc.in b/requirements/doc.in index 717e11ad..eba7bafc 100644 --- a/requirements/doc.in +++ b/requirements/doc.in @@ -8,7 +8,6 @@ edx_sphinx_theme # edX theme for Sphinx output build # Needed for twine command twine # Utility for publishing Python packages on PyPI. sphinx -sphinx-book-theme sphinx-copybutton sphinx-autobuild sphinxcontrib-mermaid diff --git a/requirements/doc.txt b/requirements/doc.txt index e635f702..cef42ce0 100644 --- a/requirements/doc.txt +++ b/requirements/doc.txt @@ -197,7 +197,6 @@ sphinx==5.3.0 # edx-sphinx-theme # pydata-sphinx-theme # sphinx-autobuild - # sphinx-book-theme # sphinx-copybutton # sphinxcontrib-contentui sphinx-autobuild==2021.3.14 From 120435b937955044a81300948b089eeb8320db58 Mon Sep 17 00:00:00 2001 From: Maria Grimaldi Date: Wed, 18 Jan 2023 15:10:39 -0400 Subject: [PATCH 02/23] fix: use pinned version of sphinx-book-theme --- requirements/doc.in | 1 + requirements/doc.txt | 1 + 2 files changed, 2 insertions(+) diff --git a/requirements/doc.in b/requirements/doc.in index eba7bafc..717e11ad 100644 --- a/requirements/doc.in +++ b/requirements/doc.in @@ -8,6 +8,7 @@ edx_sphinx_theme # edX theme for Sphinx output build # Needed for twine command twine # Utility for publishing Python packages on PyPI. sphinx +sphinx-book-theme sphinx-copybutton sphinx-autobuild sphinxcontrib-mermaid diff --git a/requirements/doc.txt b/requirements/doc.txt index cef42ce0..e635f702 100644 --- a/requirements/doc.txt +++ b/requirements/doc.txt @@ -197,6 +197,7 @@ sphinx==5.3.0 # edx-sphinx-theme # pydata-sphinx-theme # sphinx-autobuild + # sphinx-book-theme # sphinx-copybutton # sphinxcontrib-contentui sphinx-autobuild==2021.3.14 From 52e594fa46d85cce45d6f9d90d7290230359d2e0 Mon Sep 17 00:00:00 2001 From: Maria Grimaldi Date: Wed, 20 Jul 2022 13:17:46 -0400 Subject: [PATCH 03/23] docs: add draft of create a new event guide --- docs/how-to/create-new-event.rst | 60 ++++++++++++++++++++++++++++++++ 1 file changed, 60 insertions(+) create mode 100644 docs/how-to/create-new-event.rst diff --git a/docs/how-to/create-new-event.rst b/docs/how-to/create-new-event.rst new file mode 100644 index 00000000..33de9774 --- /dev/null +++ b/docs/how-to/create-new-event.rst @@ -0,0 +1,60 @@ +How to create a new Open edX Event +================================== + +The mechanisms implemented by the Open edX Events library are supported and maintained by the Open edX community. +Therefore, we've put together a guide on how to add a new event to have an effective contribution process. + + +1. Propose the new event to the community +----------------------------------------- + +When creating a new event, you must justify its implementation. For example, you could create a post in Discuss, +send a message through slack or open a new issue in the library repository listing your use cases for it. Or even, +if you have time, you could accompany your proposal with the implementation of the event to illustrate its behavior. + + +2. Create the data attributes for the event (OEP-49) +---------------------------------------------------- + +Events send data attribute instances when triggered. Therefore, when designing your new event definition you must +decided if an existent data attribute class works for your use case or you must create a new one. If the answer is +the latter, then try to answer: + +- Which attributes of the object are the most relevant? +- Which type are they? +- Is any of them optional/required? + +And with that information, create the new class justifying each decision. The class created in this step must comply +with: + +- It should be created in the `data.py` file in the corresponding subdomain. Refer to Naming Conventions ADR for more + on events subdomains. +- It should follow the naming conventions specified in... + +3. Create the event definition +------------------------------ + +Open edX Events are instances of the class OpenEdxPublicSignal, this instance represents the event definition that +specifies: + +- The event type which should follow the conventions in the Naming Conventions ADR. +- The events' payload, here you must use the class you decided on before. + +The definition created in this step must comply with: + +- It should be created in the `signals.py` file in the corresponding subdomain. Refer to Naming Conventions ADR for more + on events subdomains. +- It should follow the naming conventions specified in Naming Conventions ADR. +- It must be documented using in-line documentation with at least: `event_type`, `event_name`, `event_description` and + `event_data`. + +4. Integrate into service +------------------------- + +After or during the events definition implementation, you now must trigger the event in the service you intentioned. Meaning: + +- Add the openedx-events library to the service project. +- Import the events' data and definition into the place where will be triggered. Remember the Open edX Events purpose when + choosing a place to send the new event + +Before opening a PR in the service project, refer to its contribution guidelines. From 49093c963f568386d7bce9e8ae5f6c01221354b3 Mon Sep 17 00:00:00 2001 From: Maria Grimaldi Date: Fri, 12 Aug 2022 15:06:01 -0400 Subject: [PATCH 04/23] fix: address PR comments --- docs/how-to/create-new-event.rst | 128 ++++++++++++++++++++++++++++--- 1 file changed, 117 insertions(+), 11 deletions(-) diff --git a/docs/how-to/create-new-event.rst b/docs/how-to/create-new-event.rst index 33de9774..751d69c3 100644 --- a/docs/how-to/create-new-event.rst +++ b/docs/how-to/create-new-event.rst @@ -12,13 +12,38 @@ When creating a new event, you must justify its implementation. For example, you send a message through slack or open a new issue in the library repository listing your use cases for it. Or even, if you have time, you could accompany your proposal with the implementation of the event to illustrate its behavior. - -2. Create the data attributes for the event (OEP-49) +2. Place your event in an architecture subdomain +------------------------------------------------- + +As specified in the Architectural Decisions Record (ADR) events naming and versioning, the event definition needs an Open edX Architecture +Subdomain for: + +- The name of the event: ``{Reverse DNS}.{Architecture Subdomain}.{Subject}.{Action}.{Major Version}`` +- The package name where the definition will live, eg. ``learning/signals.py`` or `` + +For those reasons, after studying your new event purpose, you must place it in one of the subdomains supported by the project: + ++----------------+----------------------------------------------------------------------------------------------------+ +| Subdomain name | Description | ++================+====================================================================================================+ +| Authoring | Allows educators to create, modify, discover, package, annotate (tag), and share learning content. | ++----------------+----------------------------------------------------------------------------------------------------+ +| Learning | Allows learners to consume content and perform actions in a learning activity on the platform. | ++----------------+----------------------------------------------------------------------------------------------------+ +| Discovery | Allows learners to find the right content at the right time to help achieve their learning goals. | ++----------------+----------------------------------------------------------------------------------------------------+ +| Enterprise | ??? | ++----------------+----------------------------------------------------------------------------------------------------+ +| Programs | Allows educators and learners to manage and engage in bundled packages (programs) of learning. | ++----------------+----------------------------------------------------------------------------------------------------+ + +Refer to `edX DDD Bounded Contexts `_ confluence page for more documentation on domain-driven design in the Open edX project. + +3. Create the data attributes for the event (OEP-49) ---------------------------------------------------- -Events send data attribute instances when triggered. Therefore, when designing your new event definition you must -decided if an existent data attribute class works for your use case or you must create a new one. If the answer is -the latter, then try to answer: +Events send `data attributes `_ when triggered. Therefore, when designing your new event definition you must +decide if an existent data class works for your use case or you must create a new one. If the answer is the latter, then try to answer: - Which attributes of the object are the most relevant? - Which type are they? @@ -27,11 +52,53 @@ the latter, then try to answer: And with that information, create the new class justifying each decision. The class created in this step must comply with: -- It should be created in the `data.py` file in the corresponding subdomain. Refer to Naming Conventions ADR for more +- It should be created in the `data.py` file, as described in the OEP-49, in the corresponding architectural subdomain. Refer to Naming Conventions ADR for more on events subdomains. -- It should follow the naming conventions specified in... - -3. Create the event definition +- It should follow the naming conventions used across the other events definitions. + +Consider the user data representation as an example: + +.. code-block:: python + @attr.s(frozen=True) + class CourseData: + """ + Attributes defined for Open edX Course Overview object. + + Arguments: + course_key (str): identifier of the Course object. + display_name (str): display name associated with the course. + start (datetime): start date for the course. + end (datetime): end date for the course. + """ + + course_key = attr.ib(type=CourseKey) + display_name = attr.ib(type=str, factory=str) + start = attr.ib(type=datetime, default=None) + end = attr.ib(type=datetime, default=None) + + + @attr.s(frozen=True) + class CourseEnrollmentData: + """ + Attributes defined for Open edX Course Enrollment object. + + Arguments: + user (UserData): user associated with the Course Enrollment. + course (CourseData): course where the user is enrolled in. + mode (str): course mode associated with the course. + is_active (bool): whether the enrollment is active. + creation_date (datetime): creation date of the enrollment. + created_by (UserData): if available, who created the enrollment. + """ + + user = attr.ib(type=UserData) + course = attr.ib(type=CourseData) + mode = attr.ib(type=str) + is_active = attr.ib(type=bool) + creation_date = attr.ib(type=datetime) + created_by = attr.ib(type=UserData, default=None) + +4. Create the event definition ------------------------------ Open edX Events are instances of the class OpenEdxPublicSignal, this instance represents the event definition that @@ -48,13 +115,52 @@ The definition created in this step must comply with: - It must be documented using in-line documentation with at least: `event_type`, `event_name`, `event_description` and `event_data`. -4. Integrate into service +Consider the following example: + +.. code-block:: python + # Location openedx_events/learning/signals.py + # .. event_type: org.openedx.learning.course.enrollment.created.v1 + # .. event_name: COURSE_ENROLLMENT_CREATED + # .. event_description: emitted when the user's enrollment process is completed. + # .. event_data: CourseEnrollmentData + COURSE_ENROLLMENT_CREATED = OpenEdxPublicSignal( + event_type="org.openedx.learning.course.enrollment.created.v1", + data={ + "enrollment": CourseEnrollmentData, + } + ) + +5. Integrate into service ------------------------- After or during the events definition implementation, you now must trigger the event in the service you intentioned. Meaning: - Add the openedx-events library to the service project. - Import the events' data and definition into the place where will be triggered. Remember the Open edX Events purpose when - choosing a place to send the new event + choosing a place to send the new event. +- Add inline documentation with the event implemented name. Before opening a PR in the service project, refer to its contribution guidelines. + +Consider the integration of the event ``STUDENT_REGISTRATION_COMPLETED`` as an example: + +.. code-block:: python + # Location openedx/core/djangoapps/user_authn/views/register.py + # .. event_implemented_name: COURSE_ENROLLMENT_CREATED + COURSE_ENROLLMENT_CREATED.send_event( + enrollment=CourseEnrollmentData( + user=UserData( + pii=UserPersonalData( + username=user.username, + email=user.email, + name=user.profile.name, + ), + id=user.id, + is_active=user.is_active, + ), + course=course_data, + mode=enrollment.mode, + is_active=enrollment.is_active, + creation_date=enrollment.created, + ) + ) From 625f691910ca43b116920deb2abdb2df9fcc5f1f Mon Sep 17 00:00:00 2001 From: Maria Grimaldi Date: Fri, 12 Aug 2022 15:08:30 -0400 Subject: [PATCH 05/23] fix: use correct indentation for code --- docs/how-to/create-new-event.rst | 136 +++++++++++++++---------------- 1 file changed, 68 insertions(+), 68 deletions(-) diff --git a/docs/how-to/create-new-event.rst b/docs/how-to/create-new-event.rst index 751d69c3..d01c2f09 100644 --- a/docs/how-to/create-new-event.rst +++ b/docs/how-to/create-new-event.rst @@ -59,44 +59,44 @@ with: Consider the user data representation as an example: .. code-block:: python - @attr.s(frozen=True) - class CourseData: - """ - Attributes defined for Open edX Course Overview object. - - Arguments: - course_key (str): identifier of the Course object. - display_name (str): display name associated with the course. - start (datetime): start date for the course. - end (datetime): end date for the course. - """ - - course_key = attr.ib(type=CourseKey) - display_name = attr.ib(type=str, factory=str) - start = attr.ib(type=datetime, default=None) - end = attr.ib(type=datetime, default=None) - - - @attr.s(frozen=True) - class CourseEnrollmentData: - """ - Attributes defined for Open edX Course Enrollment object. - - Arguments: - user (UserData): user associated with the Course Enrollment. - course (CourseData): course where the user is enrolled in. - mode (str): course mode associated with the course. - is_active (bool): whether the enrollment is active. - creation_date (datetime): creation date of the enrollment. - created_by (UserData): if available, who created the enrollment. - """ - - user = attr.ib(type=UserData) - course = attr.ib(type=CourseData) - mode = attr.ib(type=str) - is_active = attr.ib(type=bool) - creation_date = attr.ib(type=datetime) - created_by = attr.ib(type=UserData, default=None) + @attr.s(frozen=True) + class CourseData: + """ + Attributes defined for Open edX Course Overview object. + + Arguments: + course_key (str): identifier of the Course object. + display_name (str): display name associated with the course. + start (datetime): start date for the course. + end (datetime): end date for the course. + """ + + course_key = attr.ib(type=CourseKey) + display_name = attr.ib(type=str, factory=str) + start = attr.ib(type=datetime, default=None) + end = attr.ib(type=datetime, default=None) + + + @attr.s(frozen=True) + class CourseEnrollmentData: + """ + Attributes defined for Open edX Course Enrollment object. + + Arguments: + user (UserData): user associated with the Course Enrollment. + course (CourseData): course where the user is enrolled in. + mode (str): course mode associated with the course. + is_active (bool): whether the enrollment is active. + creation_date (datetime): creation date of the enrollment. + created_by (UserData): if available, who created the enrollment. + """ + + user = attr.ib(type=UserData) + course = attr.ib(type=CourseData) + mode = attr.ib(type=str) + is_active = attr.ib(type=bool) + creation_date = attr.ib(type=datetime) + created_by = attr.ib(type=UserData, default=None) 4. Create the event definition ------------------------------ @@ -118,17 +118,17 @@ The definition created in this step must comply with: Consider the following example: .. code-block:: python - # Location openedx_events/learning/signals.py - # .. event_type: org.openedx.learning.course.enrollment.created.v1 - # .. event_name: COURSE_ENROLLMENT_CREATED - # .. event_description: emitted when the user's enrollment process is completed. - # .. event_data: CourseEnrollmentData - COURSE_ENROLLMENT_CREATED = OpenEdxPublicSignal( - event_type="org.openedx.learning.course.enrollment.created.v1", - data={ - "enrollment": CourseEnrollmentData, - } - ) + # Location openedx_events/learning/signals.py + # .. event_type: org.openedx.learning.course.enrollment.created.v1 + # .. event_name: COURSE_ENROLLMENT_CREATED + # .. event_description: emitted when the user's enrollment process is completed. + # .. event_data: CourseEnrollmentData + COURSE_ENROLLMENT_CREATED = OpenEdxPublicSignal( + event_type="org.openedx.learning.course.enrollment.created.v1", + data={ + "enrollment": CourseEnrollmentData, + } + ) 5. Integrate into service ------------------------- @@ -145,22 +145,22 @@ Before opening a PR in the service project, refer to its contribution guidelines Consider the integration of the event ``STUDENT_REGISTRATION_COMPLETED`` as an example: .. code-block:: python - # Location openedx/core/djangoapps/user_authn/views/register.py - # .. event_implemented_name: COURSE_ENROLLMENT_CREATED - COURSE_ENROLLMENT_CREATED.send_event( - enrollment=CourseEnrollmentData( - user=UserData( - pii=UserPersonalData( - username=user.username, - email=user.email, - name=user.profile.name, - ), - id=user.id, - is_active=user.is_active, - ), - course=course_data, - mode=enrollment.mode, - is_active=enrollment.is_active, - creation_date=enrollment.created, - ) - ) + # Location openedx/core/djangoapps/user_authn/views/register.py + # .. event_implemented_name: COURSE_ENROLLMENT_CREATED + COURSE_ENROLLMENT_CREATED.send_event( + enrollment=CourseEnrollmentData( + user=UserData( + pii=UserPersonalData( + username=user.username, + email=user.email, + name=user.profile.name, + ), + id=user.id, + is_active=user.is_active, + ), + course=course_data, + mode=enrollment.mode, + is_active=enrollment.is_active, + creation_date=enrollment.created, + ) + ) From ffc28149c0125569c353251827e3f5278c826265 Mon Sep 17 00:00:00 2001 From: Maria Grimaldi Date: Fri, 12 Aug 2022 15:09:14 -0400 Subject: [PATCH 06/23] fix: remove enterprise (unsure of its current usage) --- docs/how-to/create-new-event.rst | 2 -- 1 file changed, 2 deletions(-) diff --git a/docs/how-to/create-new-event.rst b/docs/how-to/create-new-event.rst index d01c2f09..f25e5398 100644 --- a/docs/how-to/create-new-event.rst +++ b/docs/how-to/create-new-event.rst @@ -32,8 +32,6 @@ For those reasons, after studying your new event purpose, you must place it in o +----------------+----------------------------------------------------------------------------------------------------+ | Discovery | Allows learners to find the right content at the right time to help achieve their learning goals. | +----------------+----------------------------------------------------------------------------------------------------+ -| Enterprise | ??? | -+----------------+----------------------------------------------------------------------------------------------------+ | Programs | Allows educators and learners to manage and engage in bundled packages (programs) of learning. | +----------------+----------------------------------------------------------------------------------------------------+ From ec12dd9b481de205eb4dcb607dd4230ecb0c1114 Mon Sep 17 00:00:00 2001 From: Maria Grimaldi Date: Fri, 12 Aug 2022 15:10:42 -0400 Subject: [PATCH 07/23] fix: add example of the package names --- docs/how-to/create-new-event.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/how-to/create-new-event.rst b/docs/how-to/create-new-event.rst index f25e5398..fd7b1004 100644 --- a/docs/how-to/create-new-event.rst +++ b/docs/how-to/create-new-event.rst @@ -19,7 +19,7 @@ As specified in the Architectural Decisions Record (ADR) events naming and versi Subdomain for: - The name of the event: ``{Reverse DNS}.{Architecture Subdomain}.{Subject}.{Action}.{Major Version}`` -- The package name where the definition will live, eg. ``learning/signals.py`` or `` +- The package name where the definition will live, eg. ``learning/`` or ``content_authoring/``. For those reasons, after studying your new event purpose, you must place it in one of the subdomains supported by the project: From 62d64303bebc09c1051f67d24c0b7b61213cba64 Mon Sep 17 00:00:00 2001 From: Maria Grimaldi Date: Fri, 12 Aug 2022 15:11:26 -0400 Subject: [PATCH 08/23] fix: add missing line in code blocks --- docs/how-to/create-new-event.rst | 3 +++ 1 file changed, 3 insertions(+) diff --git a/docs/how-to/create-new-event.rst b/docs/how-to/create-new-event.rst index fd7b1004..a6cdc2e5 100644 --- a/docs/how-to/create-new-event.rst +++ b/docs/how-to/create-new-event.rst @@ -57,6 +57,7 @@ with: Consider the user data representation as an example: .. code-block:: python + @attr.s(frozen=True) class CourseData: """ @@ -116,6 +117,7 @@ The definition created in this step must comply with: Consider the following example: .. code-block:: python + # Location openedx_events/learning/signals.py # .. event_type: org.openedx.learning.course.enrollment.created.v1 # .. event_name: COURSE_ENROLLMENT_CREATED @@ -143,6 +145,7 @@ Before opening a PR in the service project, refer to its contribution guidelines Consider the integration of the event ``STUDENT_REGISTRATION_COMPLETED`` as an example: .. code-block:: python + # Location openedx/core/djangoapps/user_authn/views/register.py # .. event_implemented_name: COURSE_ENROLLMENT_CREATED COURSE_ENROLLMENT_CREATED.send_event( From 34d57a93a8d10f07518c995ce6cf8cbf7b7eb54a Mon Sep 17 00:00:00 2001 From: Maria Grimaldi Date: Tue, 30 Aug 2022 10:25:42 -0400 Subject: [PATCH 09/23] refactor: add new docs structure --- docs/concepts/event-architecture.rst | 0 docs/how-tos/adding-events-to-a-service.rst | 38 ++++++ .../adding-new-events.rst} | 50 ++------ .../configure-events-with-edx-platform.rst | 0 .../using-events-with-edx-platform.rst | 116 ++++++++++++++++++ .../use-events-to-call-webhook.rst | 12 ++ docs/references/index.rst | 0 7 files changed, 179 insertions(+), 37 deletions(-) create mode 100644 docs/concepts/event-architecture.rst create mode 100644 docs/how-tos/adding-events-to-a-service.rst rename docs/{how-to/create-new-event.rst => how-tos/adding-new-events.rst} (82%) create mode 100644 docs/how-tos/configure-events-with-edx-platform.rst create mode 100644 docs/how-tos/using-events-with-edx-platform.rst create mode 100644 docs/quickstarts/use-events-to-call-webhook.rst create mode 100644 docs/references/index.rst diff --git a/docs/concepts/event-architecture.rst b/docs/concepts/event-architecture.rst new file mode 100644 index 00000000..e69de29b diff --git a/docs/how-tos/adding-events-to-a-service.rst b/docs/how-tos/adding-events-to-a-service.rst new file mode 100644 index 00000000..c25ee3d3 --- /dev/null +++ b/docs/how-tos/adding-events-to-a-service.rst @@ -0,0 +1,38 @@ +How to add an Open edX Event to a service +========================================= + +5. Integrate into service +------------------------- + +After or during the events definition implementation, you now must trigger the event in the service you intentioned. Meaning: + +- Add the openedx-events library to the service project. +- Import the events' data and definition into the place where will be triggered. Remember the Open edX Events purpose when + choosing a place to send the new event. +- Add inline documentation with the event implemented name. + +Before opening a PR in the service project, refer to its contribution guidelines. + +Consider the integration of the event ``STUDENT_REGISTRATION_COMPLETED`` as an example: + +.. code-block:: python + + # Location openedx/core/djangoapps/user_authn/views/register.py + # .. event_implemented_name: COURSE_ENROLLMENT_CREATED + COURSE_ENROLLMENT_CREATED.send_event( + enrollment=CourseEnrollmentData( + user=UserData( + pii=UserPersonalData( + username=user.username, + email=user.email, + name=user.profile.name, + ), + id=user.id, + is_active=user.is_active, + ), + course=course_data, + mode=enrollment.mode, + is_active=enrollment.is_active, + creation_date=enrollment.created, + ) + ) diff --git a/docs/how-to/create-new-event.rst b/docs/how-tos/adding-new-events.rst similarity index 82% rename from docs/how-to/create-new-event.rst rename to docs/how-tos/adding-new-events.rst index a6cdc2e5..ab8290da 100644 --- a/docs/how-to/create-new-event.rst +++ b/docs/how-tos/adding-new-events.rst @@ -112,7 +112,19 @@ The definition created in this step must comply with: on events subdomains. - It should follow the naming conventions specified in Naming Conventions ADR. - It must be documented using in-line documentation with at least: `event_type`, `event_name`, `event_description` and - `event_data`. + `event_data`: + ++-------------------+----------------------------------------------------------------------------------------------------+ +| Annotation | Description | ++===================+====================================================================================================+ +| event_type | Allows educators to create, modify, discover, package, annotate (tag), and share learning content. | ++-------------------+----------------------------------------------------------------------------------------------------+ +| event_name | Allows learners to consume content and perform actions in a learning activity on the platform. | ++-------------------+----------------------------------------------------------------------------------------------------+ +| event_description | Allows learners to find the right content at the right time to help achieve their learning goals. | ++-------------------+----------------------------------------------------------------------------------------------------+ +| event_data | Allows educators and learners to manage and engage in bundled packages (programs) of learning. | ++-------------------+----------------------------------------------------------------------------------------------------+ Consider the following example: @@ -129,39 +141,3 @@ Consider the following example: "enrollment": CourseEnrollmentData, } ) - -5. Integrate into service -------------------------- - -After or during the events definition implementation, you now must trigger the event in the service you intentioned. Meaning: - -- Add the openedx-events library to the service project. -- Import the events' data and definition into the place where will be triggered. Remember the Open edX Events purpose when - choosing a place to send the new event. -- Add inline documentation with the event implemented name. - -Before opening a PR in the service project, refer to its contribution guidelines. - -Consider the integration of the event ``STUDENT_REGISTRATION_COMPLETED`` as an example: - -.. code-block:: python - - # Location openedx/core/djangoapps/user_authn/views/register.py - # .. event_implemented_name: COURSE_ENROLLMENT_CREATED - COURSE_ENROLLMENT_CREATED.send_event( - enrollment=CourseEnrollmentData( - user=UserData( - pii=UserPersonalData( - username=user.username, - email=user.email, - name=user.profile.name, - ), - id=user.id, - is_active=user.is_active, - ), - course=course_data, - mode=enrollment.mode, - is_active=enrollment.is_active, - creation_date=enrollment.created, - ) - ) diff --git a/docs/how-tos/configure-events-with-edx-platform.rst b/docs/how-tos/configure-events-with-edx-platform.rst new file mode 100644 index 00000000..e69de29b diff --git a/docs/how-tos/using-events-with-edx-platform.rst b/docs/how-tos/using-events-with-edx-platform.rst new file mode 100644 index 00000000..4bf141d5 --- /dev/null +++ b/docs/how-tos/using-events-with-edx-platform.rst @@ -0,0 +1,116 @@ +Using Open edX Events within edx-platform +========================================= + +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 STUDENT_REGISTRATION_COMPLETED + + @receiver(STUDENT_REGISTRATION_COMPLETED) + def your_receiver_function(**kwargs): + # your implementation 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.STUDENT_REGISTRATION_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. diff --git a/docs/quickstarts/use-events-to-call-webhook.rst b/docs/quickstarts/use-events-to-call-webhook.rst new file mode 100644 index 00000000..a768fe6c --- /dev/null +++ b/docs/quickstarts/use-events-to-call-webhook.rst @@ -0,0 +1,12 @@ +Using Open edX Events within edx-platform +========================================= + +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 diff --git a/docs/references/index.rst b/docs/references/index.rst new file mode 100644 index 00000000..e69de29b From 9457b56165d88c20de1d8a3000844a3b3abddb65 Mon Sep 17 00:00:00 2001 From: Maria Grimaldi Date: Wed, 15 Feb 2023 10:54:52 -0400 Subject: [PATCH 10/23] feat: add index files to subfolders --- docs/concepts/{event-architecture.rst => events-architecture.rst} | 0 docs/quickstarts/event-bus.rst | 0 2 files changed, 0 insertions(+), 0 deletions(-) rename docs/concepts/{event-architecture.rst => events-architecture.rst} (100%) create mode 100644 docs/quickstarts/event-bus.rst diff --git a/docs/concepts/event-architecture.rst b/docs/concepts/events-architecture.rst similarity index 100% rename from docs/concepts/event-architecture.rst rename to docs/concepts/events-architecture.rst diff --git a/docs/quickstarts/event-bus.rst b/docs/quickstarts/event-bus.rst new file mode 100644 index 00000000..e69de29b From 4d73e19655dbcb533c16d47ada5bc2c07b9b8f50 Mon Sep 17 00:00:00 2001 From: Maria Grimaldi Date: Wed, 15 Feb 2023 14:45:15 -0400 Subject: [PATCH 11/23] docs: add latest documentation --- docs/concepts/hooks-extension-framework.rst | 45 ++++++++ docs/concepts/index.rst | 6 + docs/decisions/index.rst | 4 +- docs/how-tos/adding-events-to-event-bus.rst | 0 docs/index.rst | 2 +- docs/quickstarts/event-bus.rst | 1 + .../use-events-to-call-webhook.rst | 108 +++++++++++++++++- 7 files changed, 160 insertions(+), 6 deletions(-) create mode 100644 docs/concepts/hooks-extension-framework.rst create mode 100644 docs/how-tos/adding-events-to-event-bus.rst diff --git a/docs/concepts/hooks-extension-framework.rst b/docs/concepts/hooks-extension-framework.rst new file mode 100644 index 00000000..49127e8d --- /dev/null +++ b/docs/concepts/hooks-extension-framework.rst @@ -0,0 +1,45 @@ +Openedx 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`_ +* `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 +.. _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 service where this library is installed. +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. diff --git a/docs/concepts/index.rst b/docs/concepts/index.rst index 6b799793..1144e8ac 100644 --- a/docs/concepts/index.rst +++ b/docs/concepts/index.rst @@ -1,2 +1,8 @@ Concepts ======== + +.. toctree:: + :maxdepth: 1 + :caption: Contents: + + hooks-extension-framework diff --git a/docs/decisions/index.rst b/docs/decisions/index.rst index a052b89a..ecff959b 100644 --- a/docs/decisions/index.rst +++ b/docs/decisions/index.rst @@ -1,5 +1,5 @@ -Decisions -========= +Architectural Decision Records (ADRs) +##################################### .. toctree:: :maxdepth: 1 diff --git a/docs/how-tos/adding-events-to-event-bus.rst b/docs/how-tos/adding-events-to-event-bus.rst new file mode 100644 index 00000000..e69de29b diff --git a/docs/index.rst b/docs/index.rst index 23a6c175..59877fa7 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -4,7 +4,7 @@ contain the root `toctree` directive. Welcome to Open edX Events' documentation! -=========================================== +============================================ .. toctree:: :maxdepth: 2 diff --git a/docs/quickstarts/event-bus.rst b/docs/quickstarts/event-bus.rst index e69de29b..8997ab25 100644 --- a/docs/quickstarts/event-bus.rst +++ b/docs/quickstarts/event-bus.rst @@ -0,0 +1 @@ +whole process of adding an event to a service and adding it to event bus \ No newline at end of file diff --git a/docs/quickstarts/use-events-to-call-webhook.rst b/docs/quickstarts/use-events-to-call-webhook.rst index a768fe6c..c88616fc 100644 --- a/docs/quickstarts/use-events-to-call-webhook.rst +++ b/docs/quickstarts/use-events-to-call-webhook.rst @@ -1,12 +1,114 @@ -Using Open edX Events within edx-platform -========================================= +Using Open edX Events in the LMS service +======================================== 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. +Let's see it working! + +Setup your environment +---------------------- + +This tutorial assumes you're using `Tutor`_ > 13.x and its default services are +already provisioned. + +Installation +------------ + +For this tutorial to work, you'll need a openedx image with the following package +installed: + +- `openedx-events-2-zapier`_ + +You can use your preferred method for installing new packages in Tutor. + +Configuration +------------- + +The package we just installed is a `Django plugin`_, which adds additional +configurations to our working environment thanks to the extension mechanisms put in place. Now, +signal receivers are listening to the registration and enrollment events sent within the LMS service. + +The following is the implementation for the signal receiver listening for the event ``STUDENT_REGISTRATION_COMPLETED``: + +.. code-block:: python + + # File openedx_events_2_zapier/receivers.py + class OpenedxEventsSamplesConfig(AppConfig): + """ + Configuration for the openedx_events_2_zapier Django application. + """ + + name = "openedx_events_2_zapier" + + plugin_app = { + "settings_config": {}, + "signals_config": { + "lms.djangoapp": { + "relative_path": "receivers", + "receivers": [ + { + "receiver_func_name": "send_user_data_to_webhook", + "signal_path": "openedx_events.learning.signals.STUDENT_REGISTRATION_COMPLETED", + }, + ], + } + }, + } + + # File openedx_events_2_zapier/receivers.py + def send_user_data_to_webhook(user, **kwargs): + """ + POST user's data after STUDENT_REGISTRATION_COMPLETED event is sent. + + The data sent to the webhook is, for example: + + 'user_id': 39, + 'user_is_active': True, + 'user_pii_username': 'test', + 'user_pii_email': 'test@example.com', + 'user_pii_name': 'test', + 'event_metadata_id': UUID('b1be2fac-1af1-11ec-bdf4-0242ac12000b'), + 'event_metadata_event_type': 'org.openedx.learning.student.registration.completed.v1', + 'event_metadata_minorversion': 0, + 'event_metadata_source': 'openedx/lms/web', + 'event_metadata_sourcehost': 'lms.devstack.edx', + 'event_metadata_time': datetime.datetime(2021, 9, 21, 15, 36, 31, 311506), + 'event_metadata_sourcelib': [0, 6, 0] + + This format is convenient for Zapier to read. + """ + user_info = asdict(user) + event_metadata = asdict(kwargs.get("metadata")) + zapier_payload = { + "user": user_info, + "event_metadata": event_metadata, + } + requests.post( + settings.ZAPIER_REGISTRATION_WEBHOOK, + flatten_dict(zapier_payload), + ) + +Those receivers work out of the box after the plugin installation. Now, we must +set the plugin settings which indicate where to send the events data. For this, +go to ``env/apps/openedx/settings/development.py`` and add your Zapier configuration: + +.. code-block:: python + + ZAPIER_REGISTRATION_WEBHOOK = "https://hooks.zapier.com/hooks/catch///" + ZAPIER_ENROLLMENT_WEBHOOK = "https://hooks.zapier.com/hooks/catch///" + +Getting data from Zapier +------------------------ + +Now that you have configured both receivers, you'll need to trigger the events +so you receive the events data in Zapier. Try it out! + .. _openedx-events-2-zapier: https://github.com/eduNEXT/openedx-events-2-zapier +.. _Tutor: https://github.com/overhangio/tutor +.. _Django plugin: https://github.com/openedx/edx-django-utils/blob/master/edx_django_utils/plugins/README.rst From b07bba3c48228e5e2f37682ab616db0a0cd4028c Mon Sep 17 00:00:00 2001 From: Maria Grimaldi Date: Wed, 15 Feb 2023 14:57:39 -0400 Subject: [PATCH 12/23] refactor: address PR reviews --- docs/concepts/events-architecture.rst | 0 docs/how-tos/adding-events-to-a-service.rst | 3 --- docs/how-tos/configure-events-with-edx-platform.rst | 0 docs/how-tos/using-events-with-edx-platform.rst | 3 --- docs/references/index.rst | 0 5 files changed, 6 deletions(-) delete mode 100644 docs/concepts/events-architecture.rst delete mode 100644 docs/how-tos/configure-events-with-edx-platform.rst delete mode 100644 docs/references/index.rst diff --git a/docs/concepts/events-architecture.rst b/docs/concepts/events-architecture.rst deleted file mode 100644 index e69de29b..00000000 diff --git a/docs/how-tos/adding-events-to-a-service.rst b/docs/how-tos/adding-events-to-a-service.rst index c25ee3d3..bdb3e889 100644 --- a/docs/how-tos/adding-events-to-a-service.rst +++ b/docs/how-tos/adding-events-to-a-service.rst @@ -1,9 +1,6 @@ How to add an Open edX Event to a service ========================================= -5. Integrate into service -------------------------- - After or during the events definition implementation, you now must trigger the event in the service you intentioned. Meaning: - Add the openedx-events library to the service project. diff --git a/docs/how-tos/configure-events-with-edx-platform.rst b/docs/how-tos/configure-events-with-edx-platform.rst deleted file mode 100644 index e69de29b..00000000 diff --git a/docs/how-tos/using-events-with-edx-platform.rst b/docs/how-tos/using-events-with-edx-platform.rst index 4bf141d5..03a19ff9 100644 --- a/docs/how-tos/using-events-with-edx-platform.rst +++ b/docs/how-tos/using-events-with-edx-platform.rst @@ -7,7 +7,6 @@ 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 ^^^^^^^^^^^^^^^^ @@ -80,7 +79,6 @@ attr data classes that encapsulate the event data. You can do this both from the edx-platform code as well as from an openedx plugin. - Testing events ^^^^^^^^^^^^^^ @@ -110,7 +108,6 @@ testing dependencies and make the signal connection in your test case. # 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. diff --git a/docs/references/index.rst b/docs/references/index.rst deleted file mode 100644 index e69de29b..00000000 From 5f8da097e9a9853764c19cdb643d32ef3d9fc385 Mon Sep 17 00:00:00 2001 From: Maria Grimaldi Date: Wed, 15 Feb 2023 16:01:56 -0400 Subject: [PATCH 13/23] refactor: add latest information --- docs/how-tos/adding-events-to-a-service.rst | 2 +- docs/how-tos/adding-events-to-event-bus.rst | 6 ++++++ docs/how-tos/adding-new-events.rst | 2 +- ...dx-platform.rst => using-events-within-edx-platform.rst} | 0 4 files changed, 8 insertions(+), 2 deletions(-) rename docs/how-tos/{using-events-with-edx-platform.rst => using-events-within-edx-platform.rst} (100%) diff --git a/docs/how-tos/adding-events-to-a-service.rst b/docs/how-tos/adding-events-to-a-service.rst index bdb3e889..50588edd 100644 --- a/docs/how-tos/adding-events-to-a-service.rst +++ b/docs/how-tos/adding-events-to-a-service.rst @@ -4,7 +4,7 @@ How to add an Open edX Event to a service After or during the events definition implementation, you now must trigger the event in the service you intentioned. Meaning: - Add the openedx-events library to the service project. -- Import the events' data and definition into the place where will be triggered. Remember the Open edX Events purpose when +- Import the events' data and definition into the place where the event be triggered. Remember the Open edX Events purpose when choosing a place to send the new event. - Add inline documentation with the event implemented name. diff --git a/docs/how-tos/adding-events-to-event-bus.rst b/docs/how-tos/adding-events-to-event-bus.rst index e69de29b..07463626 100644 --- a/docs/how-tos/adding-events-to-event-bus.rst +++ b/docs/how-tos/adding-events-to-event-bus.rst @@ -0,0 +1,6 @@ +How to add an Open edX Event to the Event Bus +============================================= + +Open edX Events can be sent synchronously in the same Django process where the +service runs or asynchronously using the event bus mechanism. We've put together +this guide on how to send new events over the event bus. diff --git a/docs/how-tos/adding-new-events.rst b/docs/how-tos/adding-new-events.rst index ab8290da..ccc3628b 100644 --- a/docs/how-tos/adding-new-events.rst +++ b/docs/how-tos/adding-new-events.rst @@ -2,7 +2,7 @@ How to create a new Open edX Event ================================== The mechanisms implemented by the Open edX Events library are supported and maintained by the Open edX community. -Therefore, we've put together a guide on how to add a new event to have an effective contribution process. +Therefore, we've put together a guide on how to add a new event the library so future contributions are effective. 1. Propose the new event to the community diff --git a/docs/how-tos/using-events-with-edx-platform.rst b/docs/how-tos/using-events-within-edx-platform.rst similarity index 100% rename from docs/how-tos/using-events-with-edx-platform.rst rename to docs/how-tos/using-events-within-edx-platform.rst From bd0195bd4f4f22d9c96c05bcd0ce0b866c59dd18 Mon Sep 17 00:00:00 2001 From: Maria Grimaldi Date: Thu, 16 Feb 2023 15:57:01 -0400 Subject: [PATCH 14/23] docs: add documentation to correct indexes --- .../{adding-new-events.rst => creating-new-events.rst} | 0 docs/how-tos/index.rst | 9 +++++++++ ...g-events-within-edx-platform.rst => using-events.rst} | 4 ++-- docs/quickstarts/index.rst | 7 +++++++ docs/reference/achitecture-subdomains.rst | 0 docs/reference/oep-51.rst | 0 6 files changed, 18 insertions(+), 2 deletions(-) rename docs/how-tos/{adding-new-events.rst => creating-new-events.rst} (100%) rename docs/how-tos/{using-events-within-edx-platform.rst => using-events.rst} (97%) create mode 100644 docs/reference/achitecture-subdomains.rst create mode 100644 docs/reference/oep-51.rst diff --git a/docs/how-tos/adding-new-events.rst b/docs/how-tos/creating-new-events.rst similarity index 100% rename from docs/how-tos/adding-new-events.rst rename to docs/how-tos/creating-new-events.rst diff --git a/docs/how-tos/index.rst b/docs/how-tos/index.rst index 5147f808..f8908b33 100644 --- a/docs/how-tos/index.rst +++ b/docs/how-tos/index.rst @@ -1,2 +1,11 @@ How-tos ####### + +.. toctree:: + :maxdepth: 1 + :caption: Contents: + + creating-new-events + adding-events-to-a-service + adding-events-to-event-bus + using-events diff --git a/docs/how-tos/using-events-within-edx-platform.rst b/docs/how-tos/using-events.rst similarity index 97% rename from docs/how-tos/using-events-within-edx-platform.rst rename to docs/how-tos/using-events.rst index 03a19ff9..9285f938 100644 --- a/docs/how-tos/using-events-within-edx-platform.rst +++ b/docs/how-tos/using-events.rst @@ -1,5 +1,5 @@ -Using Open edX Events within edx-platform -========================================= +Using Open edX Events +===================== How to use ---------- diff --git a/docs/quickstarts/index.rst b/docs/quickstarts/index.rst index a60e9164..e54f066f 100644 --- a/docs/quickstarts/index.rst +++ b/docs/quickstarts/index.rst @@ -1,2 +1,9 @@ Quickstarts ########### + +.. toctree:: + :maxdepth: 1 + :caption: Contents: + + use-events-to-call-webhook + event-bus diff --git a/docs/reference/achitecture-subdomains.rst b/docs/reference/achitecture-subdomains.rst new file mode 100644 index 00000000..e69de29b diff --git a/docs/reference/oep-51.rst b/docs/reference/oep-51.rst new file mode 100644 index 00000000..e69de29b From 758060c372c0fce8b4f8b2785f19f3f7e2170666 Mon Sep 17 00:00:00 2001 From: Maria Grimaldi Date: Tue, 28 Feb 2023 11:57:59 -0400 Subject: [PATCH 15/23] fix: add title to event bus documentation --- docs/quickstarts/event-bus.rst | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/docs/quickstarts/event-bus.rst b/docs/quickstarts/event-bus.rst index 8997ab25..efc9af27 100644 --- a/docs/quickstarts/event-bus.rst +++ b/docs/quickstarts/event-bus.rst @@ -1 +1,4 @@ -whole process of adding an event to a service and adding it to event bus \ No newline at end of file +Using the Open edX Event bus +============================ + +whole process of adding an event to a service and adding it to event bus From 9c5f6fe39f9a6f3b2b4a0e09391060f7589cfa13 Mon Sep 17 00:00:00 2001 From: Maria Grimaldi Date: Mon, 27 Mar 2023 18:58:49 -0400 Subject: [PATCH 16/23] docs: add references for openedx-events --- docs/reference/achitecture-subdomains.rst | 17 +++++++++++++++++ docs/reference/index.rst | 7 +++++++ docs/reference/oep-51.rst | 0 docs/reference/oeps.rst | 17 +++++++++++++++++ 4 files changed, 41 insertions(+) delete mode 100644 docs/reference/oep-51.rst create mode 100644 docs/reference/oeps.rst diff --git a/docs/reference/achitecture-subdomains.rst b/docs/reference/achitecture-subdomains.rst index e69de29b..68fd5e61 100644 --- a/docs/reference/achitecture-subdomains.rst +++ b/docs/reference/achitecture-subdomains.rst @@ -0,0 +1,17 @@ +Architecture Subdomains +======================= + +Here we list useful information about Open edX architecture subdomains and +their use in the Hooks Extension framework: + +- `Events Naming and Versioning`_ +- `Notes on events design and subdomains`_ +- `edX Domain Driven Design documentation`_ +- `Subdomains from OEP-41`_ +- `Message Content Data Guidelines`_ + +.. _Events Naming and Versioning: https://github.com/openedx/openedx-events/blob/main/docs/decisions/0002-events-naming-and-versioning.rst#L1 +.. _edX Domain Driven Design documentation: https://openedx.atlassian.net/wiki/spaces/AC/pages/213910332/Domain-Driven+Design +.. _`Subdomain from OEP-41`: https://docs.openedx.org/projects/openedx-proposals/en/latest/architectural-decisions/oep-0041-arch-async-server-event-messaging.html#subdomain-from-domain-driven-design +.. _`Message Content Data Guidelines`: https://docs.openedx.org/projects/openedx-proposals/en/latest/architectural-decisions/oep-0041-arch-async-server-event-messaging.html?highlight=subdomain#message-content-data-guidelines +.. _`Notes on events design and subdomains`: https://github.com/openedx/openedx-events/issues/72#issuecomment-1179291340 diff --git a/docs/reference/index.rst b/docs/reference/index.rst index ba5ea57c..28c276cc 100644 --- a/docs/reference/index.rst +++ b/docs/reference/index.rst @@ -1,2 +1,9 @@ References ########## + +.. toctree:: + :maxdepth: 1 + :caption: Contents: + + oeps + architecture-subdomains diff --git a/docs/reference/oep-51.rst b/docs/reference/oep-51.rst deleted file mode 100644 index e69de29b..00000000 diff --git a/docs/reference/oeps.rst b/docs/reference/oeps.rst new file mode 100644 index 00000000..eb110f08 --- /dev/null +++ b/docs/reference/oeps.rst @@ -0,0 +1,17 @@ +Open edX Proposals +================== + +Here we list the Open edX proposals used throughout the project, that will help +you understand the major decisions made during the library's design. + +- The `Hooks extension framework (OEP-50)`_ which specifies its motivation, +implementation details, rationale, performance considerations, general use +cases and more. The goal of the OEP-50 is give the extensions' developer a +glance on the framework implementation and design. + +- The `Asynchronous Server Event Message Format (OEP-41)`_, which +specifies the header information format sent by the events. For a detailed description +on the impact of the OEP-41, please refer to the Events Payload ADR. + +.. _Hooks extension framework (OEP-50): https://open-edx-proposals.readthedocs.io/en/latest/architectural-decisions/oep-0050-hooks-extension-framework.html +.. _Asynchronous Server Event Message Format (OEP-41): https://open-edx-proposals.readthedocs.io/en/latest/architectural-decisions/oep-0041-arch-async-server-event-messaging.html From 8d5ebe4d0f80941c4c4ad6d7b6d10e709bd796b0 Mon Sep 17 00:00:00 2001 From: Maria Grimaldi Date: Mon, 27 Mar 2023 19:14:54 -0400 Subject: [PATCH 17/23] fix: move info to the correct file --- docs/how-tos/adding-events-to-event-bus.rst | 18 +++++++++++++----- docs/quickstarts/event-bus.rst | 4 ---- 2 files changed, 13 insertions(+), 9 deletions(-) delete mode 100644 docs/quickstarts/event-bus.rst diff --git a/docs/how-tos/adding-events-to-event-bus.rst b/docs/how-tos/adding-events-to-event-bus.rst index 07463626..e5b64d0a 100644 --- a/docs/how-tos/adding-events-to-event-bus.rst +++ b/docs/how-tos/adding-events-to-event-bus.rst @@ -1,6 +1,14 @@ -How to add an Open edX Event to the Event Bus -============================================= +Using the Open edX Event bus +============================ -Open edX Events can be sent synchronously in the same Django process where the -service runs or asynchronously using the event bus mechanism. We've put together -this guide on how to send new events over the event bus. +After creating a new Open edX Event, you might need to send it across services +instead of just within the same process. For this kind of use-cases, you might want +to use the Open edX Event Bus. Here, we list useful information about +adding a new event to the event bus: + +- `How to start using the Event Bus`_ +- `Sample pull request adding new Open edX Events to the Event Bus` + + +.. _How to start using the Event Bus: https://openedx.atlassian.net/wiki/spaces/AC/pages/3508699151/How+to+start+using+the+Event+Bus +.. _Sample pull request adding new Open edX Events to the Event Bus: https://github.com/openedx/edx-platform/pull/31350 diff --git a/docs/quickstarts/event-bus.rst b/docs/quickstarts/event-bus.rst deleted file mode 100644 index efc9af27..00000000 --- a/docs/quickstarts/event-bus.rst +++ /dev/null @@ -1,4 +0,0 @@ -Using the Open edX Event bus -============================ - -whole process of adding an event to a service and adding it to event bus From 63c8bd25559a7a953989aacabc6d9e10f044fb5d Mon Sep 17 00:00:00 2001 From: Maria Grimaldi Date: Mon, 27 Mar 2023 19:36:29 -0400 Subject: [PATCH 18/23] docs: remove unused subdomains --- docs/how-tos/creating-new-events.rst | 25 ++++++++++++------------- 1 file changed, 12 insertions(+), 13 deletions(-) diff --git a/docs/how-tos/creating-new-events.rst b/docs/how-tos/creating-new-events.rst index ccc3628b..9082176e 100644 --- a/docs/how-tos/creating-new-events.rst +++ b/docs/how-tos/creating-new-events.rst @@ -21,19 +21,18 @@ Subdomain for: - The name of the event: ``{Reverse DNS}.{Architecture Subdomain}.{Subject}.{Action}.{Major Version}`` - The package name where the definition will live, eg. ``learning/`` or ``content_authoring/``. -For those reasons, after studying your new event purpose, you must place it in one of the subdomains supported by the project: - -+----------------+----------------------------------------------------------------------------------------------------+ -| Subdomain name | Description | -+================+====================================================================================================+ -| Authoring | Allows educators to create, modify, discover, package, annotate (tag), and share learning content. | -+----------------+----------------------------------------------------------------------------------------------------+ -| Learning | Allows learners to consume content and perform actions in a learning activity on the platform. | -+----------------+----------------------------------------------------------------------------------------------------+ -| Discovery | Allows learners to find the right content at the right time to help achieve their learning goals. | -+----------------+----------------------------------------------------------------------------------------------------+ -| Programs | Allows educators and learners to manage and engage in bundled packages (programs) of learning. | -+----------------+----------------------------------------------------------------------------------------------------+ +For those reasons, after studying your new event purpose, you must place it in one of the subdomains already in use, or introduce a new subdomain: + ++------------------+----------------------------------------------------------------------------------------------------+ +| Subdomain name | Description | ++==================+====================================================================================================+ +| Course Authoring | Allows educators to create, modify, package, annotate (tag), and share learning content. | ++----------------- +----------------------------------------------------------------------------------------------------+ +| Learning | Allows learners to consume content and perform actions in a learning activity on the platform. | ++------------------+----------------------------------------------------------------------------------------------------+ + +New subdomains may require some discussion, because there does not yet exist and agreed upon set on subdomains. So we encourage you to start the conversation +as soon as possible through any of the communication channels available. Refer to `edX DDD Bounded Contexts `_ confluence page for more documentation on domain-driven design in the Open edX project. From 9a3e83fd95c89c434f519b0a3577b31784a31fb8 Mon Sep 17 00:00:00 2001 From: Maria Grimaldi Date: Tue, 28 Mar 2023 16:12:26 -0400 Subject: [PATCH 19/23] fix: address PR reviews --- docs/concepts/hooks-extension-framework.rst | 8 ++++---- docs/decisions/0001-purpose-of-this-repo.rst | 2 +- .../0002-events-naming-and-versioning.rst | 4 ++-- docs/decisions/0003-events-payload.rst | 6 +++--- docs/how-tos/adding-events-to-a-service.rst | 16 ++++++++++------ docs/how-tos/creating-new-events.rst | 12 ++++++------ docs/how-tos/using-events.rst | 12 ++++++------ 7 files changed, 32 insertions(+), 28 deletions(-) diff --git a/docs/concepts/hooks-extension-framework.rst b/docs/concepts/hooks-extension-framework.rst index 49127e8d..2d204120 100644 --- a/docs/concepts/hooks-extension-framework.rst +++ b/docs/concepts/hooks-extension-framework.rst @@ -4,20 +4,20 @@ Openedx 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. +the main Open edX platform. Context ------- -Hooks are predefined places in the edx-platform core where externally defined +Hooks are predefined places in the Open edX project 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 +functionality. functionality. On the other hand Filters can be used to act on data before +it 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. diff --git a/docs/decisions/0001-purpose-of-this-repo.rst b/docs/decisions/0001-purpose-of-this-repo.rst index 8eab83c5..8e860207 100644 --- a/docs/decisions/0001-purpose-of-this-repo.rst +++ b/docs/decisions/0001-purpose-of-this-repo.rst @@ -19,7 +19,7 @@ Decision -------- In this repository will reside the signals that define the events used by the -edx-platform repo. The same applies to the necessary tooling used by the Hooks +Open edX project. The same applies to the necessary tooling used by the Hooks Extension Framework to manage the events execution and extra tools. Consequences diff --git a/docs/decisions/0002-events-naming-and-versioning.rst b/docs/decisions/0002-events-naming-and-versioning.rst index 2a3d69a3..48cbcfe1 100644 --- a/docs/decisions/0002-events-naming-and-versioning.rst +++ b/docs/decisions/0002-events-naming-and-versioning.rst @@ -80,8 +80,8 @@ Consequences major versions of this library. Also there will not be a need to make a major release if there is no breaking for consecutive Open edX releases. -2. Open edX core and in particular edx-platform must emit the signals meant for -public consumption as they are written in this library, changes in edx-platform +2. The Open edX platform must emit the signals meant for +public consumption as they are written in this library, changes in the platform that require changes in the public signal will require a backwards compatible addition to this library or an altogether new signal with support for the old signal until deprecated and removed. diff --git a/docs/decisions/0003-events-payload.rst b/docs/decisions/0003-events-payload.rst index f003c9e0..fcb4f5ee 100644 --- a/docs/decisions/0003-events-payload.rst +++ b/docs/decisions/0003-events-payload.rst @@ -14,7 +14,7 @@ Given their public promise status, event hooks have maintainability as the main design goal. The contracts we are creating here should be stable enough to support the growth of the extensions community. That said, things should be allowed to evolve in a backwards compatible manner. When things inevitable break, -they should break in CI. Which should not require the code of edx-platform to +they should break in CI. Which should not require the code of The Open edX platform to test integrations. @@ -46,7 +46,7 @@ Consequences ------------ 1. Extension developers will be able to test their event listeners without the -need to import any edx-platform code. +need to import any Open edX platform code. 2. Consequence of the versioning ADR together with this one, extension developers will be able to test their code with different versions of the library and thus @@ -55,5 +55,5 @@ guarantee that their code will not break when upgrading open releases. 3. The events library will have a dependency on the OpaqueKeys library. 4. Events defined by this library will not be drop-in replacement of current -edx-platform signals. This means some refactoring will be needed when converting +Open edX platform signals. This means some refactoring will be needed when converting the platform code over to openedx_events. diff --git a/docs/how-tos/adding-events-to-a-service.rst b/docs/how-tos/adding-events-to-a-service.rst index 50588edd..7c028690 100644 --- a/docs/how-tos/adding-events-to-a-service.rst +++ b/docs/how-tos/adding-events-to-a-service.rst @@ -1,16 +1,16 @@ How to add an Open edX Event to a service ========================================= -After or during the events definition implementation, you now must trigger the event in the service you intentioned. Meaning: +The next step after creating your first event in the Open edX Events library, it's to trigger the event in the service +you implemented it for. Here is a checklist of what we've done so far when including a new event to a service: - Add the openedx-events library to the service project. -- Import the events' data and definition into the place where the event be triggered. Remember the Open edX Events purpose when +- Import the events' data and definition into the place where the event be triggered. Remember the event's purpose when choosing a place to send the new event. -- Add inline documentation with the event implemented name. +- Add inline documentation with the ``event_implemented_name``. This matches the ``event_name`` in line documentation from the library. +- Refer to the service project's contribution guidelines and follow the instructions. Then, open a new pull request! -Before opening a PR in the service project, refer to its contribution guidelines. - -Consider the integration of the event ``STUDENT_REGISTRATION_COMPLETED`` as an example: +Consider the addition of the event ``STUDENT_REGISTRATION_COMPLETED`` to edx-platform as an example: .. code-block:: python @@ -33,3 +33,7 @@ Consider the integration of the event ``STUDENT_REGISTRATION_COMPLETED`` as an e creation_date=enrollment.created, ) ) + +If you want to know more about how the integration of the first events' batch went, check out the `PR 28266`_. + +.. _PR 28266: https://github.com/openedx/edx-platform/pull/28266 diff --git a/docs/how-tos/creating-new-events.rst b/docs/how-tos/creating-new-events.rst index 9082176e..46c062b8 100644 --- a/docs/how-tos/creating-new-events.rst +++ b/docs/how-tos/creating-new-events.rst @@ -2,7 +2,7 @@ How to create a new Open edX Event ================================== The mechanisms implemented by the Open edX Events library are supported and maintained by the Open edX community. -Therefore, we've put together a guide on how to add a new event the library so future contributions are effective. +Therefore, we've put together a guide on how to add a new event to the library so future contributions are effective. 1. Propose the new event to the community @@ -44,7 +44,7 @@ decide if an existent data class works for your use case or you must create a ne - Which attributes of the object are the most relevant? - Which type are they? -- Is any of them optional/required? +- Are any of them optional/required? And with that information, create the new class justifying each decision. The class created in this step must comply with: @@ -116,13 +116,13 @@ The definition created in this step must comply with: +-------------------+----------------------------------------------------------------------------------------------------+ | Annotation | Description | +===================+====================================================================================================+ -| event_type | Allows educators to create, modify, discover, package, annotate (tag), and share learning content. | +| event_type | Identifier across services of the event. Should follow the events naming conventions. | +-------------------+----------------------------------------------------------------------------------------------------+ -| event_name | Allows learners to consume content and perform actions in a learning activity on the platform. | +| event_name | Name of the variable storing the event instance. | +-------------------+----------------------------------------------------------------------------------------------------+ -| event_description | Allows learners to find the right content at the right time to help achieve their learning goals. | +| event_description | General description which includes when the event should be emitted. | +-------------------+----------------------------------------------------------------------------------------------------+ -| event_data | Allows educators and learners to manage and engage in bundled packages (programs) of learning. | +| event_data | What type of class attribute the event sends. | +-------------------+----------------------------------------------------------------------------------------------------+ Consider the following example: diff --git a/docs/how-tos/using-events.rst b/docs/how-tos/using-events.rst index 9285f938..b6dda642 100644 --- a/docs/how-tos/using-events.rst +++ b/docs/how-tos/using-events.rst @@ -10,8 +10,8 @@ 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. +This is one of the most common use cases for plugins. The Open edX platform will send +an event and you want to react to it in your plugin. For this you need to: @@ -48,9 +48,9 @@ Or at the apps.py } -In case you are listening to an event in the edx-platform repo, you can directly +In case you are listening to an event in an Open edX platform repo, you can directly use the django syntax since the apps.py method will not be available without the -plugin. +plugin system. Sending events @@ -76,14 +76,14 @@ attr data classes that encapsulate the event data. ), ) -You can do this both from the edx-platform code as well as from an openedx +You can do this both from the Open 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. +import the complete Open 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. From 3553c610695fbf322158127bd2af94e4a6706a97 Mon Sep 17 00:00:00 2001 From: Maria Grimaldi Date: Tue, 28 Mar 2023 16:38:55 -0400 Subject: [PATCH 20/23] docs: add warning encouraging tasks --- docs/how-tos/using-events.rst | 3 +++ 1 file changed, 3 insertions(+) diff --git a/docs/how-tos/using-events.rst b/docs/how-tos/using-events.rst index b6dda642..a7acc628 100644 --- a/docs/how-tos/using-events.rst +++ b/docs/how-tos/using-events.rst @@ -52,6 +52,9 @@ In case you are listening to an event in an Open edX platform repo, you can dire use the django syntax since the apps.py method will not be available without the plugin system. +.. warning:: + For non-trivial work, we encourage using asynchronous tasks in your receiver functions in order + to avoid affecting the performance of the service. Sending events ^^^^^^^^^^^^^^ From 87cf1d7a20d3a16afc5fc79c69258c26c3d586a0 Mon Sep 17 00:00:00 2001 From: Maria Grimaldi Date: Tue, 28 Mar 2023 16:42:54 -0400 Subject: [PATCH 21/23] docs: add warning when using events to call webhooks --- docs/quickstarts/use-events-to-call-webhook.rst | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/docs/quickstarts/use-events-to-call-webhook.rst b/docs/quickstarts/use-events-to-call-webhook.rst index c88616fc..d3df286e 100644 --- a/docs/quickstarts/use-events-to-call-webhook.rst +++ b/docs/quickstarts/use-events-to-call-webhook.rst @@ -112,3 +112,7 @@ so you receive the events data in Zapier. Try it out! .. _openedx-events-2-zapier: https://github.com/eduNEXT/openedx-events-2-zapier .. _Tutor: https://github.com/overhangio/tutor .. _Django plugin: https://github.com/openedx/edx-django-utils/blob/master/edx_django_utils/plugins/README.rst + +.. warning:: + The receiver function implemented in this tutorial was intended to be lightweight, just to serve as an example for events' receivers. However, in production + settings, we encourage the use of asynchronous tasks to avoid creating bottlenecks. From c2696200eaf1a57f1191ba33e17921925116f03e Mon Sep 17 00:00:00 2001 From: Maria Grimaldi Date: Tue, 4 Apr 2023 16:40:55 -0400 Subject: [PATCH 22/23] fix: fix quality issues with sphinx --- docs/concepts/index.rst | 2 +- docs/how-tos/creating-new-events.rst | 14 +++++++------- docs/reference/achitecture-subdomains.rst | 2 +- docs/reference/oeps.rst | 9 ++------- 4 files changed, 11 insertions(+), 16 deletions(-) diff --git a/docs/concepts/index.rst b/docs/concepts/index.rst index 1144e8ac..cade1612 100644 --- a/docs/concepts/index.rst +++ b/docs/concepts/index.rst @@ -5,4 +5,4 @@ Concepts :maxdepth: 1 :caption: Contents: - hooks-extension-framework + hooks-extension-framework diff --git a/docs/how-tos/creating-new-events.rst b/docs/how-tos/creating-new-events.rst index 46c062b8..fa55de5d 100644 --- a/docs/how-tos/creating-new-events.rst +++ b/docs/how-tos/creating-new-events.rst @@ -23,13 +23,13 @@ Subdomain for: For those reasons, after studying your new event purpose, you must place it in one of the subdomains already in use, or introduce a new subdomain: -+------------------+----------------------------------------------------------------------------------------------------+ -| Subdomain name | Description | -+==================+====================================================================================================+ -| Course Authoring | Allows educators to create, modify, package, annotate (tag), and share learning content. | -+----------------- +----------------------------------------------------------------------------------------------------+ -| Learning | Allows learners to consume content and perform actions in a learning activity on the platform. | -+------------------+----------------------------------------------------------------------------------------------------+ ++-------------------+----------------------------------------------------------------------------------------------------+ +| Subdomain name | Description | ++===================+====================================================================================================+ +| Course Authoring | Allows educators to create, modify, package, annotate (tag), and share learning content. | ++-------------------+----------------------------------------------------------------------------------------------------+ +| Learning | Allows learners to consume content and perform actions in a learning activity on the platform. | ++-------------------+----------------------------------------------------------------------------------------------------+ New subdomains may require some discussion, because there does not yet exist and agreed upon set on subdomains. So we encourage you to start the conversation as soon as possible through any of the communication channels available. diff --git a/docs/reference/achitecture-subdomains.rst b/docs/reference/achitecture-subdomains.rst index 68fd5e61..b69adbc6 100644 --- a/docs/reference/achitecture-subdomains.rst +++ b/docs/reference/achitecture-subdomains.rst @@ -12,6 +12,6 @@ their use in the Hooks Extension framework: .. _Events Naming and Versioning: https://github.com/openedx/openedx-events/blob/main/docs/decisions/0002-events-naming-and-versioning.rst#L1 .. _edX Domain Driven Design documentation: https://openedx.atlassian.net/wiki/spaces/AC/pages/213910332/Domain-Driven+Design -.. _`Subdomain from OEP-41`: https://docs.openedx.org/projects/openedx-proposals/en/latest/architectural-decisions/oep-0041-arch-async-server-event-messaging.html#subdomain-from-domain-driven-design +.. _`Subdomains from OEP-41`: https://docs.openedx.org/projects/openedx-proposals/en/latest/architectural-decisions/oep-0041-arch-async-server-event-messaging.html#subdomain-from-domain-driven-design .. _`Message Content Data Guidelines`: https://docs.openedx.org/projects/openedx-proposals/en/latest/architectural-decisions/oep-0041-arch-async-server-event-messaging.html?highlight=subdomain#message-content-data-guidelines .. _`Notes on events design and subdomains`: https://github.com/openedx/openedx-events/issues/72#issuecomment-1179291340 diff --git a/docs/reference/oeps.rst b/docs/reference/oeps.rst index eb110f08..519b5833 100644 --- a/docs/reference/oeps.rst +++ b/docs/reference/oeps.rst @@ -4,14 +4,9 @@ Open edX Proposals Here we list the Open edX proposals used throughout the project, that will help you understand the major decisions made during the library's design. -- The `Hooks extension framework (OEP-50)`_ which specifies its motivation, -implementation details, rationale, performance considerations, general use -cases and more. The goal of the OEP-50 is give the extensions' developer a -glance on the framework implementation and design. +- The `Hooks extension framework (OEP-50)`_ which specifies its motivation, implementation details, rationale, performance considerations, general use cases and more. The goal of the OEP-50 is give the extensions' developer a glance on the framework implementation and design. -- The `Asynchronous Server Event Message Format (OEP-41)`_, which -specifies the header information format sent by the events. For a detailed description -on the impact of the OEP-41, please refer to the Events Payload ADR. +- The `Asynchronous Server Event Message Format (OEP-41)`_, which specifies the header information format sent by the events. For a detailed description on the impact of the OEP-41, please refer to the Events Payload ADR. .. _Hooks extension framework (OEP-50): https://open-edx-proposals.readthedocs.io/en/latest/architectural-decisions/oep-0050-hooks-extension-framework.html .. _Asynchronous Server Event Message Format (OEP-41): https://open-edx-proposals.readthedocs.io/en/latest/architectural-decisions/oep-0041-arch-async-server-event-messaging.html From 2aa0e05a5eba155fa7a11b186d7d061ec67569b3 Mon Sep 17 00:00:00 2001 From: Maria Grimaldi Date: Tue, 4 Apr 2023 16:57:40 -0400 Subject: [PATCH 23/23] docs: address PR reviews --- docs/concepts/hooks-extension-framework.rst | 2 +- docs/decisions/0003-events-payload.rst | 2 +- docs/how-tos/adding-events-to-a-service.rst | 2 +- docs/how-tos/creating-new-events.rst | 6 +++++- docs/quickstarts/index.rst | 1 - docs/quickstarts/use-events-to-call-webhook.rst | 3 +++ ...hitecture-subdomains.rst => architecture-subdomains.rst} | 0 7 files changed, 11 insertions(+), 5 deletions(-) rename docs/reference/{achitecture-subdomains.rst => architecture-subdomains.rst} (100%) diff --git a/docs/concepts/hooks-extension-framework.rst b/docs/concepts/hooks-extension-framework.rst index 2d204120..1ad61964 100644 --- a/docs/concepts/hooks-extension-framework.rst +++ b/docs/concepts/hooks-extension-framework.rst @@ -30,7 +30,7 @@ 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`_. +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 .. _versioning ADR: https://github.com/eduNEXT/openedx-events/blob/main/docs/decisions/0002-events-naming-and-versioning.rst diff --git a/docs/decisions/0003-events-payload.rst b/docs/decisions/0003-events-payload.rst index fcb4f5ee..a1546ca0 100644 --- a/docs/decisions/0003-events-payload.rst +++ b/docs/decisions/0003-events-payload.rst @@ -14,7 +14,7 @@ Given their public promise status, event hooks have maintainability as the main design goal. The contracts we are creating here should be stable enough to support the growth of the extensions community. That said, things should be allowed to evolve in a backwards compatible manner. When things inevitable break, -they should break in CI. Which should not require the code of The Open edX platform to +they should break in CI. Which should not require the code of the Open edX platform to test integrations. diff --git a/docs/how-tos/adding-events-to-a-service.rst b/docs/how-tos/adding-events-to-a-service.rst index 7c028690..532284c7 100644 --- a/docs/how-tos/adding-events-to-a-service.rst +++ b/docs/how-tos/adding-events-to-a-service.rst @@ -1,7 +1,7 @@ How to add an Open edX Event to a service ========================================= -The next step after creating your first event in the Open edX Events library, it's to trigger the event in the service +The next step after creating your first event in the Open edX Events library is to trigger the event in the service you implemented it for. Here is a checklist of what we've done so far when including a new event to a service: - Add the openedx-events library to the service project. diff --git a/docs/how-tos/creating-new-events.rst b/docs/how-tos/creating-new-events.rst index fa55de5d..4bf7e2da 100644 --- a/docs/how-tos/creating-new-events.rst +++ b/docs/how-tos/creating-new-events.rst @@ -12,6 +12,10 @@ When creating a new event, you must justify its implementation. For example, you send a message through slack or open a new issue in the library repository listing your use cases for it. Or even, if you have time, you could accompany your proposal with the implementation of the event to illustrate its behavior. +.. note:: + There is an open discussion about whether organization scoped events would also exist in openedx-events, + in which case this step would be optional. See issue `Organization scoped events `_. + 2. Place your event in an architecture subdomain ------------------------------------------------- @@ -26,7 +30,7 @@ For those reasons, after studying your new event purpose, you must place it in o +-------------------+----------------------------------------------------------------------------------------------------+ | Subdomain name | Description | +===================+====================================================================================================+ -| Course Authoring | Allows educators to create, modify, package, annotate (tag), and share learning content. | +| Content Authoring | Allows educators to create, modify, package, annotate (tag), and share learning content. | +-------------------+----------------------------------------------------------------------------------------------------+ | Learning | Allows learners to consume content and perform actions in a learning activity on the platform. | +-------------------+----------------------------------------------------------------------------------------------------+ diff --git a/docs/quickstarts/index.rst b/docs/quickstarts/index.rst index e54f066f..16cd167c 100644 --- a/docs/quickstarts/index.rst +++ b/docs/quickstarts/index.rst @@ -6,4 +6,3 @@ Quickstarts :caption: Contents: use-events-to-call-webhook - event-bus diff --git a/docs/quickstarts/use-events-to-call-webhook.rst b/docs/quickstarts/use-events-to-call-webhook.rst index d3df286e..3d8b4d86 100644 --- a/docs/quickstarts/use-events-to-call-webhook.rst +++ b/docs/quickstarts/use-events-to-call-webhook.rst @@ -89,6 +89,9 @@ The following is the implementation for the signal receiver listening for the ev "user": user_info, "event_metadata": event_metadata, } + # WARNING: The receiver function implemented in this tutorial was intended to be lightweight, just to + # serve as an example for events' receivers. However, in production, you must use asynchronous tasks + # to avoid creating bottlenecks if you wish for others to use your implementation. requests.post( settings.ZAPIER_REGISTRATION_WEBHOOK, flatten_dict(zapier_payload), diff --git a/docs/reference/achitecture-subdomains.rst b/docs/reference/architecture-subdomains.rst similarity index 100% rename from docs/reference/achitecture-subdomains.rst rename to docs/reference/architecture-subdomains.rst