当前位置: 首页 > 知识库问答 >
问题:

谷歌教室API补丁

臧梓
2023-03-14

在谷歌教室API中执行课程.courseWork.studentSubmissions.patch方法时,当我尝试更新学生提交的内容时,返回403错误。下面是我的代码。

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

学生提交的内容包含以下字段assignedGrade、draftGrade、附件(链接资源)和state。

电话是从一个经过认证的学生账户打来的。开发人员控制台项目启用了Google Classroom API,对Google Classroom API的其他调用工作正常,例如courses.courseWork.createcourses.courseWork.studentSubmissions.list.此外,我正在从相同的开发人员控制台项目提出请求,从课程工作项被关联/创建。

当我从谷歌API浏览器尝试时,返回了相同的错误403错误和不同的消息。

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

任何帮助都将不胜感激谢谢

共有1个答案

邹宏峻
2023-03-14

这个错误消息基本上意味着你没有权限去做你想做的事情。权限与您对用户进行身份验证的作用域有关。下面是作用域的完整列表

方法:courses.courseWork.studentSubmis.patch需要以下范围。

授权

需要以下OAuth作用域之一:

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

在补丁之前使用列表和获取

使用list和get-before-patch确保您拥有corect ID。

如果您让用户先执行一个列表,然后找到您要的列表,然后执行一个get,那么您可以在get中对对象进行更改,然后对该对象运行更新。这样做可以确保您传递的所有ID都是正确的,并且用户实际上可以访问他们试图更新的内容。

 类似资料:
  • 我已经用自动完成和谷歌地理编码应用编程接口实现了谷歌地方应用编程接口。问题是结果似乎不正确。 有时自动完成列表中的一些选择结果根本没有地理编码,我得到的只是状态ZERO_RESULTS。 我知道Google Autocomplete也使用Places,而Google Geocode只使用邮政编码,这可能会有一些问题,但我如何限制Autocomplete只提供邮政编码结果呢。

  • 我知道可以使用谷歌API视觉在网上找到类似的图片。我的目标是根据我的图像数据库找到类似的图像。我不想在网上看到类似的图片。 可能吗? 如果是,你能给我一些链接或建议吗? 谢谢

  • 我正在开发一个网络应用程序,代表用户获取谷歌广告活动的信息。我使用的是谷歌提供的python库,但我在获取开始测试API调用的初始凭据时遇到了很多麻烦。 我遵循以下文件:https://github.com/googleads/google-ads-python/wiki/OAuth-Web-Application-Flow 我已经完成了第一步,我有我的客户机密码、客户机ID和重定向uri。 在第

  • 我想知道我是否需要Google java客户端库才能从GAE访问我的Google日历。默认情况下,它们是Google App Engine SDK的一部分吗? 此外,我找不到一个很好的示例或教程来展示如何从Google Cloud Platform应用程序创建、读取、更新和删除Google日历事件。 非常感谢,如果您可以提供相同的代码示例或链接到适当的工作教程。

  • 最近Chrome开始发出以下警告: [违规]将非被动事件侦听器添加到阻止滚动的触摸移动事件。考虑将事件处理程序标记为“被动”,以使页面更具响应性。看https://www.chromestatus.com/feature/5745543795965952 这些都来自JavaScript谷歌地图API代码。我可以在自己的代码中将{passive:true}添加到addEventListener(),

  • 编译时,我得到了这个错误:错误:任务执行失败:应用程序:进程调试资源。 错误:多个包名为com.google.android.gms的库 但是,当删除该行时:compile'com。谷歌。Android游戏服务:6.1.11' 我得到以下错误:错误:(41,42)错误:包com。谷歌。Androidgms。appindexing不存在错误:(42,42)错误:包com。谷歌。Androidgms。