Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: Add Content Library Collections signals [FC-0062] #386

22 changes: 21 additions & 1 deletion CHANGELOG.rst
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,28 @@ Change Log

.. There should always be an "Unreleased" section for changes pending release.



Unreleased
----------
__________



[9.14.0] - 2024-09-12
---------------------

Added
~~~~~

* Adds event ``CONTENT_OBJECT_ASSOCIATIONS_CHANGED``
navinkarkera marked this conversation as resolved.
Show resolved Hide resolved
navinkarkera marked this conversation as resolved.
Show resolved Hide resolved
* Added new ``LIBRARY_COLLECTION_CREATED``, ``LIBRARY_COLLECTION_UPDATED`` and ``LIBRARY_COLLECTION_DELETED`` events in content_authoring.
* Adds ``ContentObjectChangedData``, which inherits from ContentObjectData and adds an optional list of string ``changes``.

Deprecated
~~~~~~~~~~

* Deprecated event ``CONTENT_OBJECT_TAGS_CHANGED`` in favor of ``CONTENT_OBJECT_ASSOCIATIONS_CHANGED``
Plan to remove after Sumac.

[9.13.0] - 2024-09-05
---------------------
Expand Down
2 changes: 1 addition & 1 deletion openedx_events/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,4 @@
more information about the project.
"""

__version__ = "9.13.0"
__version__ = "9.14.0"
33 changes: 32 additions & 1 deletion openedx_events/content_authoring/data.py
Original file line number Diff line number Diff line change
Expand Up @@ -185,7 +185,7 @@ class LibraryBlockData:
@attr.s(frozen=True)
class ContentObjectData:
"""
Data about changed content object.
Data about a content object.

Arguments:
object_id (str): identifier of the Content object. This represents the id of the course or library block
Expand All @@ -194,3 +194,34 @@ class ContentObjectData:
"""

object_id = attr.ib(type=str)


@attr.s(frozen=True)
class ContentObjectChangedData(ContentObjectData):
"""
Data about a changed content object.

Arguments:
object_id (str): identifier of the Content object. This represents the id of the course or library block
as a string. For example:
block-v1:SampleTaxonomyOrg2+STC1+2023_1+type@vertical+block@f8de78f0897049ce997777a3a31b6ea0

changes: list of changes made to this ContentObject, e.g. "tags", "collections"
If list is empty, assume everything has changed.
"""

changes = attr.ib(type=List[str], factory=list)


@attr.s(frozen=True)
class LibraryCollectionData:
"""
Data about changed content library Collection.

Arguments:
library_key (LibraryLocatorV2): a key that represents a Blockstore-based content library.
collection_key (str): identifies the collection within the library's learning package
"""

library_key = attr.ib(type=LibraryLocatorV2)
collection_key = attr.ib(type=str)
47 changes: 47 additions & 0 deletions openedx_events/content_authoring/signals.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,13 @@
from openedx_events.content_authoring.data import (
CertificateConfigData,
ContentLibraryData,
ContentObjectChangedData,
ContentObjectData,
CourseCatalogData,
CourseData,
DuplicatedXBlockData,
LibraryBlockData,
LibraryCollectionData,
XBlockData,
)
from openedx_events.tooling import OpenEdxPublicSignal
Expand Down Expand Up @@ -200,13 +202,58 @@
}
)

# .. event_type: org.openedx.content_authoring.content.object.associations.changed.v1
# .. event_name: CONTENT_OBJECT_ASSOCIATIONS_CHANGED
# .. event_description: emitted when an object's associations are changed, e.g tags, collections
# .. event_data: ContentObjectData
CONTENT_OBJECT_ASSOCIATIONS_CHANGED = OpenEdxPublicSignal(
event_type="org.openedx.content_authoring.content.object.associations.changed.v1",
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
event_type="org.openedx.content_authoring.content.object.associations.changed.v1",
event_type="org.openedx.content_authoring.content_object.associations.changed.v1",

data={
"content_object": ContentObjectChangedData
}
)

# .. event_type: org.openedx.content_authoring.content.object.tags.changed.v1
# .. event_name: CONTENT_OBJECT_TAGS_CHANGED
# .. event_description: emitted when an object's tags are changed
# DEPRECATED: please use CONTENT_OBJECT_ASSOCIATIONS_CHANGED instead.
# .. event_data: ContentObjectData
CONTENT_OBJECT_TAGS_CHANGED = OpenEdxPublicSignal(
event_type="org.openedx.content_authoring.content.object.tags.changed.v1",
data={
"content_object": ContentObjectData
}
)

# .. event_type: org.openedx.content_authoring.content_library.collection.created.v1
# .. event_name: LIBRARY_COLLECTION_CREATED
# .. event_description: emitted when a content library collection is created
# .. event_data: LibraryCollectionData
LIBRARY_COLLECTION_CREATED = OpenEdxPublicSignal(
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@bradenmacdonald Are we allowed to put new signals in this repo? Or are we supposed to put them in https://github.com/openedx/openedx-events ?

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm actually not sure. Maybe @mariajgrimaldi can answer? What's the difference between this signals.py and that signals.py?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure I follow. This repo es openedx-events and both signals.py files are the same.

You are definitely allowed to propose new signal definitions in this repository and the location is correct. The idea of having the signal here instead of in the edx-platform code is that plugins that will listen for the signal can include this lightweight library in their dependencies instead of requiring edx-platform all the time.

Copy link

@bradenmacdonald bradenmacdonald Aug 27, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

lol whoops, please ignore my confusion. I thought this was edx-platform :/

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No worries. Happy to address this in depth. As before, if you are planning to add a signal into edx-platform, then it would be better to write it here so plugins can use that without the large import.
However, other pattern we have seen is when a plugin defines a new signal and uses it in its own code. In that case if reuse of said signal is not a goal from the devs, then the definition can be left in the plugin as you could import that plugin as a library if you are writing a second level library/plugin.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

My apologies for the noise! I could have sworn there was a signals.py file in openedx-learning, but it's not there now, so not sure what I was on about :)

Copy link
Contributor

@pomegranited pomegranited Aug 28, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah, it was here in this closed PR! signals.py. I'm not going nuts.. 😊

event_type="org.openedx.content_authoring.content_library.collection.created.v1",
data={
"library_collection": LibraryCollectionData
}
)

# .. event_type: org.openedx.content_authoring.content_library.collection.updated.v1
# .. event_name: LIBRARY_COLLECTION_UPDATED
# .. event_description: emitted when when a content library collection is updated
# .. event_data: LibraryCollectionData
LIBRARY_COLLECTION_UPDATED = OpenEdxPublicSignal(
event_type="org.openedx.content_authoring.content_library.collection.updated.v1",
data={
"library_collection": LibraryCollectionData
}
)

# .. event_type: org.openedx.content_authoring.content_library.collection.deleted.v1
# .. event_name: LIBRARY_COLLECTION_DELETED
# .. event_description: emitted when an when a content library collection is deleted
# .. event_data: LibraryCollectionData
LIBRARY_COLLECTION_DELETED = OpenEdxPublicSignal(
event_type="org.openedx.content_authoring.content_library.collection.deleted.v1",
data={
"library_collection": LibraryCollectionData
}
)
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
{
"name": "CloudEvent",
"type": "record",
"doc": "Avro Event Format for CloudEvents created with openedx_events/schema",
"fields": [
{
"name": "content_object",
"type": {
"name": "ContentObjectChangedData",
"type": "record",
"fields": [
{
"name": "object_id",
"type": "string"
},
{
"name": "changes",
"type": {
"type": "array",
"items": "string"
}
}
]
}
}
],
"namespace": "org.openedx.content_authoring.content.object.associations.changed.v1"
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
{
"name": "CloudEvent",
"type": "record",
"doc": "Avro Event Format for CloudEvents created with openedx_events/schema",
"fields": [
{
"name": "library_collection",
"type": {
"name": "LibraryCollectionData",
"type": "record",
"fields": [
{
"name": "library_key",
"type": "string"
},
{
"name": "collection_key",
"type": "string"
}
]
}
}
],
"namespace": "org.openedx.content_authoring.content_library.collection.created.v1"
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
{
"name": "CloudEvent",
"type": "record",
"doc": "Avro Event Format for CloudEvents created with openedx_events/schema",
"fields": [
{
"name": "library_collection",
"type": {
"name": "LibraryCollectionData",
"type": "record",
"fields": [
{
"name": "library_key",
"type": "string"
},
{
"name": "collection_key",
"type": "string"
}
]
}
}
],
"namespace": "org.openedx.content_authoring.content_library.collection.deleted.v1"
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
{
"name": "CloudEvent",
"type": "record",
"doc": "Avro Event Format for CloudEvents created with openedx_events/schema",
"fields": [
{
"name": "library_collection",
"type": {
"name": "LibraryCollectionData",
"type": "record",
"fields": [
{
"name": "library_key",
"type": "string"
},
{
"name": "collection_key",
"type": "string"
}
]
}
}
],
"namespace": "org.openedx.content_authoring.content_library.collection.updated.v1"
}
1 change: 1 addition & 0 deletions openedx_events/event_bus/avro/tests/test_avro.py
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,7 @@ def generate_test_event_data_for_data_type(data_type): # pragma: no cover
LibraryLocatorV2: LibraryLocatorV2.from_string('lib:MITx:reallyhardproblems'),
LibraryUsageLocatorV2: LibraryUsageLocatorV2.from_string('lb:MITx:reallyhardproblems:problem:problem1'),
List[int]: [1, 2, 3],
List[str]: ["hi", "there"],
datetime: datetime.now(),
CCXLocator: CCXLocator(org='edx', course='DemoX', run='Demo_course', ccx='1'),
UUID: uuid4(),
Expand Down