Skip to content

Commit

Permalink
feat: grading rest api for authoring api (openedx#34854)
Browse files Browse the repository at this point in the history
* feat: grading rest api for authoring api

* fix: doc string api path
  • Loading branch information
KristinAoki committed May 29, 2024
1 parent b264988 commit 38320f8
Show file tree
Hide file tree
Showing 5 changed files with 117 additions and 2 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
"""
from .advanced_settings import AdvancedSettingsFieldSerializer, CourseAdvancedSettingsSerializer
from .assets import AssetSerializer
from .authoring_grading import CourseGradingModelSerializer
from .tabs import CourseTabSerializer, CourseTabUpdateSerializer, TabIDLocatorSerializer
from .transcripts import TranscriptSerializer, YoutubeTranscriptCheckSerializer, YoutubeTranscriptUploadSerializer
from .xblock import XblockSerializer
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
"""
API Serializers for course grading
"""

from rest_framework import serializers


class GradersSerializer(serializers.Serializer):
""" Serializer for graders """
type = serializers.CharField()
min_count = serializers.IntegerField()
drop_count = serializers.IntegerField()
short_label = serializers.CharField(required=False, allow_null=True, allow_blank=True)
weight = serializers.IntegerField()
id = serializers.IntegerField()


class CourseGradingModelSerializer(serializers.Serializer):
""" Serializer for course grading model data """
graders = GradersSerializer(many=True, allow_null=True, allow_empty=True)
9 changes: 7 additions & 2 deletions cms/djangoapps/contentstore/rest_api/v0/urls.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@

from .views import (
AdvancedCourseSettingsView,
AuthoringGradingView,
CourseTabSettingsView,
CourseTabListView,
CourseTabReorderView,
Expand Down Expand Up @@ -46,8 +47,8 @@
),

# Authoring API
re_path(
r'^heartbeat$', APIHeartBeatView.as_view(), name='heartbeat'
path(
'heartbeat', APIHeartBeatView.as_view(), name='heartbeat'
),
re_path(
fr'^file_assets/{settings.COURSE_ID_PATTERN}$',
Expand All @@ -61,6 +62,10 @@
fr'^videos/encodings/{settings.COURSE_ID_PATTERN}$',
authoring_videos.VideoEncodingsDownloadView.as_view(), name='cms_api_videos_encodings'
),
re_path(
fr'grading/{settings.COURSE_ID_PATTERN}',
AuthoringGradingView.as_view(), name='cms_api_update_grading'
),
path(
'videos/features',
authoring_videos.VideoFeaturesView.as_view(), name='cms_api_videos_features'
Expand Down
1 change: 1 addition & 0 deletions cms/djangoapps/contentstore/rest_api/v0/views/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
Views for v0 contentstore API.
"""
from .advanced_settings import AdvancedCourseSettingsView
from .authoring_grading import AuthoringGradingView
from .tabs import CourseTabSettingsView, CourseTabListView, CourseTabReorderView
from .transcripts import TranscriptView, YoutubeTranscriptCheckView, YoutubeTranscriptUploadView
from .api_heartbeat import APIHeartBeatView
88 changes: 88 additions & 0 deletions cms/djangoapps/contentstore/rest_api/v0/views/authoring_grading.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
""" API Views for course advanced settings """

import edx_api_doc_tools as apidocs
from opaque_keys.edx.keys import CourseKey
from rest_framework.request import Request
from rest_framework.response import Response
from rest_framework.views import APIView

from cms.djangoapps.models.settings.course_grading import CourseGradingModel
from common.djangoapps.student.auth import has_studio_read_access
from openedx.core.djangoapps.credit.tasks import update_credit_course_requirements
from openedx.core.lib.api.view_utils import DeveloperErrorViewMixin, verify_course_exists, view_auth_classes
from ..serializers import CourseGradingModelSerializer


@view_auth_classes(is_authenticated=True)
class AuthoringGradingView(DeveloperErrorViewMixin, APIView):
"""
View for getting and setting the advanced settings for a course.
"""
@apidocs.schema(
body=CourseGradingModelSerializer,
parameters=[
apidocs.string_parameter("course_id", apidocs.ParameterLocation.PATH, description="Course ID"),
],
responses={
200: CourseGradingModelSerializer,
401: "The requester is not authenticated.",
403: "The requester cannot access the specified course.",
404: "The requested course does not exist.",
},
)
@verify_course_exists()
def post(self, request: Request, course_id: str):
"""
Update a course's grading.
**Example Request**
POST /api/contentstore/v0/course_grading/{course_id}
**POST Parameters**
The data sent for a post request should follow next object.
Here is an example request data that updates the ``course_grading``
```json
{
"graders": [
{
"type": "Homework",
"min_count": 1,
"drop_count": 0,
"short_label": "",
"weight": 100,
"id": 0
}
],
"grade_cutoffs": {
"A": 0.75,
"B": 0.63,
"C": 0.57,
"D": 0.5
},
"grace_period": {
"hours": 12,
"minutes": 0
},
"minimum_grade_credit": 0.7,
"is_credit_course": true
}
```
**Response Values**
If the request is successful, an HTTP 200 "OK" response is returned,
"""
course_key = CourseKey.from_string(course_id)

if not has_studio_read_access(request.user, course_key):
self.permission_denied(request)

if 'minimum_grade_credit' in request.data:
update_credit_course_requirements.delay(str(course_key))

updated_data = CourseGradingModel.update_from_json(course_key, request.data, request.user)
serializer = CourseGradingModelSerializer(updated_data)
return Response(serializer.data)

0 comments on commit 38320f8

Please sign in to comment.