openedx.core.djangoapps.notifications package#
Subpackages#
Submodules#
openedx.core.djangoapps.notifications.apps module#
Config for notifications app
openedx.core.djangoapps.notifications.base_notification module#
Base setup for Notification Apps and Types.
- class openedx.core.djangoapps.notifications.base_notification.NotificationAppManager#
Bases:
objectNotification app manager
- add_core_notification_non_editable(notification_app_attrs, non_editable_channels)#
Adds non_editable for core notification.
- add_core_notification_preference(notification_app_attrs, notification_types)#
Adds core notification preference for the given notification app.
- get_notification_app_preferences()#
Returns notification app preferences for the given name.
- class openedx.core.djangoapps.notifications.base_notification.NotificationPreferenceSyncManager#
Bases:
objectSync Manager for Notification Preferences
- static denormalize_preferences(normalized_preferences)#
Denormalizes preference from simplified to normal structure for saving it in database
- static normalize_preferences(preferences)#
Normalizes preferences to reduce depth of structure. This simplifies matching of preferences reducing effort to get difference.
- static update_preferences(preferences)#
Creates a new preference version from old preferences. New preference is created instead of updating old preference
- Steps to update existing user preference
Normalize existing user preference
Normalize default preferences
Iterate over all the apps in default preference, if app_name exists in existing preference, update new preference app enabled value as existing enabled value
Iterate over all preferences, if preference_name exists in existing preference, update new preference values of web, email and push as existing web, email and push respectively
Denormalize new preference
- class openedx.core.djangoapps.notifications.base_notification.NotificationTypeManager#
Bases:
objectManager for notification types
- get_core_and_non_core_notification_types(notification_app)#
Returns core notification types for the given app name.
- static get_non_core_notification_type_preferences(non_core_notification_types)#
Returns non-core notification type preferences for the given notification types.
- static get_non_editable_notification_channels(notification_types)#
Returns non_editable notification channels for the given notification types.
- get_notification_app_preference(notification_app)#
Returns notification app preferences for the given notification app.
- get_notification_types_by_app(notification_app)#
Returns notification types for the given notification app.
- openedx.core.djangoapps.notifications.base_notification.get_default_values_of_preference(notification_app, notification_type)#
Returns default preference for notification_type
- openedx.core.djangoapps.notifications.base_notification.get_notification_content(notification_type, context)#
Returns notification content for the given notification type with provided context.
openedx.core.djangoapps.notifications.events module#
Events for notification app.
- openedx.core.djangoapps.notifications.events.get_user_course_roles(user, course_id)#
Get the user’s roles in the course.
- openedx.core.djangoapps.notifications.events.get_user_forums_roles(user, course_id)#
Get the user’s roles in the course forums.
- openedx.core.djangoapps.notifications.events.notification_event_context(user, course_id, notification)#
- openedx.core.djangoapps.notifications.events.notification_generated_event(user_ids, app_name, notification_type, course_key, content_url, content)#
Emit an event when a notification is generated.
- openedx.core.djangoapps.notifications.events.notification_preference_update_event(user, course_id, updated_preference)#
Emit an event when a notification preference is updated.
- openedx.core.djangoapps.notifications.events.notification_preferences_viewed_event(request, course_id)#
Emit an event when a user views their notification preferences.
- openedx.core.djangoapps.notifications.events.notification_read_event(user, notification, first_read=False)#
Emit an event when a notification app is marked read for a user.
- openedx.core.djangoapps.notifications.events.notification_tray_opened_event(user, unseen_notifications_count)#
Emit an event when a notification tray is opened.
- openedx.core.djangoapps.notifications.events.notifications_app_all_read_event(user, app_name)#
Emit an event when a notification is read.
openedx.core.djangoapps.notifications.handlers module#
Handlers for notifications
- openedx.core.djangoapps.notifications.handlers.course_enrollment_post_save(signal, sender, enrollment, metadata, **kwargs)#
Watches for post_save signal for creates on the CourseEnrollment table. Generate a CourseNotificationPreference if new Enrollment is created
- openedx.core.djangoapps.notifications.handlers.generate_user_notifications(signal, sender, notification_data, metadata, **kwargs)#
Watches for USER_NOTIFICATION_REQUESTED signal and calls send_web_notifications task
- openedx.core.djangoapps.notifications.handlers.on_user_course_unenrollment(enrollment, **kwargs)#
Removes user notification preference when user un-enrolls from the course
openedx.core.djangoapps.notifications.models module#
Models for notifications
- class openedx.core.djangoapps.notifications.models.CourseNotificationPreference(*args, **kwargs)#
Bases:
TimeStampedModelModel to store notification preferences for users
- exception DoesNotExist#
Bases:
ObjectDoesNotExist
- exception MultipleObjectsReturned#
Bases:
MultipleObjectsReturned
- config_version#
A wrapper for a deferred-loading field. When the value is read from this object the first time, the query is executed.
- course_id#
DO NOT REUSE THIS CLASS. Provided for backwards compatibility only!
A placeholder class that provides a way to set the attribute on the model.
- created#
A wrapper for a deferred-loading field. When the value is read from this object the first time, the query is executed.
- get_app_config(app_name) Dict#
Returns the app config for the given app name.
- get_core_config(app_name) Dict#
Returns the core config for the given app name.
Sample Response: {
‘email’: True, ‘push’: True, ‘web’: True, ‘info’: ‘comment on post and response on comment’
}
- get_next_by_created(*, field=<model_utils.fields.AutoCreatedField: created>, is_next=True, **kwargs)#
- get_next_by_modified(*, field=<model_utils.fields.AutoLastModifiedField: modified>, is_next=True, **kwargs)#
- get_notification_type_config(app_name, notification_type) Dict#
Returns the notification type config for the given app name and notification type.
Sample Response: {
‘email’: True, ‘push’: True, ‘web’: True, ‘info’: ‘Comment on post’
}
- get_notification_types(app_name) Dict#
Returns the notification types for the given app name.
Sample Response: {
- ‘new_comment_on_post’: {
‘email’: True, ‘push’: True, ‘web’: True, ‘info’: ‘Comment on post’
}, ‘new_response_on_comment’: {
‘email’: True, ‘push’: True, ‘web’: True, ‘info’: ‘Response on comment’
},
- get_previous_by_created(*, field=<model_utils.fields.AutoCreatedField: created>, is_next=False, **kwargs)#
- get_previous_by_modified(*, field=<model_utils.fields.AutoLastModifiedField: modified>, is_next=False, **kwargs)#
- static get_updated_user_course_preferences(user, course_id)#
- static get_user_course_preference(user_id, course_id)#
Returns updated courses preferences for a user
- get_web_config(app_name, notification_type) bool#
Returns the web config for the given app name and notification type.
- id#
A wrapper for a deferred-loading field. When the value is read from this object the first time, the query is executed.
- is_active#
A wrapper for a deferred-loading field. When the value is read from this object the first time, the query is executed.
- is_core(app_name, notification_type) bool#
Returns True if the given notification type is a core notification type.
- modified#
A wrapper for a deferred-loading field. When the value is read from this object the first time, the query is executed.
- notification_preference_config#
A wrapper for a deferred-loading field. When the value is read from this object the first time, the query is executed.
- objects = <django.db.models.manager.Manager object>#
- user#
Accessor to the related object on the forward side of a many-to-one or one-to-one (via ForwardOneToOneDescriptor subclass) relation.
In the example:
class Child(Model): parent = ForeignKey(Parent, related_name='children')
Child.parentis aForwardManyToOneDescriptorinstance.
- user_id#
- class openedx.core.djangoapps.notifications.models.Notification(*args, **kwargs)#
Bases:
TimeStampedModelModel to store notifications for users
- exception DoesNotExist#
Bases:
ObjectDoesNotExist
- exception MultipleObjectsReturned#
Bases:
MultipleObjectsReturned
- app_name#
A wrapper for a deferred-loading field. When the value is read from this object the first time, the query is executed.
- property content#
Returns the content for the notification.
- content_context#
A wrapper for a deferred-loading field. When the value is read from this object the first time, the query is executed.
- content_url#
A wrapper for a deferred-loading field. When the value is read from this object the first time, the query is executed.
- course_id#
DO NOT REUSE THIS CLASS. Provided for backwards compatibility only!
A placeholder class that provides a way to set the attribute on the model.
- created#
A wrapper for a deferred-loading field. When the value is read from this object the first time, the query is executed.
- get_next_by_created(*, field=<model_utils.fields.AutoCreatedField: created>, is_next=True, **kwargs)#
- get_next_by_modified(*, field=<model_utils.fields.AutoLastModifiedField: modified>, is_next=True, **kwargs)#
- get_previous_by_created(*, field=<model_utils.fields.AutoCreatedField: created>, is_next=False, **kwargs)#
- get_previous_by_modified(*, field=<model_utils.fields.AutoLastModifiedField: modified>, is_next=False, **kwargs)#
- id#
A wrapper for a deferred-loading field. When the value is read from this object the first time, the query is executed.
- last_read#
A wrapper for a deferred-loading field. When the value is read from this object the first time, the query is executed.
- last_seen#
A wrapper for a deferred-loading field. When the value is read from this object the first time, the query is executed.
- modified#
A wrapper for a deferred-loading field. When the value is read from this object the first time, the query is executed.
- notification_type#
A wrapper for a deferred-loading field. When the value is read from this object the first time, the query is executed.
- objects = <django.db.models.manager.Manager object>#
- user#
Accessor to the related object on the forward side of a many-to-one or one-to-one (via ForwardOneToOneDescriptor subclass) relation.
In the example:
class Child(Model): parent = ForeignKey(Parent, related_name='children')
Child.parentis aForwardManyToOneDescriptorinstance.
- user_id#
- openedx.core.djangoapps.notifications.models.get_course_notification_preference_config()#
Returns the course specific notification preference config.
Sample Response: {
- ‘discussion’: {
‘enabled’: True, ‘not_editable’: {
‘new_comment_on_post’: [‘push’], ‘new_response_on_post’: [‘web’], ‘new_response_on_comment’: [‘web’, ‘push’]
}, ‘notification_types’: {
- ‘new_comment_on_post’: {
‘email’: True, ‘push’: True, ‘web’: True, ‘info’: ‘Comment on post’
}, ‘new_response_on_comment’: {
‘email’: True, ‘push’: True, ‘web’: True, ‘info’: ‘Response on comment’
}, ‘new_response_on_post’: {
‘email’: True, ‘push’: True, ‘web’: True, ‘info’: ‘New Response on Post’
}, ‘core’: {
‘email’: True, ‘push’: True, ‘web’: True, ‘info’: ‘comment on post and response on comment’
}
}, ‘core_notification_types’: []
}
}
- openedx.core.djangoapps.notifications.models.get_course_notification_preference_config_version()#
Returns the notification preference config version.
- openedx.core.djangoapps.notifications.models.get_notification_channels()#
Returns the notification channels.
openedx.core.djangoapps.notifications.permissions module#
Permissions for notifications
- openedx.core.djangoapps.notifications.permissions.allow_any_authenticated_user()#
Function and class decorator that abstracts the authentication and permission checks for api views. Allows both verified and non-verified users
openedx.core.djangoapps.notifications.serializers module#
Serializers for the notifications API.
- class openedx.core.djangoapps.notifications.serializers.CourseOverviewSerializer(*args, **kwargs)#
Bases:
ModelSerializerSerializer for CourseOverview model.
- class Meta#
Bases:
object- fields = ('id', 'display_name')#
- model#
alias of
CourseOverview
- class openedx.core.djangoapps.notifications.serializers.NotificationCourseEnrollmentSerializer(*args, **kwargs)#
Bases:
ModelSerializerSerializer for CourseEnrollment model.
- class openedx.core.djangoapps.notifications.serializers.NotificationSerializer(*args, **kwargs)#
Bases:
ModelSerializerSerializer for the Notification model.
- class Meta#
Bases:
object- fields = ('id', 'app_name', 'notification_type', 'content_context', 'content', 'content_url', 'last_read', 'last_seen', 'created')#
- model#
alias of
Notification
- class openedx.core.djangoapps.notifications.serializers.UserCourseNotificationPreferenceSerializer(*args, **kwargs)#
Bases:
ModelSerializerSerializer for user notification preferences.
- class Meta#
Bases:
object- fields = ('id', 'course_name', 'course_id', 'notification_preference_config')#
- model#
alias of
CourseNotificationPreference
- read_only_fields = ('id', 'course_name', 'course_id')#
- write_only_fields = ('notification_preference_config',)#
- get_course_name(obj)#
Returns course name from course id.
- to_representation(instance)#
Override to_representation to add info of all notification types
- class openedx.core.djangoapps.notifications.serializers.UserNotificationPreferenceUpdateSerializer(*args, **kwargs)#
Bases:
SerializerSerializer for user notification preferences update.
- update(instance, validated_data)#
Update notification preference config.
- validate(attrs)#
Validation for notification preference update form
openedx.core.djangoapps.notifications.tasks module#
This file contains celery tasks for notifications.
- openedx.core.djangoapps.notifications.tasks.create_notification_pref_if_not_exists(user_ids: List, preferences: List, course_id: CourseKey)#
Create notification preference if not exist.
- openedx.core.djangoapps.notifications.tasks.update_user_preference(preference: CourseNotificationPreference, user_id, course_id)#
Update user preference if config version is changed.
openedx.core.djangoapps.notifications.urls module#
URLs for the notifications API.
openedx.core.djangoapps.notifications.utils module#
Utils function for notifications app
- openedx.core.djangoapps.notifications.utils.find_app_in_normalized_apps(app_name, apps_list)#
Returns app preference based on app_name
- openedx.core.djangoapps.notifications.utils.find_pref_in_normalized_prefs(pref_name, app_name, prefs_list)#
Returns preference based on preference_name and app_name
- openedx.core.djangoapps.notifications.utils.get_list_in_batches(input_list, batch_size)#
Divides the list of objects into list of list of objects each of length batch_size.
- openedx.core.djangoapps.notifications.utils.get_show_notifications_tray(user)#
Returns show_notifications_tray as boolean for the courses in which user is enrolled
openedx.core.djangoapps.notifications.views module#
Views for the notifications API.
- class openedx.core.djangoapps.notifications.views.CourseEnrollmentListView(**kwargs)#
Bases:
ListAPIViewAPI endpoint to get active CourseEnrollments for requester.
Permissions: User must be authenticated. Response Format (paginated):
- {
“next”: (str) url_to_next_page_of_courses, “previous”: (str) url_to_previous_page_of_courses, “count”: (int) total_number_of_courses, “num_pages”: (int) total_number_of_pages, “current_page”: (int) current_page_number, “start”: (int) index_of_first_course_on_page, “results” : [
- {
- “course”: {
“id”: (int) course_id, “display_name”: (str) course_display_name
},
],
}
Response Error Codes: - 403: The requester cannot access resource.
- authentication_classes = (<class 'edx_rest_framework_extensions.auth.jwt.authentication.JwtAuthentication'>, <class 'openedx.core.lib.api.authentication.BearerAuthenticationAllowInactiveUser'>, <class 'edx_rest_framework_extensions.auth.session.authentication.SessionAuthenticationAllowInactiveUser'>)#
- get_paginated_response(data)#
Return a response given serialized page data with show_preferences flag.
- get_queryset()#
Get the list of items for this view. This must be an iterable, and may be a queryset. Defaults to using self.queryset.
This method should always be used rather than accessing self.queryset directly, as self.queryset gets evaluated only once, and those results are cached for all subsequent requests.
You may want to override this if you need to provide different querysets depending on the incoming request.
(Eg. return a list of items that is specific to the user)
- list(request, *args, **kwargs)#
Returns the list of active course enrollments for which ENABLE_NOTIFICATIONS Waffle flag is enabled
- permission_classes = (<class 'rest_framework.permissions.IsAuthenticated'>,)#
- serializer_class#
- class openedx.core.djangoapps.notifications.views.MarkNotificationsSeenAPIView(**kwargs)#
Bases:
UpdateAPIViewAPI view for marking user’s all notifications seen for a provided app_name.
- authentication_classes = (<class 'edx_rest_framework_extensions.auth.jwt.authentication.JwtAuthentication'>, <class 'openedx.core.lib.api.authentication.BearerAuthenticationAllowInactiveUser'>, <class 'edx_rest_framework_extensions.auth.session.authentication.SessionAuthenticationAllowInactiveUser'>)#
- permission_classes = (<class 'rest_framework.permissions.IsAuthenticated'>,)#
- update(request, *args, **kwargs)#
Marks all notifications for the given app name seen for the authenticated user.
- Args:
app_name: The name of the app to mark notifications seen for.
- Response Format:
A Response object with a 200 OK status code if the notifications were successfully marked seen.
Response Error Codes: - 400: Bad Request status code if the app name is invalid.
- class openedx.core.djangoapps.notifications.views.NotificationCountView(**kwargs)#
Bases:
APIViewAPI view for getting the unseen notifications count and show_notification_tray flag for a user.
- authentication_classes = (<class 'edx_rest_framework_extensions.auth.jwt.authentication.JwtAuthentication'>, <class 'openedx.core.lib.api.authentication.BearerAuthenticationAllowInactiveUser'>, <class 'edx_rest_framework_extensions.auth.session.authentication.SessionAuthenticationAllowInactiveUser'>)#
- get(request)#
Get the unseen notifications count and show_notification_tray flag for a user.
Permissions: User must be authenticated. Response Format: ```json {
“show_notifications_tray”: (bool) show_notifications_tray, “count”: (int) total_number_of_unseen_notifications, “count_by_app_name”: {
(str) app_name: (int) number_of_unseen_notifications, …
}, “notification_expiry_days”: 60
}#
Response Error Codes: - 403: The requester cannot access resource.
- permission_classes = (<class 'rest_framework.permissions.IsAuthenticated'>,)#
- class openedx.core.djangoapps.notifications.views.NotificationListAPIView(**kwargs)#
Bases:
ListAPIViewAPI view for listing notifications for a user.
Permissions: User must be authenticated. Response Format (paginated):
- {
- “results”[
- {
“id”: (int) notification_id, “app_name”: (str) app_name, “notification_type”: (str) notification_type, “content”: (str) content, “content_context”: (dict) content_context, “content_url”: (str) content_url, “last_read”: (datetime) last_read, “last_seen”: (datetime) last_seen
], “count”: (int) total_number_of_notifications, “next”: (str) url_to_next_page_of_notifications, “previous”: (str) url_to_previous_page_of_notifications, “page_size”: (int) number_of_notifications_per_page,
}
Response Error Codes: - 403: The requester cannot access resource.
- authentication_classes = (<class 'edx_rest_framework_extensions.auth.jwt.authentication.JwtAuthentication'>, <class 'openedx.core.lib.api.authentication.BearerAuthenticationAllowInactiveUser'>, <class 'edx_rest_framework_extensions.auth.session.authentication.SessionAuthenticationAllowInactiveUser'>)#
- get_queryset()#
Override the get_queryset method to filter the queryset by app name, request.user and created
- permission_classes = (<class 'rest_framework.permissions.IsAuthenticated'>,)#
- serializer_class#
alias of
NotificationSerializer
- class openedx.core.djangoapps.notifications.views.NotificationReadAPIView(**kwargs)#
Bases:
APIViewAPI view for marking user notifications as read, either all notifications or a single notification
- authentication_classes = (<class 'edx_rest_framework_extensions.auth.jwt.authentication.JwtAuthentication'>, <class 'openedx.core.lib.api.authentication.BearerAuthenticationAllowInactiveUser'>, <class 'edx_rest_framework_extensions.auth.session.authentication.SessionAuthenticationAllowInactiveUser'>)#
- patch(request, *args, **kwargs)#
Marks all notifications or single notification read for the given app name or notification id for the authenticated user.
Requests: PATCH /api/notifications/read/
- Parameters:
request (Request) –
The request object containing the app name or notification id. {
”app_name”: (str) app_name, “notification_id”: (int) notification_id
}
Returns: - 200: OK status code if the notification or notifications were successfully marked read. - 400: Bad Request status code if the app name is invalid. - 403: Forbidden status code if the user is not authenticated. - 404: Not Found status code if the notification was not found.
- permission_classes = (<class 'rest_framework.permissions.IsAuthenticated'>,)#
- class openedx.core.djangoapps.notifications.views.UserNotificationPreferenceView(**kwargs)#
Bases:
APIViewSupports retrieving and patching the UserNotificationPreference model.
- Example Requests
GET /api/notifications/configurations/{course_id} PATCH /api/notifications/configurations/{course_id}
Example Response: {
‘id’: 1, ‘course_name’: ‘testcourse’, ‘course_id’: ‘course-v1:testorg+testcourse+testrun’, ‘notification_preference_config’: {
- ‘discussion’: {
‘enabled’: False, ‘core’: {
‘info’: ‘’, ‘web’: False, ‘push’: False, ‘email’: False,
}, ‘notification_types’: {
- ‘new_post’: {
‘info’: ‘’, ‘web’: False, ‘push’: False, ‘email’: False,
},
}, ‘not_editable’: {},
},
}
}
- authentication_classes = (<class 'edx_rest_framework_extensions.auth.jwt.authentication.JwtAuthentication'>, <class 'openedx.core.lib.api.authentication.BearerAuthenticationAllowInactiveUser'>, <class 'edx_rest_framework_extensions.auth.session.authentication.SessionAuthenticationAllowInactiveUser'>)#
- get(request, course_key_string)#
Returns notification preference for user for a course.
- Parameters:
request (Request): The request object. course_key_string (int): The ID of the course to retrieve notification preference.
- Returns:
- {
‘id’: 1, ‘course_name’: ‘testcourse’, ‘course_id’: ‘course-v1:testorg+testcourse+testrun’, ‘notification_preference_config’: {
- ‘discussion’: {
‘enabled’: False, ‘core’: {
‘info’: ‘’, ‘web’: False, ‘push’: False, ‘email’: False,
}, ‘notification_types’: {
- ‘new_post’: {
‘info’: ‘’, ‘web’: False, ‘push’: False, ‘email’: False,
},
}, ‘not_editable’: {},
},
}
}
- patch(request, course_key_string)#
Update an existing user notification preference with the data in the request body.
- Parameters:
request (Request) – The request object
course_key_string (int) – The ID of the course of the notification preference to be updated.
- Returns:
The updated preference, serialized using the UserNotificationPreferenceSerializer 404: If the preference does not exist 403: If the user does not have permission to update the preference 400: Validation error
- Return type:
200
- permission_classes = (<class 'rest_framework.permissions.IsAuthenticated'>,)#