title: Google Classroom API patch
body: <p>When executing the <code>courses.courseWork.studentSubmissions.patch</code> method in the Google Classroom API, a 403 error is returned when I try to update the student's submission. Below is my code.</p>
  
  <pre><code>from googleapiclient.discovery import build
  from oauth2client import client
  import simplejson as json
  
  class Google:
      SCOPE = {
          "profile": {"scope": "profile email", "access_type": "offline"},
          "classroom": {"scope": 'https://www.googleapis.com/auth/classroom.courses.readonly '
                                 'https://www.googleapis.com/auth/classroom.rosters.readonly '
                                  'https://www.googleapis.com/auth/classroom.profile.emails '
                                  'https://www.googleapis.com/auth/classroom.profile.photos ',
                      "access_type": "offline"},
          "classwork":{
              "scope": "https://www.googleapis.com/auth/classroom.coursework.students https://www.googleapis.com/auth/classroom.coursework.me",
              "access_type":"offline"
          },
          "submission":{
              "scope": "https://www.googleapis.com/auth/classroom.coursework.me https://www.googleapis.com/auth/classroom.coursework.students profile email",
              "access_type":"offline"
          }
      }
      ERRORS = {
                  "invalid_request":{"code":"invalid_request","msg":"Invalid request. Please Try with login again."},
                  "account_used":{"code":"account_used","msg":"Google account is already configured with different PracTutor Account."},
                  "assignment_permission_denied":{"code":"assignment_permission_denied","msg":"permission denied"},
                  "unknown_error":{"code":"unknown_error","msg":"something went wrong."}
                }
  
      def __init__(self, code = "", genFor = "profile"):
          if code:
              genFor = genFor if genFor else "profile"
              self.credentials = client.credentials_from_clientsecrets_and_code(pConfig['googleOauthSecretFile'],self.SCOPE[genFor]["scope"], code)
              self.http_auth = self.credentials.authorize(httplib2.Http())
              cred_json = self.credentials.to_json()
              idinfo = json.loads(cred_json)["id_token"]
          else:
              raise ValueError(Google.ERRORS["invalid_request"])
  
      def getUserInfo(self):
          service = build(serviceName='oauth2', version='v2', http=self.http_auth)
          idinfo = service.userinfo().get().execute()
          return idinfo
  
      def getClasses(self):
          courses = []
          page_token = None
          service = build('classroom', 'v1', http=self.http_auth)
          while True:
              response = service.courses().list(teacherId="me",pageToken=page_token,
                                                pageSize=100).execute()
              courses.extend(response.get('courses', []))
              page_token = response.get('nextPageToken', None)
              if not page_token:
                  break
          return courses
  
      def getStudent(self,course_id):
          students = []
          page_token = None
          service = build('classroom', 'v1', http=self.http_auth)
          while True:
              response = service.courses().students().list(courseId=course_id, pageToken=page_token,
                                                pageSize=100).execute()
              students.extend(response.get('students', []))
              page_token = response.get('nextPageToken', None)
              if not page_token:
                  break
          return students
  
      def createAssignment(self,course_id,**kwargs):
          service = build('classroom', 'v1', http=self.http_auth)
          date, time = kwargs["dueDate"].split(" ")
          yy,mm,dd = date.split("-")
          h,m,s = time.split(":")
          courseWork = {
              'title': kwargs["title"],
              'description': kwargs["desc"],
              'materials': [
                  {'link': { 'url': kwargs["link"] } },
              ],
              'dueDate': {
                  "month": mm,
                  "year": yy,
                  "day": dd
              },
              'dueTime':{
                  "hours": h,
                  "minutes": m,
                  "seconds": s
                },
              'workType': 'ASSIGNMENT',
              'state': 'PUBLISHED',
          }
          courseWork = service.courses().courseWork().create(courseId=course_id, body=courseWork).execute()
          return courseWork
  
      def submitAssignment(self,**kwargs):
          service = build('classroom', 'v1', http=self.http_auth)
          course_id = kwargs["courseId"]
          courseWorkId = kwargs["courseWorkId"]
          score = kwargs["score"]
          studentSubmission = {
              'assignedGrade': score,
              'draftGrade': score,
              'assignmentSubmission': {
                  'attachments': [
                      {
                          'link': {
                              "url": "demo.com",
                              "title": "Assignment1",
                              "thumbnailUrl": "demo.com",
                          }
                      }
                  ],
              },
              'state': 'TURNED_IN',
          }
          gCredentials = json.loads(self.credentials.to_json())
          userGId = gCredentials["id_token"]["sub"]
          studentSubmissionsData = service.courses().courseWork().studentSubmissions().list(
              courseId=course_id,
              courseWorkId=courseWorkId,
              userId=userGId).execute()
          studentSubmissionId = studentSubmissionsData["studentSubmissions"][0]["id"]
          courseWorkRes = service.courses().courseWork().studentSubmissions().patch(
                      courseId=course_id,
                      courseWorkId=courseWorkId,
                      id=studentSubmissionId,
                      updateMask='assignedGrade,draftGrade',
                      body=studentSubmission).execute()
          return courseWorkRes
  
  
  Method Calling     
  g = Google()
  kwargs = {"courseId":courseId,"courseWorkId":courseWorkId,"score":80}
  courseworkResponse = g.submitAssignment(**kwargs)
  </code></pre>
  
  <p>Error:</p>
  
  <blockquote>
    <p>https://classroom.googleapis.com/v1/courses/{courses_id}/courseWork/{courseWork_id}/studentSubmissions/{studentSubmissions_id}?alt=json&amp;updateMask=assignedGrade%2CdraftGrade
    returned "The caller does not have permission"></p>
  </blockquote>
  
  <p>Student's submission contains following fields assignedGrade, draftGrade, attachments (Link resource) and state.</p>
  
  <p>The call is being made from an authenticated student account. The Developer Console project has the Google Classroom API enabled, and other calls to the Google Classroom API are working fine, such as courses.courseWork.create and courses.courseWork.studentSubmissions.list. Also I am making request from the same Developer Console project from course work item is associated/created.</p>
  
  <p>The same error 403 error with different message is returned when I am trying from Google API explorer.</p>
  
  <pre><code>{
    "error": {
      "code": 403,
      "message": "@ProjectPermissionDenied The Developer Console project is not permitted to make this request.",
      "status": "PERMISSION_DENIED"
    }
  }
  </code></pre>
  
  <p>Any help would be appreciated, thank you</p>