2017-04-19 62 views
1

在Google Classroom API中執行courses.courseWork.studentSubmissions.patch方法時,當我嘗試更新學生的提交時,會返回403錯誤。以下是我的代碼。Google課堂API補丁

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) 

錯誤:

https://classroom.googleapis.com/v1/courses/{courses_id}/courseWork/{courseWork_id}/studentSubmissions/{studentSubmissions_id}?alt=json&updateMask=assignedGrade%2CdraftGrade returned "The caller does not have permission">

學生提交的材料包括以下字段assignedGrade,draftGrade,附件(鏈接資源)和狀態。

該通話是通過經過身份驗證的學生帳戶進行的。開發者控制檯項目啓用了Google課堂API,並且其他對Google Classroom API的調用工作正常,例如courses.courseWork.create和courses.courseWork.studentSubmissions.list。另外,我正在從課程工作項目的相同開發者控制檯項目請求關聯/創建。

當我從Google API Explorer嘗試時,返回不同消息的錯誤403錯誤。

{ 
    "error": { 
    "code": 403, 
    "message": "@ProjectPermissionDenied The Developer Console project is not permitted to make this request.", 
    "status": "PERMISSION_DENIED" 
    } 
} 

任何幫助,將不勝感激,謝謝

+0

你認證該學生的範圍是什麼? – DaImTo

回答

0

該錯誤消息基本上意味着你沒有權限做什麼是你正在嘗試做的。權限與您使用哪個範圍進行身份驗證相關。這裏是完整列表scopes

Method: courses.courseWork.studentSubmis.patch需要以下範圍。

授權

需要以下OAuth範圍之一:

https://www.googleapis.com/auth/classroom.coursework.students 
https://www.googleapis.com/auth/classroom.coursework.me 

使用列表和補丁之前獲取

使用列表和補丁前獲得,以確保你有corect ID。

如果您先讓用戶執行list然後找到您要執行的操作,然後執行get,則可以更改get中的對象然後在其上運行更新。這樣做可以確保您傳遞的所有ID都是正確的,並且用戶確實可以訪問他們嘗試更新的內容。

+0

是的,我正在使用這兩個範圍進行身份驗證。 –

+0

你可以在你創建服務時添加代碼 – DaImTo

+0

你可以檢查代碼[here](https://pastebin.com/PPWVXBq1) –