Skip to content

Commit bfae636

Browse files
authored
docs: add link code extension (#469)
1 parent ad025bc commit bfae636

14 files changed

+121
-26
lines changed

CHANGELOG.rst

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,15 @@ Change Log
1616
Unreleased
1717
__________
1818

19+
[9.18.2] - 2025-02-18
20+
---------------------
21+
22+
Changed
23+
~~~~~~~
24+
25+
* Added linkcode Sphinx extension to the documentation.
26+
* Added common_refs.rst file to reuse common references in the documentation.
27+
1928
[9.18.1] - 2025-02-13
2029
---------------------
2130

docs/common_refs.rst

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
.. _Tutor: https://docs.tutor.edly.io/
2+
.. _event-bus-redis: https://github.com/openedx/event-bus-redis
3+
.. _event-bus-kafka: https://github.com/openedx/event-bus-kafka
4+
.. _Django Signals Documentation: https://docs.djangoproject.com/en/4.2/topics/signals/
5+
.. _openedx-events-2-zapier: https://github.com/eduNEXT/openedx-events-2-zapier
6+
.. _Open edX Events To Zapier: https://github.com/eduNEXT/openedx-events-2-zapier
7+
8+
.. Replaces
9+
.. |OpenEdxPublicSignal| replace:: :class:`OpenEdxPublicSignal <openedx_events.tooling.OpenEdxPublicSignal>`

docs/concepts/event-bus.rst

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
.. include:: ../common_refs.rst
2+
13
Open edX Event Bus
24
####################
35

@@ -127,8 +129,6 @@ We encourage you to review the :doc:`../reference/real-life-use-cases` page for
127129
.. _EventProducer: https://github.com/openedx/openedx-events/blob/main/openedx_events/event_bus/__init__.py#L71-L91
128130
.. _EventConsumer: https://github.com/openedx/openedx-events/blob/main/openedx_events/event_bus/__init__.py#L128-L139
129131
.. _publish/subscribe messaging pattern: https://en.wikipedia.org/wiki/Publish%E2%80%93subscribe_pattern
130-
.. _event-bus-redis: https://github.com/openedx/event-bus-redis/
131-
.. _event-bus-kafka: https://github.com/openedx/event-bus-kafka/
132132

133133
**Maintenance chart**
134134

docs/concepts/openedx-events.rst

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
.. include:: ../common_refs.rst
2+
13
Open edX Events
24
#################
35

@@ -81,8 +83,6 @@ As mentioned previously, developers can listen to Open edX Events by registering
8183

8284
For more information on using Open edX Events, refer to the :doc:`../how-tos/create-a-new-event` how-to guide. We also encourage you to explore the :doc:`../reference/real-life-use-cases` section for real-life examples of how Open edX Events are used by the community.
8385

84-
85-
.. _Django Signals Documentation: https://docs.djangoproject.com/en/4.2/topics/signals/
8686
.. _triggering the COURSE_ENROLLMENT_CREATED event: https://github.com/openedx/edx-platform/blob/master/common/djangoapps/student/models/course_enrollment.py#L777-L795
8787
.. _course_enrollment_post_save receiver: https://github.com/openedx/edx-platform/blob/master/openedx/core/djangoapps/notifications/handlers.py#L38-L53
8888
.. _Django signals registry mechanism: https://docs.djangoproject.com/en/4.2/topics/signals/#listening-to-signals

docs/conf.py

Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,9 +10,11 @@
1010
# add these directories to sys.path here. If the directory is relative to the
1111
# documentation root, use os.path.abspath to make it absolute, like shown here.
1212
#
13+
import inspect
1314
import os
1415
import re
1516
import sys
17+
from os.path import dirname, relpath
1618

1719
import git
1820

@@ -46,6 +48,7 @@
4648
'sphinx.ext.autodoc',
4749
'sphinx.ext.autosummary',
4850
'sphinx.ext.napoleon',
51+
'sphinx.ext.linkcode',
4952
]
5053

5154
# Add any paths that contain templates here, relative to this directory.
@@ -157,3 +160,76 @@
157160
settings_source_path = str(root)
158161
settings_repo_url = "https://github.com/openedx/openedx-events"
159162
settings_repo_version = openedx_event_version
163+
openedxevents_repo_url = settings_repo_url
164+
165+
# Linkcode Extension Configuration
166+
167+
REPO_URL = "https://github.com/openedx/openedx-events/blob/main"
168+
169+
def linkcode_resolve(domain: str, info: dict[str, str]) -> str | None:
170+
"""
171+
Resolves source code links for Python objects in Sphinx documentation.
172+
This function is based on the `linkcode_resolve` function in the SciPy project.
173+
174+
Args:
175+
domain (str): The language domain of the object. Only processes Python objects ('py')
176+
info (dict[str, str]): Dictionary containing information about the object to link.
177+
Must contain:
178+
- 'module': Name of the module containing the object
179+
- 'fullname': Complete name of the object including its path
180+
181+
Returns:
182+
str | None: URL to the source code on GitHub with specific line numbers,
183+
or None if the link cannot be resolved
184+
"""
185+
if domain != "py":
186+
return None
187+
188+
modname = info["module"]
189+
fullname = info["fullname"]
190+
191+
submod = sys.modules.get(modname)
192+
if submod is None:
193+
return None
194+
195+
obj = submod
196+
for part in fullname.split("."):
197+
try:
198+
obj = getattr(obj, part)
199+
except Exception:
200+
return None
201+
202+
# Use the original function object if it is wrapped.
203+
while hasattr(obj, "__wrapped__"):
204+
obj = obj.__wrapped__
205+
206+
# Get the file path where the object is defined
207+
try:
208+
# Try to get the file path of the object directly
209+
file_path = inspect.getsourcefile(obj)
210+
except Exception:
211+
try:
212+
# If that fails, try to get the file path of the module where the object is defined
213+
file_path = inspect.getsourcefile(sys.modules[obj.__module__])
214+
except Exception:
215+
# If both attempts fail, set file_path to None
216+
file_path = None
217+
if not file_path:
218+
return None
219+
220+
try:
221+
source, start_line = inspect.getsourcelines(obj)
222+
except Exception:
223+
start_line = None
224+
225+
if start_line:
226+
linespec = f"#L{start_line}-L{start_line + len(source) - 1}"
227+
else:
228+
linespec = ""
229+
230+
import openedx_events
231+
232+
start_dir = os.path.abspath(os.path.join(dirname(openedx_events.__file__), ".."))
233+
file_path = relpath(file_path, start=start_dir).replace(os.path.sep, "/")
234+
235+
return f"{REPO_URL}/{file_path}{linespec}"

docs/how-tos/add-event-bus-support-to-an-event.rst

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
.. include:: ../common_refs.rst
2+
13
Add Event Bus Support to an Open edX Event
24
############################################
35

@@ -30,7 +32,7 @@ Step 2: Define the Event Payload
3032

3133
An Open edX Event is compatible with the event bus when its payload can be serialized, sent, and deserialized by other services. The payload, structured as `attrs data classes`_, must align with the event bus schema format, which in this case is the :term:`Avro Schema`. This schema is used to serialize and deserialize the :term:`Event Payload` when sending it across services.
3234

33-
This ensures the event can be sent by the producer and then re-emitted by the same instance of `OpenEdxPublicSignal`_ on the consumer side, guaranteeing that the data sent and received is identical. Serializing this way should prevent data inconsistencies between services, e.g., timezone issues and precision loss. For more information on the event bus schema format, refer to the :doc:`../decisions/0004-external-event-bus-and-django-signal-events` and :doc:`../decisions/0005-external-event-schema-format` decision records.
35+
This ensures the event can be sent by the producer and then re-emitted by the same instance of |OpenEdxPublicSignal| on the consumer side, guaranteeing that the data sent and received is identical. Serializing this way should prevent data inconsistencies between services, e.g., timezone issues and precision loss. For more information on the event bus schema format, refer to the :doc:`../decisions/0004-external-event-bus-and-django-signal-events` and :doc:`../decisions/0005-external-event-schema-format` decision records.
3436

3537
The data types used in the attrs classes that the current Open edX Event Bus with the chosen schema are:
3638

@@ -129,7 +131,6 @@ To validate that you can consume the event emitted by a service through the even
129131
.. note:: If you implemented a custom serializer for a type in the :term:`Event Payload`, the custom serializer support must be included in both the producer and consumer sides before it can be used.
130132

131133
.. _Avro: https://avro.apache.org/
132-
.. _OpenEdxPublicSignal: https://github.com/openedx/openedx-events/blob/main/openedx_events/tooling.py#L37
133134
.. _attrs data classes: https://www.attrs.org/en/stable/overview.html
134135
.. _serialize_event_data_to_bytes: https://github.com/openedx/openedx-events/blob/main/openedx_events/event_bus/avro/serializer.py#L82-L98
135136
.. _deserialize_bytes_to_event_data: https://github.com/openedx/openedx-events/blob/main/openedx_events/event_bus/avro/deserializer.py#L86-L98

docs/how-tos/consume-an-event.rst

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
.. include:: ../common_refs.rst
2+
13
Consume an Open edX Event
24
##########################
35

@@ -122,9 +124,6 @@ You can review this example to understand how you can test the event receiver an
122124

123125
This way you can ensure that the event receiver is working as expected and that the custom logic is executed when the event is triggered. If the event definition or payload changes in any way, you can catch the error in the test suite instead of in production.
124126

125-
.. _Tutor: https://docs.tutor.edly.io/
126-
.. _Django Signals Documentation: https://docs.djangoproject.com/en/4.2/topics/signals/
127-
.. _openedx-events-2-zapier: https://github.com/eduNEXT/openedx-events-2-zapier
128127
.. _Open edX Django plugin: https://docs.openedx.org/en/latest/developers/concepts/platform_overview.html#new-plugin
129128
.. _OEP-49: https://docs.openedx.org/projects/openedx-proposals/en/latest/best-practices/oep-0049-django-app-patterns.html#signals
130129
.. _list of events: https://docs.openedx.org/projects/openedx-events/en/latest/reference/events.html

docs/how-tos/create-a-new-event.rst

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
.. include:: ../common_refs.rst
2+
13
Create a New Open edX Event with Long-Term Support
24
####################################################
35

@@ -320,7 +322,6 @@ For more details on how the contribution flow works, refer to the :doc:`docs.ope
320322
.. _Add Program Certificate events: https://github.com/openedx/openedx-events/issues/250
321323
.. _attrs: https://www.attrs.org/en/stable/
322324
.. _Tutor: https://docs.tutor.edly.io/
323-
.. _Django Signals Documentation: https://docs.djangoproject.com/en/4.2/topics/signals/
324325
.. _OpenEdxPublicSignal: https://github.com/openedx/openedx-events/blob/main/openedx_events/tooling.py#L37
325326

326327
**Maintenance chart**

docs/how-tos/use-the-event-bus-to-broadcast-and-consume-events.rst

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
.. include:: ../common_refs.rst
2+
13
Use the Open edX Event Bus to Broadcast and Consume Events
24
==========================================================
35

@@ -94,10 +96,7 @@ To consume events, Open edX Events provides a management command called `consume
9496
You can find more a concrete example of how to produce and consume events in the `event-bus-redis`_ documentation.
9597
9698
.. _consume_events: https://github.com/openedx/openedx-events/blob/main/openedx_events/management/commands/consume_events.py
97-
.. _event-bus-redis: https://github.com/openedx/event-bus-redis
98-
.. _event-bus-kafka: https://github.com/openedx/event-bus-kafka
9999
.. _run the consumer locally without tutor: https://github.com/openedx/event-bus-redis/?tab=readme-ov-file#testing-locally
100100
.. _run the consumer locally with tutor: https://github.com/openedx/event-bus-redis/blob/main/docs/tutor_installation.rst#setup-example-with-openedx-course-discovery-and-tutor
101101
.. _general_signal_handler: https://github.com/openedx/openedx-events/blob/main/openedx_events/apps.py#L16-L44
102102
.. _consumer using Tutor hosted in Kubernetes: https://github.com/openedx/tutor-contrib-aspects/blob/master/tutoraspects/patches/k8s-deployments#L535-L588
103-
.. _Tutor: https://docs.tutor.edly.io/

docs/how-tos/use-the-event-bus.rst

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
.. include:: ../common_refs.rst
2+
13
Use the Open edX Event Bus
24
############################
35

@@ -81,8 +83,6 @@ To consume events, Open edX Events provides a management command called `consume
8183
You can find more concrete examples of how to produce and consume events in the `event-bus-redis`_ documentation.
8284
8385
.. _consume_events: https://github.com/openedx/openedx-events/blob/main/openedx_events/management/commands/consume_events.py
84-
.. _event-bus-redis: https://github.com/openedx/event-bus-redis
85-
.. _event-bus-kafka: https://github.com/openedx/event-bus-kafka
8686
.. _run the consumer locally without tutor: https://github.com/openedx/event-bus-redis/?tab=readme-ov-file#testing-locally
8787
.. _run the consumer locally with tutor: https://github.com/openedx/event-bus-redis/blob/main/docs/tutor_installation.rst#setup-example-with-openedx-course-discovery-and-tutor
8888
.. _general_signal_handler: https://github.com/openedx/openedx-events/blob/main/openedx_events/apps.py#L16-L44

0 commit comments

Comments
 (0)