lms.djangoapps.discussion.rest_api package#
Submodules#
lms.djangoapps.discussion.rest_api.api module#
Discussion API internal interface
- class lms.djangoapps.discussion.rest_api.api.DiscussionEntity(value)#
Bases:
EnumEnum for different types of discussion related entities
- comment = 'comment'#
- thread = 'thread'#
- class lms.djangoapps.discussion.rest_api.api.DiscussionTopic(topic_id: str | None, name: str, thread_list_url: str, children: List[DiscussionTopic] | None = None, thread_counts: Dict[str, int] | None = None)#
Bases:
objectClass for discussion topic structure
- lms.djangoapps.discussion.rest_api.api.add_stats_for_users_with_null_values(course_stats, users_in_course)#
Update users stats for users with no discussion stats available in course
- lms.djangoapps.discussion.rest_api.api.create_comment(request, comment_data)#
Create a comment.
- Parameters:
request – The django request object used for build_absolute_uri and determining the requesting user.
comment_data – The data for the created comment.
- Returns:
The created comment; see discussion.rest_api.views.CommentViewSet for more detail.
- lms.djangoapps.discussion.rest_api.api.create_thread(request, thread_data)#
Create a thread.
- Parameters:
request – The django request object used for build_absolute_uri and determining the requesting user.
thread_data – The data for the created thread.
- Returns:
The created thread; see discussion.rest_api.views.ThreadViewSet for more detail.
- lms.djangoapps.discussion.rest_api.api.delete_comment(request, comment_id)#
Delete a comment.
- Parameters:
request – The django request object used for build_absolute_uri and determining the requesting user.
comment_id – The id of the comment to delete
- Raises:
PermissionDenied – if user does not have permission to delete thread
- lms.djangoapps.discussion.rest_api.api.delete_thread(request, thread_id)#
Delete a thread.
- Parameters:
request – The django request object used for build_absolute_uri and determining the requesting user.
thread_id – The id for the thread to delete
- Raises:
PermissionDenied – if user does not have permission to delete thread
- lms.djangoapps.discussion.rest_api.api.get_comment_list(request, thread_id, endorsed, page, page_size, flagged=False, requested_fields=None)#
Return the list of comments in the given thread.
- Parameters:
request – The django request object used for build_absolute_uri and determining the requesting user.
thread_id – The id of the thread to get comments for.
endorsed – Boolean indicating whether to get endorsed or non-endorsed comments (or None for all comments). Must be None for a discussion thread and non-None for a question thread.
page – The page number (1-indexed) to retrieve
page_size – The number of comments to retrieve per page
flagged – Filter comments by flagged for abuse status.
requested_fields – Indicates which additional fields to return for
comment. (each) –
- Returns:
A paginated result containing a list of comments; see discussion.rest_api.views.CommentViewSet for more detail.
- lms.djangoapps.discussion.rest_api.api.get_course(request, course_key)#
Return general discussion information for the course.
- Parameters:
request – The django request object used for build_absolute_uri and determining the requesting user.
course_key – The key of the course to get information for
- Returns:
The course information; see discussion.rest_api.views.CourseView for more detail.
- Raises:
CourseNotFoundError – if the course does not exist or is not accessible
to the requesting user –
- lms.djangoapps.discussion.rest_api.api.get_course_discussion_user_stats(request, course_key_str: str, page: int, page_size: int, order_by: UserOrdering = None, username_search_string: str = None) Dict#
Get paginated course discussion stats for users in the course.
- Parameters:
request (Request) – DRF request
course_key_str (str) – course key string
page (int) – Page number to fetch
page_size (int) – Number of items in each page
order_by (UserOrdering) – The ordering to use for the user stats
username_search_string (str) – Partial string to match user names
- Returns:
Paginated data of a user’s discussion stats sorted based on the specified ordering.
- lms.djangoapps.discussion.rest_api.api.get_course_topics(request: Request, course_key: CourseKey, topic_ids: Set[str] | None = None)#
Returns the course topic listing for the given course and user; filtered by ‘topic_ids’ list if given.
- Parameters:
course_key – The key of the course to get topics for
topic_ids – A list of topic IDs for which topic details are requested
- Returns:
A course topic listing dictionary; see discussion.rest_api.views.CourseTopicViews for more detail.
- Raises:
DiscussionNotFoundError – If topic/s not found for given topic_ids.
- lms.djangoapps.discussion.rest_api.api.get_course_topics_v2(course_key: CourseKey, user: User, topic_ids: Iterable[str] | None = None, order_by: TopicOrdering = TopicOrdering.COURSE_STRUCTURE) List[Dict]#
Returns the course topic listing for the given course and user; filtered by ‘topic_ids’ list if given.
- Parameters:
course_key – The key of the course to get topics for
user – The requesting user, for access control
topic_ids – A list of topic IDs for which topic details are requested
order_by – The sort ordering for the returned list of topics
- Returns:
A list of discussion topics for the course.
- Raises:
ValidationError – If unsupported ordering is used.
- lms.djangoapps.discussion.rest_api.api.get_courseware_topics(request: Request, course_key: CourseKey, course: CourseBlock, topic_ids: List[str] | None, thread_counts: Dict[str, Dict[str, int]]) Tuple[List[Dict], Set[str]]#
Returns a list of topic trees for courseware-linked topics.
- Parameters:
request – The django request objects used for build_absolute_uri.
course_key – The key of the course to get discussion threads for.
course – The course for which topics are requested.
topic_ids – A list of topic IDs for which details are requested. This is optional. If None then all course topics are returned.
thread_counts – A map of the thread ids to the count of each type of thread in them e.g. discussion, question
- Returns:
A list of courseware topics and a set of existing topics among topic_ids.
- lms.djangoapps.discussion.rest_api.api.get_learner_active_thread_list(request, course_key, query_params)#
Returns a list of active threads for a particular user
Parameters:
request: The django request objects used for build_absolute_uri course_key: The key of the course query_params: Parameters to fetch data from comments service. It must contain
user_id, course_id, page, per_page, group_id, count_flagged
Returns:
A paginated result containing a list of threads.
** Sample Response {
- “results”: [
- {
“id”: “thread_id”, “author”: “author_username”, “author_label”: “Staff”, “created_at”: “2010-01-01T12:00:00Z”, “updated_at”: “2010-01-01T12:00:00Z”, “raw_body”: “<p></p>”, “rendered_body”: “<p></p>”, “abuse_flagged”: false, “voted”: false, “vote_count”: 0, “editable_fields”: [
“abuse_flagged”, “anonymous”, “close_reason_code”, “closed”, “edit_reason_code”, “following”, “pinned”, “raw_body”, “read”, “title”, “topic_id”, “type”, “voted”
], “can_delete”: true, “anonymous”: false, “anonymous_to_peers”: false, “last_edit”: {
“original_body”: “<p></p>”, “reason_code”: null, “editor_username”: “author_username”, “created_at”: “2010-01-01T12:00:00Z”
}, “course_id”: “course-v1:edX+DemoX+Demo_Course”, “topic_id”: “i4x-edx-eiorguegnru-course-foobarbaz”, “group_id”: null, “group_name”: null, “type”: “discussion”, “preview_body”: “”, “abuse_flagged_count”: null, “title”: “Post Title”, “pinned”: false, “closed”: false, “following”: false, “comment_count”: 1, “unread_comment_count”: 0, “comment_list_url”: “http://localhost:18000/api/discussion/v1/comments/?thread_id=thread_id”, “endorsed_comment_list_url”: null, “non_endorsed_comment_list_url”: null, “read”: true, “has_endorsed”: false, “close_reason”: null, “closed_by”: null, “users”: {
- “username”: {
- “profile”: {
- “image”: {
“has_image”: false, “image_url_full”: “http://localhost:18000/static/images/profiles/default_500.png”, “image_url_large”: “http://localhost:18000/static/images/profiles/default_120.png”, “image_url_medium”: “http://localhost:18000/static/images/profiles/default_50.png”, “image_url_small”: “http://localhost:18000/static/images/profiles/default_30.png”
}
}
}
}
], “pagination”: {
“next”: None, “previous”: None, “count”: 10, “num_pages”: 1
}
}
- lms.djangoapps.discussion.rest_api.api.get_non_courseware_topics(request: Request, course_key: CourseKey, course: CourseBlock, topic_ids: List[str] | None, thread_counts: Dict[str, Dict[str, int]]) Tuple[List[Dict], Set[str]]#
Returns a list of topic trees that are not linked to courseware.
- Parameters:
request – The django request objects used for build_absolute_uri.
course_key – The key of the course to get discussion threads for.
course – The course for which topics are requested.
topic_ids – A list of topic IDs for which details are requested. This is optional. If None then all course topics are returned.
thread_counts – A map of the thread ids to the count of each type of thread in them e.g. discussion, question
- Returns:
A list of non-courseware topics and a set of existing topics among topic_ids.
- lms.djangoapps.discussion.rest_api.api.get_response_comments(request, comment_id, page, page_size, requested_fields=None)#
Return the list of comments for the given thread response.
- Parameters:
request – The django request object used for build_absolute_uri and determining the requesting user.
comment_id – The id of the comment/response to get child comments for.
page – The page number (1-indexed) to retrieve
page_size – The number of comments to retrieve per page
requested_fields – Indicates which additional fields to return for
comment. (each child) –
- Returns:
A paginated result containing a list of comments
- lms.djangoapps.discussion.rest_api.api.get_thread(request, thread_id, requested_fields=None, course_id=None)#
Retrieve a thread.
- Parameters:
request – The django request object used for build_absolute_uri and determining the requesting user.
thread_id – The id for the thread to retrieve
course_id – the id of the course the threads belongs to
requested_fields – Indicates which additional fields to return for
thread. (i.e. ['profile_image']) –
- lms.djangoapps.discussion.rest_api.api.get_thread_list(request: Request, course_key: CourseKey, page: int, page_size: int, topic_id_list: List[str] | None = None, text_search: str | None = None, following: bool | None = False, author: str | None = None, thread_type: Literal['discussion', 'question'] | None = None, flagged: bool | None = None, view: Literal['unread', 'unanswered'] | None = None, order_by: Literal['last_activity_at', 'comment_count', 'vote_count'] = 'last_activity_at', order_direction: Literal['desc'] = 'desc', requested_fields: List[Literal['profile_image']] | None = None, count_flagged: bool | None = None)#
Return the list of all discussion threads pertaining to the given course
Parameters:
request: The django request objects used for build_absolute_uri course_key: The key of the course to get discussion threads for page: The page number (1-indexed) to retrieve page_size: The number of threads to retrieve per page count_flagged: If true, fetch the count of flagged items in each thread topic_id_list: The list of topic_ids to get the discussion threads for text_search A text search query string to match following: If true, retrieve only threads the requester is following author: If provided, retrieve only threads by this author thread_type: filter for “discussion” or “question threads flagged: filter for only threads that are flagged view: filters for either “unread” or “unanswered” threads order_by: The key in which to sort the threads by. The only values are
“last_activity_at”, “comment_count”, and “vote_count”. The default is “last_activity_at”.
- order_direction: The direction in which to sort the threads by. The default
and only value is “desc”. This will be removed in a future major version.
- requested_fields: Indicates which additional fields to return
for each thread. (i.e. [‘profile_image’])
Note that topic_id_list, text_search, and following are mutually exclusive.
Returns:
A paginated result containing a list of threads; see discussion.rest_api.views.ThreadViewSet for more detail.
Raises:
PermissionDenied: If count_flagged is set but the user isn’t privileged ValidationError: if an invalid value is passed for a field. ValueError: if more than one of the mutually exclusive parameters is
provided
CourseNotFoundError: if the requesting user does not have access to the requested course PageNotFoundError: if page requested is beyond the last
- lms.djangoapps.discussion.rest_api.api.get_thread_list_url(request, course_key, topic_id_list=None, following=False)#
Returns the URL for the thread_list_url field, given a list of topic_ids
- lms.djangoapps.discussion.rest_api.api.get_user_comments(request: Request, author: User, course_key: CourseKey, flagged: bool = False, page: int = 1, page_size: int = 10, requested_fields: List[str] | None = None)#
Returns the list of comments made by the user in the requested course.
- Parameters:
request – The django request object.
author – The user to get comments from.
course_key – The course locator to filter the comments.
flagged – Filter comments by flagged status.
page – The page number (1-indexed) to retrieve
page_size – The number of comments to retrieve per page
requested_fields – Indicates which additional fields to return for
comment. (each child) –
- Returns:
A paginated result containing a list of comments.
- lms.djangoapps.discussion.rest_api.api.get_users_without_stats(username_search_string, course_key, page_number, page_size, request, is_privileged)#
This return users with no user stats. This function will be deprecated when this ticket DOS-3414 is resolved
- lms.djangoapps.discussion.rest_api.api.get_v2_course_topics_as_v1(request: Request, course_key: CourseKey, topic_ids: Iterable[str] | None = None)#
Returns v2 topics in v1 structure
- lms.djangoapps.discussion.rest_api.api.get_v2_courseware_topics_as_v1(request, course_key, sequentials, topics)#
Returns v2 courseware topics list as v1 structure
- lms.djangoapps.discussion.rest_api.api.get_v2_non_courseware_topics_as_v1(request, course_key, topics)#
Takes v2 topics list and returns v1 list of non courseware topics
- lms.djangoapps.discussion.rest_api.api.update_comment(request, comment_id, update_data)#
Update a comment.
- Parameters:
request – The django request object used for build_absolute_uri and determining the requesting user.
comment_id – The id for the comment to update.
update_data – The data to update in the comment.
- Returns:
The updated comment; see discussion.rest_api.views.CommentViewSet for more detail.
- Raises:
CommentNotFoundError – if the comment does not exist or is not accessible
to the requesting user –
PermissionDenied – if the comment is accessible to but not editable by the requesting user
ValidationError – if there is an error applying the update (e.g. raw_body is empty or thread_id is included)
- lms.djangoapps.discussion.rest_api.api.update_thread(request, thread_id, update_data)#
Update a thread.
- Parameters:
request – The django request object used for build_absolute_uri and determining the requesting user.
thread_id – The id for the thread to update.
update_data – The data to update in the thread.
- Returns:
The updated thread; see discussion.rest_api.views.ThreadViewSet for more detail.
lms.djangoapps.discussion.rest_api.exceptions module#
Errors used by the Discussion API.
- exception lms.djangoapps.discussion.rest_api.exceptions.CommentNotFoundError#
Bases:
ObjectDoesNotExistComment was not found.
- exception lms.djangoapps.discussion.rest_api.exceptions.DiscussionBlackOutException(detail=None, code=None)#
Bases:
APIExceptionDiscussions are in blackout period.
- default_detail = 'Discussions are in blackout period.'#
- status_code = 403#
- exception lms.djangoapps.discussion.rest_api.exceptions.DiscussionDisabledError#
Bases:
ObjectDoesNotExistDiscussion is disabled.
- exception lms.djangoapps.discussion.rest_api.exceptions.ThreadNotFoundError#
Bases:
ObjectDoesNotExistThread was not found.
lms.djangoapps.discussion.rest_api.forms module#
Discussion API forms
- class lms.djangoapps.discussion.rest_api.forms.CommentActionsForm(data=None, files=None, auto_id='id_%s', prefix=None, initial=None, error_class=<class 'django.forms.utils.ErrorList'>, label_suffix=None, empty_permitted=False, field_order=None, use_required_attribute=None, renderer=None)#
Bases:
FormA form to handle fields in comment creation/update that require separate interactions with the comments service.
- base_fields = {'abuse_flagged': <django.forms.fields.BooleanField object>, 'voted': <django.forms.fields.BooleanField object>}#
- declared_fields = {'abuse_flagged': <django.forms.fields.BooleanField object>, 'voted': <django.forms.fields.BooleanField object>}#
- property media#
Return all media required to render the widgets on this form.
- class lms.djangoapps.discussion.rest_api.forms.CommentGetForm(data=None, files=None, auto_id='id_%s', prefix=None, initial=None, error_class=<class 'django.forms.utils.ErrorList'>, label_suffix=None, empty_permitted=False, field_order=None, use_required_attribute=None, renderer=None)#
Bases:
_PaginationFormA form to validate query parameters in the comment retrieval endpoint
- base_fields = {'page': <django.forms.fields.IntegerField object>, 'page_size': <django.forms.fields.IntegerField object>, 'requested_fields': <openedx.core.djangoapps.util.forms.MultiValueField object>}#
- declared_fields = {'page': <django.forms.fields.IntegerField object>, 'page_size': <django.forms.fields.IntegerField object>, 'requested_fields': <openedx.core.djangoapps.util.forms.MultiValueField object>}#
- property media#
Return all media required to render the widgets on this form.
- class lms.djangoapps.discussion.rest_api.forms.CommentListGetForm(data=None, files=None, auto_id='id_%s', prefix=None, initial=None, error_class=<class 'django.forms.utils.ErrorList'>, label_suffix=None, empty_permitted=False, field_order=None, use_required_attribute=None, renderer=None)#
Bases:
_PaginationFormA form to validate query parameters in the comment list retrieval endpoint
- base_fields = {'endorsed': <openedx.core.djangoapps.util.forms.ExtendedNullBooleanField object>, 'flagged': <django.forms.fields.BooleanField object>, 'page': <django.forms.fields.IntegerField object>, 'page_size': <django.forms.fields.IntegerField object>, 'requested_fields': <openedx.core.djangoapps.util.forms.MultiValueField object>, 'thread_id': <django.forms.fields.CharField object>}#
- declared_fields = {'endorsed': <openedx.core.djangoapps.util.forms.ExtendedNullBooleanField object>, 'flagged': <django.forms.fields.BooleanField object>, 'page': <django.forms.fields.IntegerField object>, 'page_size': <django.forms.fields.IntegerField object>, 'requested_fields': <openedx.core.djangoapps.util.forms.MultiValueField object>, 'thread_id': <django.forms.fields.CharField object>}#
- property media#
Return all media required to render the widgets on this form.
- class lms.djangoapps.discussion.rest_api.forms.CourseActivityStatsForm(data=None, files=None, auto_id='id_%s', prefix=None, initial=None, error_class=<class 'django.forms.utils.ErrorList'>, label_suffix=None, empty_permitted=False, field_order=None, use_required_attribute=None, renderer=None)#
Bases:
_PaginationFormForm for validating course activity stats API query parameters
- base_fields = {'order_by': <django.forms.fields.ChoiceField object>, 'page': <django.forms.fields.IntegerField object>, 'page_size': <django.forms.fields.IntegerField object>, 'username': <django.forms.fields.CharField object>}#
- declared_fields = {'order_by': <django.forms.fields.ChoiceField object>, 'page': <django.forms.fields.IntegerField object>, 'page_size': <django.forms.fields.IntegerField object>, 'username': <django.forms.fields.CharField object>}#
- property media#
Return all media required to render the widgets on this form.
- class lms.djangoapps.discussion.rest_api.forms.CourseDiscussionRolesForm(*args, **kwargs)#
Bases:
CourseDiscussionSettingsFormA form to validate the fields in the course discussion roles requests.
- ROLE_CHOICES = (('Moderator', 'Moderator'), ('Community TA', 'Moderator'), ('Group Moderator', 'Group Moderator'))#
- base_fields = {'course_id': <django.forms.fields.CharField object>, 'rolename': <django.forms.fields.ChoiceField object>}#
- clean_rolename()#
Validate the ‘rolename’ value.
- declared_fields = {'course_id': <django.forms.fields.CharField object>, 'rolename': <django.forms.fields.ChoiceField object>}#
- property media#
Return all media required to render the widgets on this form.
- class lms.djangoapps.discussion.rest_api.forms.CourseDiscussionSettingsForm(*args, **kwargs)#
Bases:
FormA form to validate the fields in the course discussion settings requests.
- base_fields = {'course_id': <django.forms.fields.CharField object>}#
- clean_course_id()#
Validate the ‘course_id’ value
- declared_fields = {'course_id': <django.forms.fields.CharField object>}#
- property media#
Return all media required to render the widgets on this form.
- class lms.djangoapps.discussion.rest_api.forms.ThreadActionsForm(data=None, files=None, auto_id='id_%s', prefix=None, initial=None, error_class=<class 'django.forms.utils.ErrorList'>, label_suffix=None, empty_permitted=False, field_order=None, use_required_attribute=None, renderer=None)#
Bases:
FormA form to handle fields in thread creation/update that require separate interactions with the comments service.
- base_fields = {'abuse_flagged': <django.forms.fields.BooleanField object>, 'following': <django.forms.fields.BooleanField object>, 'pinned': <django.forms.fields.BooleanField object>, 'read': <django.forms.fields.BooleanField object>, 'voted': <django.forms.fields.BooleanField object>}#
- declared_fields = {'abuse_flagged': <django.forms.fields.BooleanField object>, 'following': <django.forms.fields.BooleanField object>, 'pinned': <django.forms.fields.BooleanField object>, 'read': <django.forms.fields.BooleanField object>, 'voted': <django.forms.fields.BooleanField object>}#
- property media#
Return all media required to render the widgets on this form.
- class lms.djangoapps.discussion.rest_api.forms.ThreadListGetForm(data=None, files=None, auto_id='id_%s', prefix=None, initial=None, error_class=<class 'django.forms.utils.ErrorList'>, label_suffix=None, empty_permitted=False, field_order=None, use_required_attribute=None, renderer=None)#
Bases:
_PaginationFormA form to validate query parameters in the thread list retrieval endpoint
- EXCLUSIVE_PARAMS = ['topic_id', 'text_search', 'following']#
- base_fields = {'author': <django.forms.fields.CharField object>, 'count_flagged': <openedx.core.djangoapps.util.forms.ExtendedNullBooleanField object>, 'course_id': <django.forms.fields.CharField object>, 'flagged': <openedx.core.djangoapps.util.forms.ExtendedNullBooleanField object>, 'following': <openedx.core.djangoapps.util.forms.ExtendedNullBooleanField object>, 'order_by': <django.forms.fields.ChoiceField object>, 'order_direction': <django.forms.fields.ChoiceField object>, 'page': <django.forms.fields.IntegerField object>, 'page_size': <django.forms.fields.IntegerField object>, 'requested_fields': <openedx.core.djangoapps.util.forms.MultiValueField object>, 'text_search': <django.forms.fields.CharField object>, 'thread_type': <django.forms.fields.ChoiceField object>, 'topic_id': <openedx.core.djangoapps.util.forms.MultiValueField object>, 'view': <django.forms.fields.ChoiceField object>}#
- clean()#
Hook for doing any extra form-wide cleaning after Field.clean() has been called on every field. Any ValidationError raised by this method will not be associated with a particular field; it will have a special-case association with the field named ‘__all__’.
- clean_course_id()#
Validate course_id
- clean_following()#
Validate following
- clean_order_by()#
Return a default choice
- clean_order_direction()#
Return a default choice
- declared_fields = {'author': <django.forms.fields.CharField object>, 'count_flagged': <openedx.core.djangoapps.util.forms.ExtendedNullBooleanField object>, 'course_id': <django.forms.fields.CharField object>, 'flagged': <openedx.core.djangoapps.util.forms.ExtendedNullBooleanField object>, 'following': <openedx.core.djangoapps.util.forms.ExtendedNullBooleanField object>, 'order_by': <django.forms.fields.ChoiceField object>, 'order_direction': <django.forms.fields.ChoiceField object>, 'page': <django.forms.fields.IntegerField object>, 'page_size': <django.forms.fields.IntegerField object>, 'requested_fields': <openedx.core.djangoapps.util.forms.MultiValueField object>, 'text_search': <django.forms.fields.CharField object>, 'thread_type': <django.forms.fields.ChoiceField object>, 'topic_id': <openedx.core.djangoapps.util.forms.MultiValueField object>, 'view': <django.forms.fields.ChoiceField object>}#
- property media#
Return all media required to render the widgets on this form.
- class lms.djangoapps.discussion.rest_api.forms.TopicListGetForm(data=None, files=None, auto_id='id_%s', prefix=None, initial=None, error_class=<class 'django.forms.utils.ErrorList'>, label_suffix=None, empty_permitted=False, field_order=None, use_required_attribute=None, renderer=None)#
Bases:
FormForm for the topics API get query parameters.
- base_fields = {'order_by': <django.forms.fields.ChoiceField object>, 'topic_id': <django.forms.fields.CharField object>}#
- clean_topic_id()#
- declared_fields = {'order_by': <django.forms.fields.ChoiceField object>, 'topic_id': <django.forms.fields.CharField object>}#
- property media#
Return all media required to render the widgets on this form.
- class lms.djangoapps.discussion.rest_api.forms.UserCommentListGetForm(data=None, files=None, auto_id='id_%s', prefix=None, initial=None, error_class=<class 'django.forms.utils.ErrorList'>, label_suffix=None, empty_permitted=False, field_order=None, use_required_attribute=None, renderer=None)#
Bases:
_PaginationFormA form to validate query parameters in the comment list retrieval endpoint
- base_fields = {'course_id': <django.forms.fields.CharField object>, 'flagged': <django.forms.fields.BooleanField object>, 'page': <django.forms.fields.IntegerField object>, 'page_size': <django.forms.fields.IntegerField object>, 'requested_fields': <openedx.core.djangoapps.util.forms.MultiValueField object>}#
- clean_course_id()#
Validate course_id
- declared_fields = {'course_id': <django.forms.fields.CharField object>, 'flagged': <django.forms.fields.BooleanField object>, 'page': <django.forms.fields.IntegerField object>, 'page_size': <django.forms.fields.IntegerField object>, 'requested_fields': <openedx.core.djangoapps.util.forms.MultiValueField object>}#
- property media#
Return all media required to render the widgets on this form.
lms.djangoapps.discussion.rest_api.pagination module#
Discussion API pagination support
- class lms.djangoapps.discussion.rest_api.pagination.DiscussionAPIPagination(request, page_num, num_pages, result_count=0)#
Bases:
NamespacedPageNumberPaginationSubclasses NamespacedPageNumberPagination to provide custom implementation of pagination metadata by overriding it’s methods
- get_next_link()#
Returns absolute url of the next page if there’s a next page available otherwise returns None
- get_num_pages()#
Returns total number of pages the response is divided into
- get_previous_link()#
Returns absolute url of the previous page if there’s a previous page available otherwise returns None
- get_result_count()#
Returns total number of results
lms.djangoapps.discussion.rest_api.permissions module#
Discussion API permission logic
- class lms.djangoapps.discussion.rest_api.permissions.IsStaffOrAdmin#
Bases:
BasePermissionPermission that checks if the user is staff or an admin.
- has_permission(request, view)#
Returns true if the user is admin or staff and request method is GET.
- class lms.djangoapps.discussion.rest_api.permissions.IsStaffOrCourseTeamOrEnrolled#
Bases:
BasePermissionPermission that checks to see if the user is allowed to post or comment in the course.
- has_permission(request, view)#
Returns true if the user is enrolled or is staff.
- lms.djangoapps.discussion.rest_api.permissions.can_delete(cc_content, context)#
Return True if the requester can delete the given content, False otherwise
- lms.djangoapps.discussion.rest_api.permissions.get_editable_fields(cc_content: Thread | Comment, context: Dict) Set[str]#
Return the set of fields that the requester can edit on the given content
- lms.djangoapps.discussion.rest_api.permissions.get_initializable_comment_fields(context)#
Return the set of fields that the requester can initialize for a comment
Any field that is editable by the author should also be initializable.
- lms.djangoapps.discussion.rest_api.permissions.get_initializable_thread_fields(context)#
Return the set of fields that the requester can initialize for a thread
Any field that is editable by the author should also be initializable.
lms.djangoapps.discussion.rest_api.render module#
Content rendering functionality
Note that this module is designed to imitate the front end behavior as implemented in Markdown.Sanitizer.js.
- lms.djangoapps.discussion.rest_api.render.render_body(raw_body)#
Render raw_body to HTML.
This includes the following steps:
Convert Markdown to HTML
Sanitise HTML using bleach
Note that this does not prevent Markdown syntax inside a MathJax block from being processed, which the forums JavaScript code does.
lms.djangoapps.discussion.rest_api.serializers module#
Discussion API serializers
- class lms.djangoapps.discussion.rest_api.serializers.BlackoutDateSerializer(*args, **kwargs)#
Bases:
SerializerSerializer for blackout dates.
- class lms.djangoapps.discussion.rest_api.serializers.CommentSerializer(*args, **kwargs)#
Bases:
_ContentSerializerA serializer for comment data.
N.B. This should not be used with a comment_client Comment object that has not had retrieve() called, because of the interaction between DRF’s attempts at introspection and Comment’s __getattr__.
- create(validated_data)#
- get_abuse_flagged_any_user(obj)#
Returns a boolean indicating whether any user has flagged the content as abusive.
- get_children(obj)#
- get_endorsed_at(obj)#
Returns the timestamp for the endorsement, if available. This information is unavailable outside the thread context.
- get_endorsed_by(obj)#
Returns the username of the endorsing user, if the information is available and would not identify the author of an anonymous thread. This information is unavailable outside the thread context.
- get_endorsed_by_label(obj)#
Returns the role label (i.e. “Staff” or “Community TA”) for the endorsing user. This information is unavailable outside the thread context.
- non_updatable_fields = {'parent_id', 'thread_id'}#
- to_representation(data)#
Object instance -> Dict of primitive datatypes.
- update(instance, validated_data)#
- validate(attrs)#
Ensure that parent_id identifies a comment that is actually in the thread identified by thread_id and does not violate the configured maximum depth.
- class lms.djangoapps.discussion.rest_api.serializers.CourseMetadataSerailizer(*args, **kwargs)#
Bases:
SerializerSerializer for course metadata.
- class lms.djangoapps.discussion.rest_api.serializers.DiscussionRolesListSerializer(*args, **kwargs)#
Bases:
SerializerSerializer for course discussion roles member list.
- create(validated_data)#
Overridden create abstract method
- get_division_scheme(obj)#
Return the division scheme for the course.
- get_results(obj)#
Return the nested serializer data representing a list of member users.
- update(instance, validated_data)#
Overridden update abstract method
- class lms.djangoapps.discussion.rest_api.serializers.DiscussionRolesMemberSerializer(*args, **kwargs)#
Bases:
SerializerSerializer for course discussion roles member data.
- create(validated_data)#
Overriden create abstract method
- get_group_name(instance)#
Return the group name of the user.
- update(instance, validated_data)#
Overriden update abstract method
- class lms.djangoapps.discussion.rest_api.serializers.DiscussionRolesSerializer(*args, **kwargs)#
Bases:
SerializerSerializer for course discussion roles.
- ACTION_CHOICES = (('allow', 'allow'), ('revoke', 'revoke'))#
- create(validated_data)#
Overriden create abstract method
- update(instance, validated_data)#
Overriden update abstract method
- validate(attrs)#
Validate the data at an object level.
- class lms.djangoapps.discussion.rest_api.serializers.DiscussionTopicSerializer(*args, **kwargs)#
Bases:
SerializerSerializer for DiscussionTopic
- create(validated_data)#
Overriden create abstract method
- get_children(obj)#
Returns a list of children of DiscussionTopicSerializer type
- update(instance, validated_data)#
Overriden update abstract method
- class lms.djangoapps.discussion.rest_api.serializers.DiscussionTopicSerializerV2(*args, **kwargs)#
Bases:
SerializerSerializer for new style topics.
- get_thread_counts(obj: DiscussionTopicLink) Dict[str, int]#
Get thread counts from provided context
- class lms.djangoapps.discussion.rest_api.serializers.ReasonCodeSeralizer(*args, **kwargs)#
Bases:
SerializerSerializer for reason codes.
- class lms.djangoapps.discussion.rest_api.serializers.ThreadSerializer(*args, **kwargs)#
Bases:
_ContentSerializerA serializer for thread data.
N.B. This should not be used with a comment_client Thread object that has not had retrieve() called, because of the interaction between DRF’s attempts at introspection and Thread’s __getattr__.
- create(validated_data)#
- get_abuse_flagged_count(obj)#
Returns the number of users that flagged content as abusive only if user has staff permissions
- get_close_reason(obj)#
Returns the reason for which the thread was closed.
- get_closed_by(obj)#
Returns the username of the moderator who closed this thread, only to other privileged users and author.
- get_closed_by_label(obj)#
Returns the role label for the user who closed the post.
- get_comment_count(obj)#
Increments comment count to include post and returns total count of contributions (i.e. post + responses + comments) for the thread
- get_comment_list_url(obj, endorsed=None)#
Returns the URL to retrieve the thread’s comments, optionally including the endorsed query parameter.
- get_endorsed_comment_list_url(obj)#
Returns the URL to retrieve the thread’s endorsed comments.
- get_following(obj)#
Returns a boolean indicating whether the requester is following the thread.
- get_group_name(obj)#
Returns the name of the group identified by the thread’s group_id.
- get_non_endorsed_comment_list_url(obj)#
Returns the URL to retrieve the thread’s non-endorsed comments.
- get_pinned(obj)#
Compensate for the fact that some threads in the comments service do not have the pinned field set.
- get_preview_body(obj)#
Returns a cleaned version of the thread’s body to display in a preview capacity.
- get_unread_comment_count(obj)#
Returns the number of unread comments. If the thread has never been read, this additionally includes 1 for the post itself, in addition to its responses and comments.
- non_updatable_fields = {'course_id'}#
- update(instance, validated_data)#
- class lms.djangoapps.discussion.rest_api.serializers.TopicOrdering(value)#
Bases:
TextChoicesEnum for the available options for ordering topics.
- ACTIVITY = 'activity'#
- COURSE_STRUCTURE = 'course_structure'#
- NAME = 'name'#
- class lms.djangoapps.discussion.rest_api.serializers.UserStatsSerializer(*args, **kwargs)#
Bases:
SerializerSerializer for course user stats.
- to_representation(instance)#
Remove flag counts if user is not privileged.
- lms.djangoapps.discussion.rest_api.serializers.get_context(course, request, thread=None)#
Returns a context appropriate for use with ThreadSerializer or (if thread is provided) CommentSerializer.
- lms.djangoapps.discussion.rest_api.serializers.validate_close_reason_code(value)#
Validate that the value is a valid close reason code.
Raises: ValidationError
- lms.djangoapps.discussion.rest_api.serializers.validate_edit_reason_code(value)#
Validate that the value is a valid edit reason code.
Raises: ValidationError
- lms.djangoapps.discussion.rest_api.serializers.validate_not_blank(value)#
Validate that a value is not an empty string or whitespace.
Raises: ValidationError
lms.djangoapps.discussion.rest_api.tasks module#
Contain celery tasks
lms.djangoapps.discussion.rest_api.urls module#
Discussion API URLs
lms.djangoapps.discussion.rest_api.utils module#
Utils for discussion API.
- class lms.djangoapps.discussion.rest_api.utils.AttributeDict#
Bases:
dictConverts Dict Keys into Attributes
- class lms.djangoapps.discussion.rest_api.utils.DiscussionNotificationSender(thread, course, creator, parent_id=None)#
Bases:
objectClass to send notifications to users who are subscribed to the thread.
- send_new_comment_notification()#
Send notification to parent thread creator i.e. comment on the response.
- send_new_comment_on_response_notification()#
Send notification to parent response creator i.e. comment on the response. Do not send notification if author of response is same as author of post.
- send_new_response_notification()#
Send notification to users who are subscribed to the main thread/post i.e. there is a response to the main thread.
- send_new_thread_created_notification()#
Send notification based on notification_type
- lms.djangoapps.discussion.rest_api.utils.add_stats_for_users_with_no_discussion_content(course_stats, users_in_course)#
Update users stats for users with no discussion stats available in course
- lms.djangoapps.discussion.rest_api.utils.add_thread_stats_to_subsection(topics_list)#
Add topic stats at subsection by adding stats of all units in the topic
- lms.djangoapps.discussion.rest_api.utils.create_blocks_params(course_usage_key, user)#
Returns param dict that is needed to get blocks
- lms.djangoapps.discussion.rest_api.utils.create_discussion_children_from_ids(children_ids, blocks, topics)#
Takes ids of discussion and return discussion dictionary
- lms.djangoapps.discussion.rest_api.utils.create_topics_v3_structure(blocks, topics)#
Create V3 topics structure from blocks and v2 topics
- lms.djangoapps.discussion.rest_api.utils.discussion_open_for_user(course, user)#
Check if the course discussion are open or not for user.
- Parameters:
course – Course to check discussions for
user – User to check for privileges in course
- lms.djangoapps.discussion.rest_api.utils.filter_topic_from_discussion_id(discussion_id, topics_list)#
Returns topic based on discussion id
- lms.djangoapps.discussion.rest_api.utils.get_archived_topics(filtered_topic_ids: List[str], topics: List[Dict[str, str]]) List[Dict[str, str]]#
This function takes a list of topic ids and a list of topics, and returns the list of archived topics.
A topic is considered archived if it has a non-null usage_key field.
Args: - filtered_topic_ids (List[str]): A list of topic ids to filter on. - topics (List[Dict[str, str]]): A list of topic dictionaries. - Each dictionary should have a ‘id’ and a ‘usage_key’ field.
Returns: - A list of archived topic dictionaries, with the same format as the input topics.
- lms.djangoapps.discussion.rest_api.utils.get_course_staff_users_list(course_id)#
Gets user ids for Staff roles for course discussions. Roles Course Instructor and Course Staff.
- lms.djangoapps.discussion.rest_api.utils.get_course_ta_users_list(course_id)#
Gets user ids for TA roles for course discussions. Roles include Community TA and Group Community TA.
- lms.djangoapps.discussion.rest_api.utils.get_moderator_users_list(course_id)#
Gets user ids for Moderator roles for course discussions. Roles include Discussion Administrator and Discussion Moderator.
- lms.djangoapps.discussion.rest_api.utils.get_topic_ids_from_topics(topics: List[Dict[str, str]]) List[str]#
This function takes a list of topics and returns a list of the topic ids.
Args: - topics (List[Dict[str, str]]): A list of topic dictionaries. Each dictionary should have an ‘id’ field.
Returns: - A list of topic ids, extracted from the input list of topics.
- lms.djangoapps.discussion.rest_api.utils.get_usernames_for_course(course_id, page_number, page_size)#
Gets usernames for all users in course.
- Parameters:
- Returns:
comma seperated usernames for the page matched_users_count (int): count of matched users in course matched_users_pages (int): pages of matched users in course
- Return type:
page_matched_users (str)
- lms.djangoapps.discussion.rest_api.utils.get_usernames_from_search_string(course_id, search_string, page_number, page_size)#
Gets usernames for all users in course that match string.
- Parameters:
- Returns:
comma seperated usernames for the page matched_users_count (int): count of matched users in course matched_users_pages (int): pages of matched users in course
- Return type:
page_matched_users (str)
- lms.djangoapps.discussion.rest_api.utils.is_discussion_cohorted(course_key_str)#
Returns if the discussion is divided by cohorts
- lms.djangoapps.discussion.rest_api.utils.is_posting_allowed(posting_restrictions: str, blackout_schedules: List)#
Check if posting is allowed based on the given posting restrictions and blackout schedules.
- lms.djangoapps.discussion.rest_api.utils.remove_empty_sequentials(data)#
Removes all objects of type “sequential” from a nested list of objects if they have no children. After removing the empty sequentials, if the parent of the sequential is now empty, it will also be removed. Parameters: data (list): A list of nested objects to check and remove empty sequentials from.
Returns: list: The modified list with empty sequentials removed.
- lms.djangoapps.discussion.rest_api.utils.set_attribute(threads, attribute, value)#
Iterates over the list of dicts and assigns the provided value to the given attribute
- Parameters:
threads – List of threads (dict objects)
attribute – the key for thread dict
value – the value to assign to the thread attribute
lms.djangoapps.discussion.rest_api.views module#
Discussion API views
- class lms.djangoapps.discussion.rest_api.views.CommentViewSet(**kwargs)#
Bases:
DeveloperErrorViewMixin,ViewSetUse Cases
Retrieve the list of comments in a thread, retrieve the list of comments from an user in a course, retrieve the list of child comments for a response comment, create a comment, or modify or delete an existing comment.
Example Requests:
GET /api/discussion/v1/comments/?username=edx&course_id=course-v1:edX+DemoX+Demo_Course
GET /api/discussion/v1/comments/?username=edx&course_id=course-v1:edX+DemoX+Demo_Course&flagged=true
GET /api/discussion/v1/comments/?thread_id=0123456789abcdef01234567
GET /api/discussion/v1/comments/2123456789abcdef01234555
POST /api/discussion/v1/comments/ {
“thread_id”: “0123456789abcdef01234567”, “raw_body”: “Body text”
}
PATCH /api/discussion/v1/comments/comment_id {“raw_body”: “Edited text”} Content Type: “application/merge-patch+json”
DELETE /api/discussion/v1/comments/comment_id
GET Comment List Parameters:
thread_id (required when username is not provided): The thread to retrieve comments for
username (required when thread_id is not provided): The user from whom to retrieve comments
course_id (required when username is provided): The course from which to retrive the user’s comments
endorsed: If specified, only retrieve the endorsed or non-endorsed comments accordingly. Required for a question thread, must be absent for a discussion thread. This parameter has no effect when fetching comments by username.
flagged: Only retrieve comments that were flagged for abuse. This requires the requester to have elevated privileges, and has no effect otherwise.
page: The (1-indexed) page to retrieve (default is 1)
page_size: The number of items per page (default is 10, max is 100)
requested_fields: (list) Indicates which additional fields to return for each thread. (supports ‘profile_image’)
GET Child Comment List Parameters:
comment_id (required): The comment to retrieve child comments for
page: The (1-indexed) page to retrieve (default is 1)
page_size: The number of items per page (default is 10, max is 100)
requested_fields: (list) Indicates which additional fields to return for each thread. (supports ‘profile_image’)
POST Parameters:
thread_id (required): The thread to post the comment in
parent_id: The parent comment of the new comment. Can be null or omitted for a comment that should be directly under the thread
raw_body: The comment’s raw body text
anonymous (optional): A boolean indicating whether the comment is
anonymous; defaults to false
anonymous_to_peers (optional): A boolean indicating whether the
comment is anonymous to peers; defaults to false
PATCH Parameters:
raw_body, anonymous and anonymous_to_peers are accepted with the same
meaning as in a POST request
edit_reason_code (optional, privileged): A string containing a reason
code for a moderator to edit the comment.
If “application/merge-patch+json” is not the specified content type, a 415 error is returned.
GET Response Values:
- results: The list of comments; each item in the list has the same
fields as the POST response below
next: The URL of the next page (or null if first page)
previous: The URL of the previous page (or null if last page)
POST/PATCH Response Values:
id: The id of the comment
thread_id: The id of the comment’s thread
parent_id: The id of the comment’s parent
author: The username of the comment’s author, or None if the comment is anonymous
author_label: A label indicating whether the author has a special role in the course, either “Staff” for moderators and administrators or “Community TA” for community TAs
created_at: The ISO 8601 timestamp for the creation of the comment
- updated_at: The ISO 8601 timestamp for the last modification of
the comment, which may not have been an update of the body
raw_body: The comment’s raw body text without any rendering applied
- endorsed: Boolean indicating whether the comment has been endorsed
(by a privileged user or, for a question thread, the thread author)
endorsed_by: The username of the endorsing user, if available
- endorsed_by_label: A label indicating whether the endorsing user
has a special role in the course (see author_label)
- endorsed_at: The ISO 8601 timestamp for the endorsement, if
available
abuse_flagged: Boolean indicating whether the requesting user has flagged the comment for abuse
- abuse_flagged_any_user: Boolean indicating whether any user has
flagged the comment for abuse. Returns null if requesting user is not a moderator.
voted: Boolean indicating whether the requesting user has voted for the comment
vote_count: The number of votes for the comment
children: The list of child comments (with the same format)
- editable_fields: The fields that the requesting user is allowed to
modify with a PATCH request
anonymous: A boolean indicating whether the comment is anonymous
anonymous_to_peers: A boolean indicating whether the comment is
anonymous to peers
DELETE Response Value
No content is returned for a DELETE request
- 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'>)#
- basename = None#
- create(request)#
Implements the POST method for the list endpoint as described in the class docstring.
- description = None#
- destroy(request, comment_id)#
Implements the DELETE method for the instance endpoint as described in the class docstring
- detail = None#
- list(request)#
Implements the GET method for the list endpoint as described in the class docstring.
This endpoint implements two distinct usage contexts.
When username is provided, the course_id parameter is required, and thread_id is ignored. The behavior is to retrieve all of the user’s non-anonymous comments from the specified course, outside of the context of a forum thread. In this context, endorsement information is unavailable.
When username is not provided, thread_id is required, and course_id is ignored, since the thread already belongs to a course. In this context, all information relevant to usage in the discussions forum is available.
- list_by_thread(request)#
Handles the case of fetching a thread’s comments.
- list_by_user(request)#
Handles the case of fetching an user’s comments.
- lookup_field = 'comment_id'#
- name = None#
- parser_classes = (<class 'rest_framework.parsers.JSONParser'>, <class 'openedx.core.lib.api.parsers.MergePatchParser'>)#
- partial_update(request, comment_id)#
Implements the PATCH method for the instance endpoint as described in the class docstring.
- permission_classes = (<class 'rest_framework.permissions.IsAuthenticated'>,)#
- retrieve(request, comment_id=None)#
Implements the GET method for comments against response ID
- suffix = None#
- class lms.djangoapps.discussion.rest_api.views.CourseActivityStatsView(**kwargs)#
Bases:
DeveloperErrorViewMixin,APIViewUse Cases
Fetch statistics about a user’s activity in a course.
Example Requests:
GET /api/discussion/v1/courses/course-v1:ExampleX+Subject101+2015/activity_stats?order_by=activity
Response Values:
- “pagination”: {
“count”: 3, “next”: null, “num_pages”: 1, “previous”: null
}, “results”: [
- {
“active_flags”: 3, “inactive_flags”: 0, “replies”: 13, “responses”: 21, “threads”: 32, “username”: “edx”
}, {
“active_flags”: 1, “inactive_flags”: 0, “replies”: 6, “responses”: 8, “threads”: 13, “username”: “honor”
]
}#
- 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)#
Implements the GET method as described in the class docstring.
- permission_classes = (<class 'rest_framework.permissions.IsAuthenticated'>,)#
- class lms.djangoapps.discussion.rest_api.views.CourseDiscussionRolesAPIView(**kwargs)#
Bases:
DeveloperErrorViewMixin,APIViewUse Cases Retrieve all the members of a given forum discussion role or update the membership of a role.
Example Requests
GET /api/discussion/v1/courses/{course_id}/roles/{rolename}
POST /api/discussion/v1/courses/{course_id}/roles/{rolename} {“user_id”: “<username or email>”, “action”: “<allow or revoke>”}
GET List Members of a Role Parameters:
course_id (required): The course to which the role belongs to.
rolename (required): The name of the forum discussion role, the members of which have to be listed. Currently supported values are ‘Moderator’, ‘Group Moderator’, ‘Community TA’. If the value has a space it has to be URL encoded.
POST Update the membership of a Role Parameters:
course_id (required): The course to which the role belongs to.
rolename (required): The name of the forum discussion role, the members of which have to be listed. Currently supported values are ‘Moderator’, ‘Group Moderator’, ‘Community TA’. If the value has a space it has to be URL encoded.
The body can use either ‘application/x-www-form-urlencoded’ or ‘application/json’ content type.
user_id (required): The username or email address of the user whose membership has to be updated.
action (required): Either ‘allow’ or ‘revoke’, depending on the action to be performed on the membership.
GET and POST Response Values:
A HTTP 404 Not Found response status code is returned when the requested course is invalid.
A HTTP 400 Bad Request response status code is returned when the request is invalid.
A HTTP 200 OK response status denote is returned to denote success.
course_id: The course to which the role belongs to.
results: A list of the members belonging to the specified role.
username: Username of the user.
email: Email address of the user.
first_name: First name of the user.
last_name: Last name of the user.
group_name: Name of the group the user belongs to.
division_scheme: The division scheme used by the course.
- 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_id, rolename)#
Implement a handler for the GET method.
- permission_classes = (<class 'rest_framework.permissions.IsAuthenticated'>, <class 'rest_framework.permissions.IsAdminUser'>)#
- post(request, course_id, rolename)#
Implement a handler for the POST method.
- class lms.djangoapps.discussion.rest_api.views.CourseDiscussionSettingsAPIView(**kwargs)#
Bases:
DeveloperErrorViewMixin,APIViewUse Cases Retrieve all the discussion settings for a course or update one or more of them.
Example Requests
GET /api/discussion/v1/courses/{course_id}/settings
PATCH /api/discussion/v1/courses/{course_id}/settings {“always_divide_inline_discussions”: true}
GET Discussion Settings Parameters:
course_id (required): The course to retrieve the discussion settings for.
PATCH Discussion Settings Parameters:
course_id (required): The course to retrieve the discussion settings for.
The body should have the ‘application/merge-patch+json’ content type.
divided_inline_discussions: A list of IDs of the topics to be marked as divided inline discussions.
divided_course_wide_discussions: A list of IDs of the topics to be marked as divided course-wide discussions.
always_divide_inline_discussions: A boolean indicating whether inline discussions should always be divided or not.
division_scheme: A string corresponding to the division scheme to be used from the list of available division schemes.
GET and PATCH Discussion Settings Parameters Response Values:
A HTTP 404 Not Found response status code is returned when the requested course is invalid.
A HTTP 400 Bad Request response status code is returned when the request is invalid.
A HTTP 200 OK response status denote is returned to denote success.
id: The discussion settings id.
divided_inline_discussions: A list of divided inline discussions.
divided_course_wide_discussions: A list of divided course-wide discussions.
division_scheme: The division scheme used for the course discussions.
available_division_schemes: A list of available division schemes for the course.
- 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_id)#
Implement a handler for the GET method.
- parser_classes = (<class 'rest_framework.parsers.JSONParser'>, <class 'openedx.core.lib.api.parsers.MergePatchParser'>)#
- patch(request, course_id)#
Implement a handler for the PATCH method.
- permission_classes = (<class 'rest_framework.permissions.IsAuthenticated'>, <class 'lms.djangoapps.discussion.rest_api.permissions.IsStaffOrAdmin'>)#
- class lms.djangoapps.discussion.rest_api.views.CourseTopicsView(**kwargs)#
Bases:
DeveloperErrorViewMixin,APIViewUse Cases
Retrieve the topic listing for a course. Only topics accessible to the authenticated user are included.
Example Requests:
- GET /api/discussion/v1/course_topics/course-v1:ExampleX+Subject101+2015
?topic_id={topic_id_1, topid_id_2}
- Response Values:
- courseware_topics: The list of topic trees for courseware-linked
topics. Each item in the list includes:
id: The id of the discussion topic (null for a topic that only has children but cannot contain threads itself).
name: The display name of the topic.
children: A list of child subtrees of the same format.
- non_courseware_topics: The list of topic trees that are not linked to
courseware. Items are of the same format as in courseware_topics.
- 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_id)#
Implements the GET method as described in the class docstring.
- permission_classes = (<class 'rest_framework.permissions.IsAuthenticated'>,)#
- class lms.djangoapps.discussion.rest_api.views.CourseTopicsViewV2(**kwargs)#
Bases:
DeveloperErrorViewMixin,APIViewView for listing course topics.
For more information visit the [API Documentation](/api-docs/?filter=discussion#/discussion/discussion_v2_course_topics_read)
- 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_id)#
Use Cases
Retrieve the topic listing for a course.
Example Requests:
- GET /api/discussion/v2/course_topics/course-v1:ExampleX+Subject101+2015
?topic_id={topic_id_1, topid_id_2}&order_by=course_structure
- permission_classes = (<class 'rest_framework.permissions.IsAuthenticated'>,)#
- class lms.djangoapps.discussion.rest_api.views.CourseTopicsViewV3(**kwargs)#
Bases:
DeveloperErrorViewMixin,APIViewView for listing course topics v3.
** Response Example **: [
- {
“id”: “non-courseware-discussion-id”, “usage_key”: None, “name”: “Non Courseware Topic”, “thread_counts”: {“discussion”: 0, “question”: 0}, “enabled_in_context”: true, “courseware”: false
}, {
“id”: “id”, “block_id”: “block_id”, “lms_web_url”: “”, “legacy_web_url”: “”, “student_view_url”: “”, “type”: “chapter”, “display_name”: “First section”, “children”: [
“id”: “id”, “block_id”: “block_id”, “lms_web_url”: “”, “legacy_web_url”: “”, “student_view_url”: “”, “type”: “sequential”, “display_name”: “First Sub-Section”, “children”: [
“id”: “id”, “usage_key”: “”, “name”: “First Unit?”, “thread_counts”: { “discussion”: 0, “question”: 0 }, “enabled_in_context”: true
]
], “courseware”: true,
}
]
- 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_id)#
Use Cases
Retrieve the topic listing for a course.
Example Requests:
GET /api/discussion/v3/course_topics/course-v1:ExampleX+Subject101+2015
- permission_classes = (<class 'rest_framework.permissions.IsAuthenticated'>,)#
- class lms.djangoapps.discussion.rest_api.views.CourseView(**kwargs)#
Bases:
DeveloperErrorViewMixin,APIViewGeneral discussion metadata API.
- 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_id)#
Retrieve general discussion metadata for a course.
Example Requests:
GET /api/discussion/v1/courses/course-v1:ExampleX+Subject101+2015
- permission_classes = (<class 'rest_framework.permissions.IsAuthenticated'>,)#
- class lms.djangoapps.discussion.rest_api.views.LearnerThreadView(**kwargs)#
Bases:
APIViewUse Cases
Fetch user’s active threads
Example Requests:
GET /api/discussion/v1/courses/course-v1:ExampleX+Subject101+2015/learner/?username=edx&page=1&page_size=10
GET Thread List Parameters:
username: (Required) Username of the user whose active threads are required
page: The (1-indexed) page to retrieve (default is 1)
page_size: The number of items per page (default is 10)
count_flagged: If True, return the count of flagged comments for each thread.
(can only be used by moderators or above)
thread_type: The type of thread to filter None, “discussion” or “question”.
order_by: Sort order for threads “last_activity_at”, “comment_count” or
“vote_count”.
status: Filter for threads “flagged”, “unanswered”, “unread”.
group_id: Filter threads w.r.t cohorts (Cohort ID).
- authentication_classes = (<class 'edx_rest_framework_extensions.auth.jwt.authentication.JwtAuthentication'>, <class 'openedx.core.lib.api.authentication.BearerAuthentication'>, <class 'rest_framework.authentication.SessionAuthentication'>)#
- get(request, course_id=None)#
Implements the GET method as described in the class docstring.
- permission_classes = (<class 'rest_framework.permissions.IsAuthenticated'>, <class 'lms.djangoapps.discussion.rest_api.permissions.IsStaffOrCourseTeamOrEnrolled'>)#
- class lms.djangoapps.discussion.rest_api.views.ReplaceUsernamesView(**kwargs)#
Bases:
APIViewWARNING: This API is only meant to be used as part of a larger job that updates usernames across all services. DO NOT run this alone or users will not match across the system and things will be broken.
API will recieve a list of current usernames and their new username.
- POST /api/discussion/v1/accounts/replace_usernames/
- {
- “username_mappings”: [
{“current_username_1”: “desired_username_1”}, {“current_username_2”: “desired_username_2”}
]
}
- authentication_classes = (<class 'edx_rest_framework_extensions.auth.jwt.authentication.JwtAuthentication'>,)#
- permission_classes = (<class 'rest_framework.permissions.IsAuthenticated'>, <class 'openedx.core.djangoapps.user_api.accounts.permissions.CanReplaceUsername'>)#
- post(request)#
Implements the username replacement endpoint
- class lms.djangoapps.discussion.rest_api.views.RetireUserView(**kwargs)#
Bases:
APIViewUse Cases
A superuser or the user with the settings.RETIREMENT_SERVICE_WORKER_USERNAME can “retire” the user’s data from the comments service, which will remove personal information and blank all posts / comments the user has made.
- Example Requests:
POST /api/discussion/v1/retire_user/ {
“username”: “an_original_user_name”
}
- Example Response:
Empty string
- authentication_classes = (<class 'edx_rest_framework_extensions.auth.jwt.authentication.JwtAuthentication'>,)#
- permission_classes = (<class 'rest_framework.permissions.IsAuthenticated'>, <class 'openedx.core.djangoapps.user_api.accounts.permissions.CanRetireUser'>)#
- post(request)#
Implements the retirement endpoint.
- class lms.djangoapps.discussion.rest_api.views.ThreadViewSet(**kwargs)#
Bases:
DeveloperErrorViewMixin,ViewSetUse Cases
Retrieve the list of threads for a course, retrieve thread details, post a new thread, or modify or delete an existing thread.
Example Requests:
GET /api/discussion/v1/threads/?course_id=ExampleX/Demo/2015
GET /api/discussion/v1/threads/{thread_id}
POST /api/discussion/v1/threads {
“course_id”: “foo/bar/baz”, “topic_id”: “quux”, “type”: “discussion”, “title”: “Title text”, “raw_body”: “Body text”
}
PATCH /api/discussion/v1/threads/thread_id {“raw_body”: “Edited text”} Content Type: “application/merge-patch+json”
DELETE /api/discussion/v1/threads/thread_id
GET Thread List Parameters:
course_id (required): The course to retrieve threads for
page: The (1-indexed) page to retrieve (default is 1)
page_size: The number of items per page (default is 10, max is 100)
- topic_id: The id of the topic to retrieve the threads. There can be
multiple topic_id queries to retrieve threads from multiple topics at once.
- author: The username of an author. If provided, only threads by this
author will be returned.
- thread_type: Can be ‘discussion’ or ‘question’, only return threads of
the selected thread type.
flagged: If True, only return threads that have been flagged (reported)
count_flagged: If True, return the count of flagged comments for each thread. (can only be used by moderators or above)
- text_search: A search string to match. Any thread whose content
(including the bodies of comments in the thread) matches the search string will be returned.
- order_by: Must be “last_activity_at”, “comment_count”, or
“vote_count”. The key to sort the threads by. The default is “last_activity_at”.
- order_direction: Must be “desc”. The direction in which to sort the
threads by. The default and only value is “desc”. This will be removed in a future major version.
- following: If true, retrieve only threads the requesting user is
following
- view: “unread” for threads the requesting user has not read, or
“unanswered” for question threads with no marked answer. Only one can be selected, or unresponded for discussion type posts with no response
requested_fields: (list) Indicates which additional fields to return for each thread. (supports ‘profile_image’)
The topic_id, text_search, and following parameters are mutually exclusive (i.e. only one may be specified in a request)
GET Thread Parameters:
thread_id (required): The id of the thread
requested_fields (optional parameter): (list) Indicates which additional
fields to return for each thread. (supports ‘profile_image’)
POST Parameters:
course_id (required): The course to create the thread in
topic_id (required): The topic to create the thread in
type (required): The thread’s type (either “question” or “discussion”)
title (required): The thread’s title
raw_body (required): The thread’s raw body text
- following (optional): A boolean indicating whether the user should
follow the thread upon its creation; defaults to false
anonymous (optional): A boolean indicating whether the post is
anonymous; defaults to false
anonymous_to_peers (optional): A boolean indicating whether the post
is anonymous to peers; defaults to false
PATCH Parameters:
abuse_flagged (optional): A boolean to mark thread as abusive
voted (optional): A boolean to vote for thread
read (optional): A boolean to mark thread as read
closed (optional, privileged): A boolean to mark thread as closed.
edit_reason_code (optional, privileged): A string containing a reason
code for editing the thread’s body.
close_reason_code (optional, privileged): A string containing a reason
code for closing the thread.
topic_id, type, title, raw_body, anonymous, and anonymous_to_peers
are accepted with the same meaning as in a POST request
If “application/merge-patch+json” is not the specified content type, a 415 error is returned.
GET Thread List Response Values:
- results: The list of threads; each item in the list has the same
fields as the POST/PATCH response below
next: The URL of the next page (or null if first page)
previous: The URL of the previous page (or null if last page)
- text_search_rewrite: The search string to which the text_search
parameter was rewritten in order to match threads (e.g. for spelling correction)
GET Thread Details Response Values:
Same response fields as the POST/PATCH response below
POST/PATCH response values:
id: The id of the thread
course_id: The id of the thread’s course
topic_id: The id of the thread’s topic
created_at: The ISO 8601 timestamp for the creation of the thread
- updated_at: The ISO 8601 timestamp for the last modification of
the thread, which may not have been an update of the title/body
type: The thread’s type (either “question” or “discussion”)
title: The thread’s title
raw_body: The thread’s raw body text without any rendering applied
pinned: Boolean indicating whether the thread has been pinned
closed: Boolean indicating whether the thread has been closed
comment_count: The number of comments within the thread
- unread_comment_count: The number of comments within the thread
that were created or updated since the last time the user read the thread
- editable_fields: The fields that the requesting user is allowed to
modify with a PATCH request
read: Boolean indicating whether the user has read this thread
has_endorsed: Boolean indicating whether this thread has been answered
response_count: The number of direct responses for a thread
- abuse_flagged_count: The number of flags(reports) on and within the
thread. Returns null if requesting user is not a moderator
anonymous: A boolean indicating whether the post is anonymous
anonymous_to_peers: A boolean indicating whether the post is
anonymous to peers
**DELETE response values:
No content is returned for a DELETE request
- 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'>)#
- basename = None#
- create(request)#
Implements the POST method for the list endpoint as described in the class docstring.
- description = None#
- destroy(request, thread_id)#
Implements the DELETE method for the instance endpoint as described in the class docstring
- detail = None#
- list(request)#
Implements the GET method for the list endpoint as described in the class docstring.
- lookup_field = 'thread_id'#
- name = None#
- parser_classes = (<class 'rest_framework.parsers.JSONParser'>, <class 'openedx.core.lib.api.parsers.MergePatchParser'>)#
- partial_update(request, thread_id)#
Implements the PATCH method for the instance endpoint as described in the class docstring.
- permission_classes = (<class 'rest_framework.permissions.IsAuthenticated'>,)#
- retrieve(request, thread_id=None)#
Implements the GET method for thread ID
- suffix = None#
- class lms.djangoapps.discussion.rest_api.views.UploadFileView(**kwargs)#
Bases:
DeveloperErrorViewMixin,APIViewUse Cases
Upload a file to be attached to a thread or comment.
URL Parameters
- course_id:
The ID of the course where this thread or comment belongs.
POST Upload File Parameters
- thread_key:
If the upload belongs to a comment, refer to the parent thread_id, otherwise it should be “root”.
- Example Requests:
POST /api/discussion/v1/courses/{course_id}/upload/ Content-Type: multipart/form-data; boundary=–Boundary
—-Boundary Content-Disposition: form-data; name=”thread_key”
<thread_key> —-Boundary Content-Disposition: form-data; name=”uploaded_file”; filename=”<filename>.<ext>” Content-Type: <mimetype>
<file_content> —-Boundary–
Response Values
location: The URL to access the uploaded file.
- authentication_classes = (<class 'edx_rest_framework_extensions.auth.jwt.authentication.JwtAuthentication'>, <class 'openedx.core.lib.api.authentication.BearerAuthentication'>, <class 'rest_framework.authentication.SessionAuthentication'>)#
- permission_classes = (<class 'rest_framework.permissions.IsAuthenticated'>, <class 'lms.djangoapps.discussion.rest_api.permissions.IsStaffOrCourseTeamOrEnrolled'>)#
- post(request, course_id)#
Handles a file upload.