使用 Classroom API 管理評分週期

本指南說明如何使用 Google Classroom API 中的評分期間端點。

總覽

評分週期可將作業、測驗和專案整理到特定日期範圍。Classroom API 可讓開發人員代表管理員和老師,在 Classroom 中建立、修改及讀取評分期間。您也可以使用 Classroom API 在 CourseWork 中設定評分週期。

Classroom API 提供兩個端點,可讀取及寫入課程的評分期間資訊:

  • GetGradingPeriodSettings:可讓您讀取課程中的評分期間設定。
  • UpdateGradingPeriodSettings:讓您管理課程中的評分期間設定,方法是新增、修改和刪除評分期間,並將已設定的評分期間套用至所有現有的 CourseWork。

授權需求

修改課程的評分週期設定

如要使用 UpdateGradingPeriodSettings 端點在課程中建立、修改或刪除評分期間,必須符合下列條件:

讀取課程中的評分週期設定

無論指派的授權為何,課程的網域管理員和老師都可以讀取評分期間設定。也就是說,系統會允許任何網域管理員或老師代表要求存取 GetGradingPeriodSettings 端點。

在 CourseWork 上設定評分週期 ID

無論指派的授權為何,課程老師都可以在使用 API 建立或更新 CourseWork 時,加入 gradingPeriodId

檢查使用者是否符合設定評分期間的資格

系統會允許代表任何管理員或老師,向 checkGradingPeriodsSetupEligibility 端點提出要求。用於判斷使用者是否可以修改課程的評分期間。

必要條件

本指南提供 Python 程式碼範例,並假設您具備以下條件:

  • Google Cloud 專案。您可以按照 Python 快速入門中的操作說明進行設定。
  • 將下列權限範圍新增至專案的 OAuth 同意畫面:
    • https://www.googleapis.com/auth/classroom.courses
    • https://www.googleapis.com/auth/classroom.coursework.students
  • 應修改評分期間的課程 ID。課程擁有者必須具備 Google Workspace for Education Plus 授權。
  • 使用 Google Workspace for Education Plus 授權存取老師或管理員的憑證。您需要老師的憑證才能建立或修改 CourseWork。如果管理員不是課程老師,就無法建立或修改 CourseWork。

管理 GradingPeriodSettings 資源

GradingPeriodSettings 資源包含個別 GradingPeriods 清單和名為 applyToExistingCoursework 的布林欄位。

GradingPeriods 清單代表課程中的所有個別評分期間。您必須為清單中的每個評分期間指定標題、開始日期和結束日期。課程中的每個評分週期都必須有專屬的標題,且不同評分週期的開始和結束日期不得重疊。每個評分期間都會有 Classroom API 指派的專屬 ID。

applyToExistingCoursework 布林值是持續設定,可讓您將先前建立的 CourseWork 組織成評分期間,而無須進行個別 API 呼叫來修改每個 CourseWork 的 gradingPeriodId。如果設為 True,當 courseWork.dueDate 落在現有評分期間的開始和結束日期之間,Classroom 就會自動為所有現有 CourseWork 設為 gradingPeriodId。如果未在 CourseWork 中設定截止日期,Classroom 會使用 courseWork.scheduledTime。如果兩個欄位都沒有值,或是在現有評分期間的開始和結束日期中沒有相符項目,CourseWork 就不會與任何評分期間建立關聯。

判斷使用者是否可修改課程的評分期間設定

只有具備特定授權的使用者,才能在 Classroom 中建立及修改評分期間,因此 Classroom API 提供 checkGradingPeriodsSetupEligibility 端點,協助您主動判斷使用者是否能向 UpdateGradingPeriodSettings 端點提出要求。

Python

def check_grading_period_setup_eligibility(classroom, course_id):
    """Checks whether a user is able to create and modify grading periods in a course."""
    try:
        grading_period_eligibility_response = classroom.courses().checkGradingPeriodsSetupEligibility(
          courseId=course_id, previewVersion="V1_20240401_PREVIEW").execute()

        # Retrieve the isGradingPeriodsSetupEligible boolean from the response.
        # If the boolean is `True`, the user is able to modify grading period settings in the course.
        is_grading_periods_eligible = grading_period_eligibility_response.get("isGradingPeriodsSetupEligible")
        return is_grading_periods_eligible
    except HttpError as error:
        # Handle errors as appropriate for your application.
        print(f"An error occurred: {error}")
        return error

新增評分週期

確認使用者具備修改課程評分期間設定所需的授權後,您就可以開始向 UpdateGradingPeriodSettings 端點發出要求。無論是新增個別評分期間、修改現有評分期間,還是刪除評分期間,都必須使用 UpdateGradingPeriodSettings 端點執行 GradingPeriodSettings 資源的任何修改作業。

Python

在以下範例中,我們修改 gradingPeriodSettings 資源,加入兩個評分期間。applyToExistingCoursework 布林值設為 True 時,系統會修改評分期間開始和結束日期之間任何現有課程作業的 gradingPeriodId。請注意,updateMask 包含這兩個欄位。在回應中傳回個別評分期間的 ID 後,請儲存這些 ID。您需要使用這些 ID 更新評分週期 (如有需要)。

def create_grading_periods(classroom, course_id):
    """
    Create grading periods in a course and apply the grading periods
    to existing courseWork.
    """
    try:
        body = {
          "gradingPeriods": [
            {
              "title": "First Semester",
              "start_date": {
                "day": 1,
                "month": 9,
                "year": 2023
              },
              "end_date": {
                "day": 15,
                "month": 12,
                "year": 2023
              }
            },
            {
              "title": "Second Semester",
              "start_date": {
                "day": 15,
                "month": 1,
                "year": 2024
              },
              "end_date": {
                "day": 31,
                "month": 5,
                "year": 2024
              }
            }
          ],
          "applyToExistingCoursework": True
        }
        gradingPeriodSettingsResponse = classroom.courses().updateGradingPeriodSettings(
          courseId=course_id,
          updateMask='gradingPeriods,applyToExistingCoursework',
          body=body,
          previewVersion="V1_20240401_PREVIEW"
        ).execute();

        print(f"Grading period settings updated.")
        return gradingPeriodSettingsResponse

    except HttpError as error:
        # Handle errors as appropriate for your application.
        print(f"An error occurred: {error}")
        return error

讀取評分週期設定

GradingPeriodSettings 會使用 GetGradingPeriodSettings 端點進行讀取。無論授權為何,任何使用者都能查看課程的評分期間設定。

Python

def get_grading_period_settings(classroom, course_id):
    """Read grading periods settings in a course."""
    try:
        gradingPeriodSettings = classroom.courses().getGradingPeriodSettings(
          courseId=course_id, previewVersion="V1_20240401_PREVIEW").execute()
        return gradingPeriodSettings
    except HttpError as error:
        # Handle errors as appropriate for your application.
        print(f"An error occurred: {error}")
        return error

將個別評分週期新增至清單

個別評分期間的更新作業必須遵循讀取-修改-寫入模式。這代表您應該:

  1. 使用 GetGradingPeriodSettings 端點讀取 GradingPeriodSettings 資源中的評分期間清單。
  2. 在評分期間清單中進行所選修改。
  3. 在要求中傳送新的評分期間清單給 UpdateGradingPeriodSettings

這個模式可確保課程中各個評分期間的標題皆不重複,且評分期間的開始與結束日期不會重疊。

請注意更新評分期間清單的規則:

  1. 未附 ID 新增至清單的評分週期視為新增
  2. 清單中「缺少」的評分期間會視為刪除
  3. 評分期間具有現有 ID,但資料已修改,會視為編輯。未修改的屬性則維持原樣。
  4. 含有新 ID 或不明 ID的評分期間會視為錯誤

Python

以下程式碼會以本指南中的範例為基礎。系統會建立名為「Summer」的新評分期間。在要求主體中,applyToExistingCoursework 布林值設為 False

做法是讀取目前的 GradingPeriodSettings,將新的評分期間新增至清單,並將 applyToExistingCoursework 布林值設為 False。請注意,已套用至現有課程作業的任何評分期間都不會遭到移除。在上述範例中,「Semester 1」和「Semester 2」評分期間已套用至現有的 CourseWork,如果在後續要求中將 applyToExistingCoursework 設為 False,就不會從 CourseWork 中移除。

def add_grading_period(classroom, course_id):
    """
    A new grading period is added to the list, but it is not applied to existing courseWork.
    """
    try:
        # Use the `GetGradingPeriodSettings` endpoint to retrieve the existing
        # grading period IDs. You will need to include these IDs in the request
        # body to make sure existing grading periods aren't deleted.
        body = {
          "gradingPeriods": [
            {
              # Specify the ID to make sure the grading period is not deleted.
              "id": "FIRST_SEMESTER_GRADING_PERIOD_ID",
              "title": "First Semester",
              "start_date": {
                "day": 1,
                "month": 9,
                "year": 2023
              },
              "end_date": {
                "day": 15,
                "month": 12,
                "year": 2023
              }
            },
            {
              # Specify the ID to make sure the grading period is not deleted.
              "id": "SECOND_SEMESTER_GRADING_PERIOD_ID",
              "title": "Second Semester",
              "start_date": {
                "day": 15,
                "month": 1,
                "year": 2024
              },
              "end_date": {
                "day": 31,
                "month": 5,
                "year": 2024
              }
            },
            {
              # Does not include an ID because this grading period is an addition.
              "title": "Summer",
              "start_date": {
                "day": 1,
                "month": 6,
                "year": 2024
              },
              "end_date": {
                "day": 31,
                "month": 8,
                "year": 2024
              }
            }
          ],
          "applyToExistingCoursework": False
        }

        gradingPeriodSettings = classroom.courses().updateGradingPeriodSettings(
          courseId=course_id, body=body, updateMask='gradingPeriods,applyToExistingCoursework',
          previewVersion="V1_20240401_PREVIEW").execute()
        return gradingPeriodSettings

    except HttpError as error:
        # Handle errors as appropriate for your application.
        print(f"An error occurred: {error}")
        return error

applyToExistingCoursework 布林欄位的實用指標

請務必記住,applyToExistingCoursework 布林值會持續保留,也就是說,如果布林值在先前的 API 呼叫中設為 True 且未變更,後續更新的評分期間會套用至現有的 CourseWork。

請注意,如果您在 UpdateGradingPeriodSettings 的要求中將此布林值從 True 變更為 False,則只有您對 GradingPeriodSettings 所做的新變更不會套用至現有的 CourseWork。當布林值設為 True 時,系統不會移除先前 API 呼叫中套用至 CourseWork 的任何評分期間資訊。您可以這麼想:這個布林值設定可讓您將現有的 CourseWork 與已設定的評分期間建立關聯,但無法移除 CourseWork 與已設定的評分期間之間的現有關聯。

無論 applyToExistingCoursework 布林值的設定為何,如果您刪除或變更評分期間的標題,這些變更都會傳播至所有現有的 CourseWork。

更新清單中的個別評分週期

如要修改與現有評分期間相關聯的部分資料,請在修改後的資料清單中加入現有評分期間的 ID。

Python

在這個範例中,系統會修改「Summer」評分期間的結束日期。applyToExistingCoursework 欄位會設為 True。請注意,將這個布林值設為 True 會將所有已設定的評分期間套用至現有的課程作業。在先前的 API 要求中,布林值已設為 False,因此「Summer」評分期間不會套用至現有的 CourseWork。這個布林值欄位已設為 True,因此「Summer」評分期間會套用至所有相符的現有 CourseWork。

def update_existing_grading_period(classroom, course_id):
    """
    An existing grading period is updated.
    """
    try:
        # Use the `GetGradingPeriodSettings` endpoint to retrieve the existing
        # grading period IDs. You will need to include these IDs in the request
        # body to make sure existing grading periods aren't deleted.
        body = {
          "gradingPeriods": [
            {
              "id": "FIRST_SEMESTER_GRADING_PERIOD_ID",
              "title": "First Semester",
              "start_date": {
                "day": 1,
                "month": 9,
                "year": 2023
              },
              "end_date": {
                "day": 15,
                "month": 12,
                "year": 2023
              }
            },
            {
              "id": "SECOND_SEMESTER_GRADING_PERIOD_ID",
              "title": "Second Semester",
              "start_date": {
                "day": 15,
                "month": 1,
                "year": 2024
              },
              "end_date": {
                "day": 31,
                "month": 5,
                "year": 2024
              }
            },
            {
              # The end date for this grading period will be modified from August 31, 2024 to September 10, 2024.
              # Include the grading period ID in the request along with the new data.
              "id": "SUMMER_GRADING_PERIOD_ID",
              "title": "Summer",
              "start_date": {
                "day": 1,
                "month": 6,
                "year": 2024
              },
              "end_date": {
                "day": 10,
                "month": 9,
                "year": 2024
              }
            }
          ],
          "applyToExistingCoursework": True
        }

        gradingPeriodSettings = classroom.courses().updateGradingPeriodSettings(
          courseId=course_id, body=body, updateMask='gradingPeriods,applyToExistingCoursework',
          previewVersion="V1_20240401_PREVIEW").execute()
        return gradingPeriodSettings

    except HttpError as error:
        # Handle errors as appropriate for your application.
        print(f"An error occurred: {error}")
        return error

刪除個別評分週期

如要刪除評分週期,請從清單中省略評分週期。請注意,無論 applyToExistingCoursework 設定為何,如果刪除評分期間,CourseWork 中任何與評分期間相關的內容也會一併刪除。

Python

如要繼續本指南中的範例,請省略「夏季」評分期間,以便刪除該期間。

def delete_grading_period(classroom, course_id):
    """
    An existing grading period is deleted.
    """
    try:
        body = {
          "gradingPeriods": [
            {
              "id": "FIRST_SEMESTER_GRADING_PERIOD_ID",
              "title": "First Semester",
              "start_date": {
                "day": 1,
                "month": 9,
                "year": 2023
              },
              "end_date": {
                "day": 15,
                "month": 12,
                "year": 2023
              }
            },
            {
              "id": "SECOND_SEMESTER_GRADING_PERIOD_ID",
              "title": "Second Semester",
              "start_date": {
                "day": 15,
                "month": 1,
                "year": 2024
              },
              "end_date": {
                "day": 31,
                "month": 5,
                "year": 2024
              }
            }
          ]
        }

        gradingPeriodSettings = classroom.courses().updateGradingPeriodSettings(
          courseId=course_id, body=body, updateMask='gradingPeriods',
          previewVersion="V1_20240401_PREVIEW").execute()
        return gradingPeriodSettings

    except HttpError as error:
        # Handle errors as appropriate for your application.
        print(f"An error occurred: {error}")
        return error

管理 CourseWork 的 gradingPeriodId 欄位

CourseWork 資源包含 gradingPeriodId 欄位。您可以使用 CourseWork 端點讀取及寫入與 CourseWork 相關聯的評分期間。您可以透過三種方式管理這項關聯:

  • 自動根據日期建立評分期間關聯
  • 自訂相關評分週期
  • 沒有評分週期關聯

1. 以日期為依據的評分週期關聯

建立課程作業時,您可以讓 Classroom 為您處理評分期間的關聯。如要這麼做,請在 CourseWork 要求中省略 gradingPeriodId 欄位。接著,請在 CourseWork 要求中指定 dueDatescheduledTime 欄位。如果 dueDate 落在現有評分期間的日期範圍內,Classroom 會在 CourseWork 上設定該評分期間 ID。如果未指定 dueDate 欄位,Classroom 會根據 scheduledTime 欄位判斷 gradingPeriodId。如果未指定這兩個欄位,或是沒有符合的評分期間日期範圍,系統就不會在 CourseWork 上設定 gradingPeriodId

2. 自訂相關評分週期

如果您想將 CourseWork 與與 dueDatescheduledTime 對應的不同評分期間建立關聯,可以在建立或更新 CourseWork 時手動設定 gradingPeriodId 欄位。如果您手動設定 gradingPeriodId,Classroom 就不會自動根據日期建立評分期間關聯。

3. 未關聯評分週期

如果您不希望 CourseWork 與任何評分期間建立關聯,請將 CourseWork 要求中的 gradingPeriodId 欄位設為空字串 (gradingPeriodId: "")。

如果繳交日期更新後,評分期間 ID 會發生什麼情況?

如果您要更新 CourseWork dueDate 欄位,且想保留自訂或無評分期間的關聯,請在 updateMask 和要求主體中加入 dueDategradingPeriodId。這會告訴 Classroom 不要使用與新 dueDate 相符的評分期間覆寫 gradingPeriodId

Python

body = {
  "dueDate": {
    "month": 6,
    "day": 10,
    "year": 2024
  },
  "dueTime": {
    "hours": 7
  },
  "gradingPeriodId": "<INSERT-GRADING-PERIOD-ID-OR-EMPTY-STRING>"
}
courseWork = classroom.courses().courseWork().patch(
  courseId=course_id, id=coursework_id, body=body,
  updateMask='dueDate,dueTime,gradingPeriodId', # include the gradingPeriodId field in the updateMask
  previewVersion="V1_20240401_PREVIEW").execute()