【问题标题】:(Python) Error 401 when trying to access course work using Google Classroom API(Python) 尝试使用 Google Classroom API 访问课程作业时出现错误 401
【发布时间】:2020-11-16 07:09:57
【问题描述】:

我对 google api 还很陌生,所以我一直在搞乱课堂 api。我使用了示例代码,它可以很好地获取课程列表,但是当我尝试访问课程作业、主题或公告的列表时,我收到以下错误:

googleapiclient.errors.HttpError: <HttpError 404 when requesting https://classroom.googleapis.com/v1/courses/courseId/courseWork?alt=json returned "Requested entity was not found.">

出于隐私原因,我在我的程序中放置了课程 ID 的占位符,但是当我使用真实的课程 ID 时会出现此问题。这是我在控制台中单击链接时显示的内容:

{
  "error": {
    "code": 401,
    "message": "Request is missing required authentication credential. Expected OAuth 2 access token, login cookie or other valid authentication credential. See https://developers.google.com/identity/sign-in/web/devconsole-project.",
    "status": "UNAUTHENTICATED"
  }
}

我尝试单击该错误中的链接,但根本没有帮助。我很困惑我的控制台给我一个错误 404,而链接给我一个错误 401。如果它们是同一件事,请原谅我。我还尝试使用其他两个帐户,但都不起作用。我以为我的代码可能做错了什么,但我用课程作业样本对其进行了测试,但也没有奏效。重要的是要提到我不是管理员,而是一个试图构建可以帮助我的东西的学生。我也认为是令牌的问题,但如上所述,我尝试使用其他帐户,所以我不应该需要使用刷新令牌。我的程序是用 python 编写的。 我的代码:

from __future__ import print_function
import pickle
import os.path
from googleapiclient.discovery import build
from google_auth_oauthlib.flow import InstalledAppFlow
from google.auth.transport.requests import Request

# If modifying these scopes, delete the file token.pickle.
SCOPES = ['https://www.googleapis.com/auth/classroom.coursework.students']

def main():
    creds = None
    # The file token.pickle stores the user's access and refresh tokens, and is
    # created automatically when the authorization flow completes for the first
    # time.
    if os.path.exists('token.pickle'):
        with open('token.pickle', 'rb') as token:
            creds = pickle.load(token)
    # If there are no (valid) credentials available, let the user log in.
    if not creds or not creds.valid:
        if creds and creds.expired and creds.refresh_token:
            creds.refresh(Request())
        else:
            flow = InstalledAppFlow.from_client_secrets_file(
                'credentials.json', SCOPES)
            creds = flow.run_local_server(port=0)
        # Save the credentials for the next run
        with open('token.pickle', 'wb') as token:
            pickle.dump(creds, token)

    service = build('classroom', 'v1', credentials=creds)
    # I put a placeholder for courseId, but I can provide an id to a test course if needed
    results = service.courses().courseWork().list(courseId="courseId").execute()
    courses = results.get('courseWork', [])

    if not courses:
        print('No coursework found.')
    else:
        print('Coursework:')
        for courseWork in cwork:
            print(courseWork['name'])
if __name__ == '__main__':
    main()

我可能将错误的参数传递给函数,但我查看了示例,但我不这么认为。这与问题无关,但如果有人能告诉我如何使用刷新令牌,那就太好了。感谢您的帮助。

【问题讨论】:

  • 确保您使用的是正确的 CourseId,并且 courseWorkStates 对应于课程工作状态。试试API Explorer
  • @Jescanellas 感谢您的帮助!问题是我没有使用正确的课程 ID。我以为您会以与 google doc 相同的方式获得它,但我需要让我的程序为此打印它。
  • 这是否意味着您设法使其工作?如果是这样,请尝试发布答案,以便其他人受益并支持您的解决方案。

标签: python google-classroom


【解决方案1】:

我的代码的问题是我使用了错误的教室 ID。与 google docs/sheets 不同,您无法在地址中找到教室 ID。对我来说,我浏览了每门课程并编写了代码来打印 ID,我将其替换到我的程序中以列出课程作业。这是我完成的代码:

from __future__ import print_function
import pickle
import os.path
from googleapiclient.discovery import build
from google_auth_oauthlib.flow import InstalledAppFlow
from google.auth.transport.requests import Request

SCOPES = ['https://www.googleapis.com/auth/classroom.coursework.me' , 'https://www.googleapis.com/auth/classroom.courses']

def main():
    """Shows basic usage of the Classroom API.
    Prints the names of the first 10 courses the user has access to.
    """
    creds = None
    if os.path.exists('token.pickle'):
        with open('token.pickle', 'rb') as token:
            creds = pickle.load(token)
    if not creds or not creds.valid:
        if creds and creds.expired and creds.refresh_token:
            creds.refresh(Request())
        else:
            flow = InstalledAppFlow.from_client_secrets_file(
                'credentials.json', SCOPES)
            creds = flow.run_local_server(port=0)
        with open('token.pickle', 'wb') as token:
            pickle.dump(creds, token)
    service = build('classroom', 'v1', credentials=creds)
    rs = service.courses().list(pageSize='1').execute()
    courses = rs.get('courses' , [])
    i = 0
    if not courses:
        print('No coursework found.')
    else:
        for course in courses:
            a = course['id']
            results = service.courses().courseWork().list(courseId=a, 
                pageSize='1').execute()
            cwork = results.get('courseWork', [])
            for courseWork in cwork:
                print(courseWork['title'])

if __name__ == '__main__':
    main()

出于测试目的,它只打印一门课程中的一项,但更改页面大小会改变这一点。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-05-20
    • 2020-03-29
    • 2015-11-30
    • 1970-01-01
    • 2012-05-12
    • 2013-03-08
    • 2019-08-24
    相关资源
    最近更新 更多