{"action":"created","comment":{"url":"https://api.github.com/repos/edx/edx-platform/pulls/comments/183775783","pull_request_review_id":114561933,"id":183775783,"diff_hunk":"@@ -0,0 +1,192 @@\n+\"\"\" API v0 views. \"\"\"\n+import logging\n+\n+from django.contrib.auth import get_user_model\n+from opaque_keys import InvalidKeyError\n+from opaque_keys.edx.keys import CourseKey\n+from rest_framework import status\n+from rest_framework.exceptions import AuthenticationFailed\n+from rest_framework.generics import GenericAPIView\n+from rest_framework.response import Response\n+\n+from enrollment import data as enrollment_data\n+from lms.djangoapps.grades.course_grade_factory import CourseGradeFactory\n+from openedx.core.djangoapps.content.course_overviews.models import CourseOverview\n+from openedx.core.lib.api.permissions import IsUserInUrlOrStaff\n+from openedx.core.lib.api.view_utils import DeveloperErrorViewMixin, view_auth_classes\n+\n+log = logging.getLogger(__name__)\n+USER_MODEL = get_user_model()\n+\n+\n+@view_auth_classes()\n+class GradeViewMixin(DeveloperErrorViewMixin):\n+    \"\"\"\n+    Mixin class for Grades related views.\n+    \"\"\"\n+    def _get_course_key(self, course_id):\n+        \"\"\"\n+        Returns the course key for the given course_id string.\n+        Validates that the course actually exists in the CourseOverview\n+        \"\"\"\n+        try:\n+            course_key = CourseKey.from_string(course_id)\n+        except InvalidKeyError:\n+            return self.make_error_response(\n+                status_code=status.HTTP_404_NOT_FOUND,\n+                developer_message='The provided course key cannot be parsed.',\n+                error_code='invalid_course_key'\n+            )\n+\n+        if not CourseOverview.get_from_id_if_exists(course_key):\n+            return self.make_error_response(\n+                status_code=status.HTTP_404_NOT_FOUND,\n+                developer_message=\"Requested grade for unknown course {course}\".format(course=course_id),\n+                error_code='course_does_not_exist'\n+            )\n+\n+        return course_key\n+\n+    def _get_effective_user(self, request, course_key):\n+        \"\"\"\n+        Returns the user object corresponding to the request's 'username' parameter,\n+        or the current request.user if no 'username' was provided.\n+        \"\"\"\n+        if 'username' in request.GET:\n+            username = request.GET.get('username')\n+        else:\n+            username = request.user.username\n+\n+        try:\n+            user = USER_MODEL.objects.get(username=username)\n+        except USER_MODEL.DoesNotExist:\n+            return self.make_error_response(\n+                status_code=status.HTTP_404_NOT_FOUND,\n+                developer_message='The user matching the requested username does not exist.',\n+                error_code='user_does_not_exist'\n+            )\n+\n+        if not enrollment_data.get_course_enrollment(username, str(course_key)):\n+            return self.make_error_response(\n+                status_code=status.HTTP_404_NOT_FOUND,\n+                developer_message='The user matching the requested username is not enrolled in this course',\n+                error_code='user_not_enrolled'\n+            )\n+\n+        return user\n+\n+    def _make_grade_response(self, user, course_key, course_grade):\n+        \"\"\"\n+        Serialize a single grade to dict to use in Responses\n+        \"\"\"\n+        return {\n+            'username': user.username,\n+            'email': user.email,\n+            'course_id': str(course_key),\n+            'passed': course_grade.passed,\n+            'percent': course_grade.percent,\n+            'letter_grade': course_grade.letter_grade,\n+        }\n+\n+    def perform_authentication(self, request):\n+        \"\"\"\n+        Ensures that the user is authenticated (e.g. not an AnonymousUser), unless DEBUG mode is enabled.\n+        \"\"\"\n+        super(GradeViewMixin, self).perform_authentication(request)\n+        if request.user.is_anonymous():\n+            raise AuthenticationFailed\n+\n+\n+class CourseGradesView(GradeViewMixin, GenericAPIView):\n+    \"\"\"\n+    **Use Case**\n+        * Get course grades if all user who are enrolled in a course.","path":"lms/djangoapps/grades/api/v1/views.py","position":103,"original_position":103,"commit_id":"85f8c1da838c2b2ce94d180b9b71cb3e7ee3d165","original_commit_id":"85f8c1da838c2b2ce94d180b9b71cb3e7ee3d165","user":{"login":"nasthagiri","id":6772826,"avatar_url":"https://avatars1.githubusercontent.com/u/6772826?v=4","gravatar_id":"","url":"https://api.github.com/users/nasthagiri","html_url":"https://github.com/nasthagiri","followers_url":"https://api.github.com/users/nasthagiri/followers","following_url":"https://api.github.com/users/nasthagiri/following{/other_user}","gists_url":"https://api.github.com/users/nasthagiri/gists{/gist_id}","starred_url":"https://api.github.com/users/nasthagiri/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/nasthagiri/subscriptions","organizations_url":"https://api.github.com/users/nasthagiri/orgs","repos_url":"https://api.github.com/users/nasthagiri/repos","events_url":"https://api.github.com/users/nasthagiri/events{/privacy}","received_events_url":"https://api.github.com/users/nasthagiri/received_events","type":"User","site_admin":false},"body":"if all user -> of all users","created_at":"2018-04-24T15:24:38Z","updated_at":"2018-04-24T15:37:20Z","html_url":"https://github.com/edx/edx-platform/pull/17602#discussion_r183775783","pull_request_url":"https://api.github.com/repos/edx/edx-platform/pulls/17602","author_association":"MEMBER","_links":{"self":{"href":"https://api.github.com/repos/edx/edx-platform/pulls/comments/183775783"},"html":{"href":"https://github.com/edx/edx-platform/pull/17602#discussion_r183775783"},"pull_request":{"href":"https://api.github.com/repos/edx/edx-platform/pulls/17602"}}},"pull_request":{"url":"https://api.github.com/repos/edx/edx-platform/pulls/17602","id":172375180,"html_url":"https://github.com/edx/edx-platform/pull/17602","diff_url":"https://github.com/edx/edx-platform/pull/17602.diff","patch_url":"https://github.com/edx/edx-platform/pull/17602.patch","issue_url":"https://api.github.com/repos/edx/edx-platform/issues/17602","number":17602,"state":"open","locked":false,"title":"Bulk Grades API (v1 grades api w/courses endpoint)","user":{"login":"kabirkhan","id":13891834,"avatar_url":"https://avatars2.githubusercontent.com/u/13891834?v=4","gravatar_id":"","url":"https://api.github.com/users/kabirkhan","html_url":"https://github.com/kabirkhan","followers_url":"https://api.github.com/users/kabirkhan/followers","following_url":"https://api.github.com/users/kabirkhan/following{/other_user}","gists_url":"https://api.github.com/users/kabirkhan/gists{/gist_id}","starred_url":"https://api.github.com/users/kabirkhan/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/kabirkhan/subscriptions","organizations_url":"https://api.github.com/users/kabirkhan/orgs","repos_url":"https://api.github.com/users/kabirkhan/repos","events_url":"https://api.github.com/users/kabirkhan/events{/privacy}","received_events_url":"https://api.github.com/users/kabirkhan/received_events","type":"User","site_admin":false},"body":"### Provides functionality for a course staff member to request grades for all students enrolled in a course, not just a single user. \r\n\r\nUses a 'v1' naming convention:\r\n\r\nPossible routes are:\r\n**anyone can get their own grade still (same as v0)**\r\n  GET /api/grades/v1/course_grade/{course_id}/users/?username={username}  \r\n\r\n**course staff member gets grades for specific student (same as v0)**\r\n  GET /api/grades/v1/course_grade/{course_id}/users/?username={username}  \r\n\r\n**course staff member gets grades for all students enrolled in course (new for v1)**\r\n  GET /api/grades/v1/course_grade/{course_id}/all_users/ ","created_at":"2018-03-01T22:42:51Z","updated_at":"2018-04-24T15:37:20Z","closed_at":null,"merged_at":null,"merge_commit_sha":"122ef0c76861bffa8f209bf318ebdb8d906b8de9","assignee":null,"assignees":[],"requested_reviewers":[],"requested_teams":[],"labels":[{"id":128413102,"url":"https://api.github.com/repos/edx/edx-platform/labels/awaiting%20prioritization","name":"awaiting prioritization","color":"fad8c7","default":false},{"id":78051711,"url":"https://api.github.com/repos/edx/edx-platform/labels/open-source-contribution","name":"open-source-contribution","color":"bfe5bf","default":false}],"milestone":null,"commits_url":"https://api.github.com/repos/edx/edx-platform/pulls/17602/commits","review_comments_url":"https://api.github.com/repos/edx/edx-platform/pulls/17602/comments","review_comment_url":"https://api.github.com/repos/edx/edx-platform/pulls/comments{/number}","comments_url":"https://api.github.com/repos/edx/edx-platform/issues/17602/comments","statuses_url":"https://api.github.com/repos/edx/edx-platform/statuses/85f8c1da838c2b2ce94d180b9b71cb3e7ee3d165","head":{"label":"Microsoft:edx_master","ref":"edx_master","sha":"85f8c1da838c2b2ce94d180b9b71cb3e7ee3d165","user":{"login":"Microsoft","id":6154722,"avatar_url":"https://avatars2.githubusercontent.com/u/6154722?v=4","gravatar_id":"","url":"https://api.github.com/users/Microsoft","html_url":"https://github.com/Microsoft","followers_url":"https://api.github.com/users/Microsoft/followers","following_url":"https://api.github.com/users/Microsoft/following{/other_user}","gists_url":"https://api.github.com/users/Microsoft/gists{/gist_id}","starred_url":"https://api.github.com/users/Microsoft/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/Microsoft/subscriptions","organizations_url":"https://api.github.com/users/Microsoft/orgs","repos_url":"https://api.github.com/users/Microsoft/repos","events_url":"https://api.github.com/users/Microsoft/events{/privacy}","received_events_url":"https://api.github.com/users/Microsoft/received_events","type":"Organization","site_admin":false},"repo":{"id":65483935,"name":"edx-platform","full_name":"Microsoft/edx-platform","owner":{"login":"Microsoft","id":6154722,"avatar_url":"https://avatars2.githubusercontent.com/u/6154722?v=4","gravatar_id":"","url":"https://api.github.com/users/Microsoft","html_url":"https://github.com/Microsoft","followers_url":"https://api.github.com/users/Microsoft/followers","following_url":"https://api.github.com/users/Microsoft/following{/other_user}","gists_url":"https://api.github.com/users/Microsoft/gists{/gist_id}","starred_url":"https://api.github.com/users/Microsoft/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/Microsoft/subscriptions","organizations_url":"https://api.github.com/users/Microsoft/orgs","repos_url":"https://api.github.com/users/Microsoft/repos","events_url":"https://api.github.com/users/Microsoft/events{/privacy}","received_events_url":"https://api.github.com/users/Microsoft/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/Microsoft/edx-platform","description":"The Open edX platform, the software that powers edX!","fork":true,"url":"https://api.github.com/repos/Microsoft/edx-platform","forks_url":"https://api.github.com/repos/Microsoft/edx-platform/forks","keys_url":"https://api.github.com/repos/Microsoft/edx-platform/keys{/key_id}","collaborators_url":"https://api.github.com/repos/Microsoft/edx-platform/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/Microsoft/edx-platform/teams","hooks_url":"https://api.github.com/repos/Microsoft/edx-platform/hooks","issue_events_url":"https://api.github.com/repos/Microsoft/edx-platform/issues/events{/number}","events_url":"https://api.github.com/repos/Microsoft/edx-platform/events","assignees_url":"https://api.github.com/repos/Microsoft/edx-platform/assignees{/user}","branches_url":"https://api.github.com/repos/Microsoft/edx-platform/branches{/branch}","tags_url":"https://api.github.com/repos/Microsoft/edx-platform/tags","blobs_url":"https://api.github.com/repos/Microsoft/edx-platform/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/Microsoft/edx-platform/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/Microsoft/edx-platform/git/refs{/sha}","trees_url":"https://api.github.com/repos/Microsoft/edx-platform/git/trees{/sha}","statuses_url":"https://api.github.com/repos/Microsoft/edx-platform/statuses/{sha}","languages_url":"https://api.github.com/repos/Microsoft/edx-platform/languages","stargazers_url":"https://api.github.com/repos/Microsoft/edx-platform/stargazers","contributors_url":"https://api.github.com/repos/Microsoft/edx-platform/contributors","subscribers_url":"https://api.github.com/repos/Microsoft/edx-platform/subscribers","subscription_url":"https://api.github.com/repos/Microsoft/edx-platform/subscription","commits_url":"https://api.github.com/repos/Microsoft/edx-platform/commits{/sha}","git_commits_url":"https://api.github.com/repos/Microsoft/edx-platform/git/commits{/sha}","comments_url":"https://api.github.com/repos/Microsoft/edx-platform/comments{/number}","issue_comment_url":"https://api.github.com/repos/Microsoft/edx-platform/issues/comments{/number}","contents_url":"https://api.github.com/repos/Microsoft/edx-platform/contents/{+path}","compare_url":"https://api.github.com/repos/Microsoft/edx-platform/compare/{base}...{head}","merges_url":"https://api.github.com/repos/Microsoft/edx-platform/merges","archive_url":"https://api.github.com/repos/Microsoft/edx-platform/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/Microsoft/edx-platform/downloads","issues_url":"https://api.github.com/repos/Microsoft/edx-platform/issues{/number}","pulls_url":"https://api.github.com/repos/Microsoft/edx-platform/pulls{/number}","milestones_url":"https://api.github.com/repos/Microsoft/edx-platform/milestones{/number}","notifications_url":"https://api.github.com/repos/Microsoft/edx-platform/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/Microsoft/edx-platform/labels{/name}","releases_url":"https://api.github.com/repos/Microsoft/edx-platform/releases{/id}","deployments_url":"https://api.github.com/repos/Microsoft/edx-platform/deployments","created_at":"2016-08-11T16:18:42Z","updated_at":"2018-04-20T18:33:01Z","pushed_at":"2018-04-24T15:34:49Z","git_url":"git://github.com/Microsoft/edx-platform.git","ssh_url":"git@github.com:Microsoft/edx-platform.git","clone_url":"https://github.com/Microsoft/edx-platform.git","svn_url":"https://github.com/Microsoft/edx-platform","homepage":"http://open.edx.org/","size":883846,"stargazers_count":11,"watchers_count":11,"language":"Python","has_issues":false,"has_projects":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":20,"mirror_url":null,"archived":false,"open_issues_count":9,"license":{"key":"agpl-3.0","name":"GNU Affero General Public License v3.0","spdx_id":"AGPL-3.0","url":"https://api.github.com/licenses/agpl-3.0"},"forks":20,"open_issues":9,"watchers":11,"default_branch":"oxa/dev.fic"}},"base":{"label":"edx:master","ref":"master","sha":"8515cdf4634c9dfa9996047ce011c3c7268b6c48","user":{"login":"edx","id":3179841,"avatar_url":"https://avatars3.githubusercontent.com/u/3179841?v=4","gravatar_id":"","url":"https://api.github.com/users/edx","html_url":"https://github.com/edx","followers_url":"https://api.github.com/users/edx/followers","following_url":"https://api.github.com/users/edx/following{/other_user}","gists_url":"https://api.github.com/users/edx/gists{/gist_id}","starred_url":"https://api.github.com/users/edx/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/edx/subscriptions","organizations_url":"https://api.github.com/users/edx/orgs","repos_url":"https://api.github.com/users/edx/repos","events_url":"https://api.github.com/users/edx/events{/privacy}","received_events_url":"https://api.github.com/users/edx/received_events","type":"Organization","site_admin":false},"repo":{"id":10391073,"name":"edx-platform","full_name":"edx/edx-platform","owner":{"login":"edx","id":3179841,"avatar_url":"https://avatars3.githubusercontent.com/u/3179841?v=4","gravatar_id":"","url":"https://api.github.com/users/edx","html_url":"https://github.com/edx","followers_url":"https://api.github.com/users/edx/followers","following_url":"https://api.github.com/users/edx/following{/other_user}","gists_url":"https://api.github.com/users/edx/gists{/gist_id}","starred_url":"https://api.github.com/users/edx/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/edx/subscriptions","organizations_url":"https://api.github.com/users/edx/orgs","repos_url":"https://api.github.com/users/edx/repos","events_url":"https://api.github.com/users/edx/events{/privacy}","received_events_url":"https://api.github.com/users/edx/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/edx/edx-platform","description":"The Open edX platform, the software that powers edX!","fork":false,"url":"https://api.github.com/repos/edx/edx-platform","forks_url":"https://api.github.com/repos/edx/edx-platform/forks","keys_url":"https://api.github.com/repos/edx/edx-platform/keys{/key_id}","collaborators_url":"https://api.github.com/repos/edx/edx-platform/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/edx/edx-platform/teams","hooks_url":"https://api.github.com/repos/edx/edx-platform/hooks","issue_events_url":"https://api.github.com/repos/edx/edx-platform/issues/events{/number}","events_url":"https://api.github.com/repos/edx/edx-platform/events","assignees_url":"https://api.github.com/repos/edx/edx-platform/assignees{/user}","branches_url":"https://api.github.com/repos/edx/edx-platform/branches{/branch}","tags_url":"https://api.github.com/repos/edx/edx-platform/tags","blobs_url":"https://api.github.com/repos/edx/edx-platform/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/edx/edx-platform/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/edx/edx-platform/git/refs{/sha}","trees_url":"https://api.github.com/repos/edx/edx-platform/git/trees{/sha}","statuses_url":"https://api.github.com/repos/edx/edx-platform/statuses/{sha}","languages_url":"https://api.github.com/repos/edx/edx-platform/languages","stargazers_url":"https://api.github.com/repos/edx/edx-platform/stargazers","contributors_url":"https://api.github.com/repos/edx/edx-platform/contributors","subscribers_url":"https://api.github.com/repos/edx/edx-platform/subscribers","subscription_url":"https://api.github.com/repos/edx/edx-platform/subscription","commits_url":"https://api.github.com/repos/edx/edx-platform/commits{/sha}","git_commits_url":"https://api.github.com/repos/edx/edx-platform/git/commits{/sha}","comments_url":"https://api.github.com/repos/edx/edx-platform/comments{/number}","issue_comment_url":"https://api.github.com/repos/edx/edx-platform/issues/comments{/number}","contents_url":"https://api.github.com/repos/edx/edx-platform/contents/{+path}","compare_url":"https://api.github.com/repos/edx/edx-platform/compare/{base}...{head}","merges_url":"https://api.github.com/repos/edx/edx-platform/merges","archive_url":"https://api.github.com/repos/edx/edx-platform/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/edx/edx-platform/downloads","issues_url":"https://api.github.com/repos/edx/edx-platform/issues{/number}","pulls_url":"https://api.github.com/repos/edx/edx-platform/pulls{/number}","milestones_url":"https://api.github.com/repos/edx/edx-platform/milestones{/number}","notifications_url":"https://api.github.com/repos/edx/edx-platform/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/edx/edx-platform/labels{/name}","releases_url":"https://api.github.com/repos/edx/edx-platform/releases{/id}","deployments_url":"https://api.github.com/repos/edx/edx-platform/deployments","created_at":"2013-05-30T20:20:38Z","updated_at":"2018-04-24T14:28:34Z","pushed_at":"2018-04-24T15:29:57Z","git_url":"git://github.com/edx/edx-platform.git","ssh_url":"git@github.com:edx/edx-platform.git","clone_url":"https://github.com/edx/edx-platform.git","svn_url":"https://github.com/edx/edx-platform","homepage":"http://open.edx.org/","size":909049,"stargazers_count":3656,"watchers_count":3656,"language":"Python","has_issues":false,"has_projects":true,"has_downloads":true,"has_wiki":true,"has_pages":true,"forks_count":2044,"mirror_url":null,"archived":false,"open_issues_count":249,"license":{"key":"agpl-3.0","name":"GNU Affero General Public License v3.0","spdx_id":"AGPL-3.0","url":"https://api.github.com/licenses/agpl-3.0"},"forks":2044,"open_issues":249,"watchers":3656,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/edx/edx-platform/pulls/17602"},"html":{"href":"https://github.com/edx/edx-platform/pull/17602"},"issue":{"href":"https://api.github.com/repos/edx/edx-platform/issues/17602"},"comments":{"href":"https://api.github.com/repos/edx/edx-platform/issues/17602/comments"},"review_comments":{"href":"https://api.github.com/repos/edx/edx-platform/pulls/17602/comments"},"review_comment":{"href":"https://api.github.com/repos/edx/edx-platform/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/edx/edx-platform/pulls/17602/commits"},"statuses":{"href":"https://api.github.com/repos/edx/edx-platform/statuses/85f8c1da838c2b2ce94d180b9b71cb3e7ee3d165"}},"author_association":"NONE"}}
{"actor":{"display_login":"nasthagiri"}}