Gérer CourseWork

L'application Classroom accepte trois types d'éléments de flux : CourseWork, CourseWorkMaterials et Announcements. Ce guide explique comment gérer CourseWork, mais les API pour tous les éléments du flux sont similaires. Pour en savoir plus sur les types d'éléments de flux et leurs différences, consultez Ressources de l'API.

La ressource CourseWork représente un devoir qui a été attribué aux élèves d'un cours spécifique, y compris les documents et informations supplémentaires, comme la date limite ou la note maximale. Il existe quatre sous-types de CourseWork : devoirs, questionnaires, questions à réponse courte et questions à choix multiples. L'API Classroom est compatible avec trois de ces sous-types : devoirs, questions à réponse courte et questions à choix multiples. Ces types sont représentés par le champ CourseWork.workType.

En plus de la ressource CourseWork, vous pouvez gérer les tâches terminées avec la ressource StudentSubmission.

Créer un devoir

Les CourseWork ne peuvent être créés qu'au nom de l'enseignant du cours. Toute tentative de création d'un CourseWork au nom d'un élève ou d'un administrateur de domaine qui n'est pas un enseignant du cours génère une erreur PERMISSION_DENIED. Pour en savoir plus sur les différents rôles dans Classroom, consultez Types d'utilisateurs.

Lorsque vous créez CourseWork à l'aide de la méthode courses.courseWork.create, vous pouvez associer des liens en tant que materials, comme indiqué dans l'exemple de code ci-dessous :

Java

classroom/snippets/src/main/java/CreateCourseWork.java
CourseWork courseWork = null;
try {
  // Create a link to add as a material on course work.
  Link articleLink =
      new Link()
          .setTitle("SR-71 Blackbird")
          .setUrl("https://www.lockheedmartin.com/en-us/news/features/history/blackbird.html");

  // Create a list of Materials to add to course work.
  List<Material> materials = Arrays.asList(new Material().setLink(articleLink));

  /* Create new CourseWork object with the material attached.
  Set workType to `ASSIGNMENT`. Possible values of workType can be found here:
  https://developers.google.com/classroom/reference/rest/v1/CourseWorkType
  Set state to `PUBLISHED`. Possible values of state can be found here:
  https://developers.google.com/classroom/reference/rest/v1/courses.courseWork#courseworkstate */
  CourseWork content =
      new CourseWork()
          .setTitle("Supersonic aviation")
          .setDescription(
              "Read about how the SR-71 Blackbird, the world’s fastest and "
                  + "highest-flying manned aircraft, was built.")
          .setMaterials(materials)
          .setWorkType("ASSIGNMENT")
          .setState("PUBLISHED");

  courseWork = service.courses().courseWork().create(courseId, content).execute();

  /* Prints the created courseWork. */
  System.out.printf("CourseWork created: %s\n", courseWork.getTitle());
} catch (GoogleJsonResponseException e) {
  // TODO (developer) - handle error appropriately
  GoogleJsonError error = e.getDetails();
  if (error.getCode() == 404) {
    System.out.printf("The courseId does not exist: %s.\n", courseId);
  } else {
    throw e;
  }
  throw e;
} catch (Exception e) {
  throw e;
}
return courseWork;

Python

classroom/snippets/classroom_create_coursework.py
import google.auth
from googleapiclient.discovery import build
from googleapiclient.errors import HttpError


def classroom_create_coursework(course_id):
  """
  Creates the coursework the user has access to.
  Load pre-authorized user credentials from the environment.
  TODO(developer) - See https://developers.google.com/identity
  for guides on implementing OAuth2 for the application.
  """

  creds, _ = google.auth.default()
  # pylint: disable=maybe-no-member

  try:
    service = build("classroom", "v1", credentials=creds)
    coursework = {
        "title": "Ant colonies",
        "description": """Read the article about ant colonies
                              and complete the quiz.""",
        "materials": [
            {"link": {"url": "http://example.com/ant-colonies"}},
            {"link": {"url": "http://example.com/ant-quiz"}},
        ],
        "workType": "ASSIGNMENT",
        "state": "PUBLISHED",
    }
    coursework = (
        service.courses()
        .courseWork()
        .create(courseId=course_id, body=coursework)
        .execute()
    )
    print(f"Assignment created with ID {coursework.get('id')}")
    return coursework

  except HttpError as error:
    print(f"An error occurred: {error}")
    return error


if __name__ == "__main__":
  # Put the course_id of course whose coursework needs to be created,
  # the user has access to.
  classroom_create_coursework(453686957652)

Les champs title et workType sont obligatoires. Tous les autres sont facultatifs. Si state n'est pas spécifié, CourseWork est créé à l'état brouillon.

Utilisez une ressource Link avec une url cible spécifiée pour inclure des supports associés dans le CourseWork. Classroom récupère automatiquement l'title et l'URL de la miniature (thumbnailUrl). L'API Classroom est également compatible en mode natif avec les ressources Google Drive et YouTube, qui peuvent être incluses de la même manière avec une ressource DriveFile ou YouTubeVideo.

Pour spécifier une date limite, définissez les champs dueDate et dueTime sur l'heure UTC correspondante. La date limite doit être située dans le futur.

La réponse CourseWork inclut un identifiant attribué par le serveur qui peut être utilisé pour référencer l'attribution dans d'autres requêtes API.

Récupérer un devoir

Vous pouvez récupérer CourseWork au nom des élèves et des enseignants du cours correspondant. Vous pouvez également récupérer CourseWork au nom des administrateurs de domaine, même s'ils ne sont pas enseignants dans le cours. Pour récupérer un CourseWork spécifique, utilisez courses.courseWork.get. Pour récupérer tous les CourseWork (en faisant éventuellement correspondre certains critères), utilisez courses.courseWork.list.

Le niveau d'accès requis dépend du rôle de l'utilisateur qui en fait la demande dans le cours. Si l'utilisateur est un élève, utilisez l'un des champs d'application suivants :

  • https://www.googleapis.com/auth/classroom.coursework.me.readonly
  • https://www.googleapis.com/auth/classroom.coursework.me

Si l'utilisateur est un enseignant ou un administrateur de domaine, utilisez l'un des champs d'application suivants :

  • https://www.googleapis.com/auth/classroom.coursework.students.readonly
  • https://www.googleapis.com/auth/classroom.coursework.students

L'autorisation de récupérer un CourseWork n'implique pas l'autorisation d'accéder aux supports ou à leurs métadonnées. En pratique, cela signifie qu'un administrateur peut ne pas voir le titre d'un fichier Drive joint s'il n'est pas membre du cours.

Gérer les réponses des élèves

Une ressource StudentSubmission représente le travail effectué par un élève pour un CourseWork. La ressource inclut des métadonnées liées au devoir, telles que son état et sa note. Un StudentSubmission est créé de manière implicite pour chaque élève lorsqu'un nouveau CourseWork est créé.

Les sections suivantes expliquent les actions courantes permettant de gérer les réponses des élèves.

Récupérer les réponses des élèves

Les élèves peuvent récupérer leurs propres devoirs, les enseignants peuvent récupérer les devoirs de tous les élèves de leurs cours et les administrateurs de domaine peuvent récupérer tous les devoirs de tous les élèves de leur domaine. Chaque StudentSubmission se voit attribuer un identifiant. Si vous connaissez l'identifiant, utilisez courses.courseWork.studentSubmissions.get pour récupérer l'envoi.

Utilisez la méthode courses.courseWork.studentSubmissions.list pour obtenir toutes les ressources StudentSubmission qui correspondent à certains critères, comme indiqué dans l'exemple suivant :

Java

classroom/snippets/src/main/java/ListSubmissions.java
List<StudentSubmission> studentSubmissions = new ArrayList<>();
String pageToken = null;

try {
  do {
    ListStudentSubmissionsResponse response =
        service
            .courses()
            .courseWork()
            .studentSubmissions()
            .list(courseId, courseWorkId)
            .setPageToken(pageToken)
            .execute();

    /* Ensure that the response is not null before retrieving data from it to avoid errors. */
    if (response.getStudentSubmissions() != null) {
      studentSubmissions.addAll(response.getStudentSubmissions());
      pageToken = response.getNextPageToken();
    }
  } while (pageToken != null);

  if (studentSubmissions.isEmpty()) {
    System.out.println("No student submission found.");
  } else {
    for (StudentSubmission submission : studentSubmissions) {
      System.out.printf(
          "Student id (%s), student submission id (%s)\n",
          submission.getUserId(), submission.getId());
    }
  }
} catch (GoogleJsonResponseException e) {
  // TODO (developer) - handle error appropriately
  GoogleJsonError error = e.getDetails();
  if (error.getCode() == 404) {
    System.out.printf(
        "The courseId (%s) or courseWorkId (%s) does not exist.\n", courseId, courseWorkId);
  } else {
    throw e;
  }
} catch (Exception e) {
  throw e;
}
return studentSubmissions;

Python

classroom/snippets/classroom_list_submissions.py
import google.auth
from googleapiclient.discovery import build
from googleapiclient.errors import HttpError


def classroom_list_submissions(course_id, coursework_id):
  """
  Creates the courses the user has access to.
  Load pre-authorized user credentials from the environment.
  TODO(developer) - See https://developers.google.com/identity
  for guides on implementing OAuth2 for the application.
  """

  creds, _ = google.auth.default()
  # pylint: disable=maybe-no-member
  submissions = []
  page_token = None

  try:
    service = build("classroom", "v1", credentials=creds)
    while True:
      coursework = service.courses().courseWork()
      response = (
          coursework.studentSubmissions()
          .list(
              pageToken=page_token,
              courseId=course_id,
              courseWorkId=coursework_id,
              pageSize=10,
          )
          .execute()
      )
      submissions.extend(response.get("studentSubmissions", []))
      page_token = response.get("nextPageToken", None)
      if not page_token:
        break

    if not submissions:
      print("No student submissions found.")

    print("Student Submissions:")
    for submission in submissions:
      print(
          "Submitted at:"
          f"{(submission.get('id'), submission.get('creationTime'))}"
      )

  except HttpError as error:
    print(f"An error occurred: {error}")
    submissions = None
  return submissions


if __name__ == "__main__":
  # Put the course_id and coursework_id of course whose list needs to be
  # submitted.
  classroom_list_submissions(453686957652, 466086979658)

Récupérez les ressources StudentSubmission appartenant à un élève spécifique en spécifiant le paramètre userId, comme illustré dans l'exemple suivant :

Java

classroom/snippets/src/main/java/ListStudentSubmissions.java
List<StudentSubmission> studentSubmissions = new ArrayList<>();
String pageToken = null;

try {
  do {
    // Set the userId as a query parameter on the request.
    ListStudentSubmissionsResponse response =
        service
            .courses()
            .courseWork()
            .studentSubmissions()
            .list(courseId, courseWorkId)
            .setPageToken(pageToken)
            .set("userId", userId)
            .execute();

    /* Ensure that the response is not null before retrieving data from it to avoid errors. */
    if (response.getStudentSubmissions() != null) {
      studentSubmissions.addAll(response.getStudentSubmissions());
      pageToken = response.getNextPageToken();
    }
  } while (pageToken != null);

  if (studentSubmissions.isEmpty()) {
    System.out.println("No student submission found.");
  } else {
    for (StudentSubmission submission : studentSubmissions) {
      System.out.printf("Student submission: %s.\n", submission.getId());
    }
  }

Python

classroom/snippets/classroom_list_student_submissions.py
import google.auth
from googleapiclient.discovery import build
from googleapiclient.errors import HttpError


def classroom_list_student_submissions(course_id, coursework_id, user_id):
  """
  Creates the courses the user has access to.
  Load pre-authorized user credentials from the environment.
  TODO(developer) - See https://developers.google.com/identity
  for guides on implementing OAuth2 for the application.
  """

  creds, _ = google.auth.default()
  # pylint: disable=maybe-no-member
  submissions = []
  page_token = None

  try:
    service = build("classroom", "v1", credentials=creds)
    while True:
      coursework = service.courses().courseWork()
      response = (
          coursework.studentSubmissions()
          .list(
              pageToken=page_token,
              courseId=course_id,
              courseWorkId=coursework_id,
              userId=user_id,
          )
          .execute()
      )
      submissions.extend(response.get("studentSubmissions", []))
      page_token = response.get("nextPageToken", None)
      if not page_token:
        break

    if not submissions:
      print("No student submissions found.")

    print("Student Submissions:")
    for submission in submissions:
      print(
          "Submitted at:"
          f"{(submission.get('id'), submission.get('creationTime'))}"
      )

  except HttpError as error:
    print(f"An error occurred: {error}")
  return submissions


if __name__ == "__main__":
  # Put the course_id, coursework_id and user_id of course whose list needs
  # to be submitted.
  classroom_list_student_submissions(453686957652, 466086979658, "me")

Les élèves sont identifiés par leur ID unique ou leur adresse e-mail, comme indiqué dans la ressource Student. L'utilisateur actuel peut également faire référence à son propre ID à l'aide du raccourci "me".

Il est également possible de récupérer les devoirs de tous les élèves pour tous les devoirs d'un cours. Pour ce faire, utilisez le littéral "-" comme courseWorkId, comme indiqué dans l'exemple suivant :

Java

service.courses().courseWork().studentSubmissions()
    .list(courseId, "-")
    .set("userId", userId)
    .execute();

Python

service.courses().courseWork().studentSubmissions().list(
    courseId=<course ID or alias>,
    courseWorkId='-',
    userId=<user ID>).execute()

Le niveau d'accès requis dépend du rôle de l'utilisateur qui en fait la demande dans le cours. Si l'utilisateur est un enseignant ou un administrateur de domaine, utilisez le champ d'application suivant :

  • https://www.googleapis.com/auth/classroom.coursework.students.readonly
  • https://www.googleapis.com/auth/classroom.coursework.students

Si l'utilisateur est un élève, utilisez le champ d'application suivant :

  • https://www.googleapis.com/auth/classroom.coursework.me.readonly
  • https://www.googleapis.com/auth/classroom.coursework.me

Le fait d'être autorisé à récupérer un StudentSubmission n'implique pas d'être autorisé à accéder aux pièces jointes ni à leurs métadonnées. En pratique, cela signifie qu'un administrateur peut ne pas voir le titre d'un fichier Drive joint s'il n'est pas membre du cours.

Ajouter des pièces jointes à une réponse d'élève

Vous pouvez joindre des liens à un devoir d'élève en joignant une ressource Link, DriveFile ou YouTubeVideo. Pour ce faire, utilisez courses.courseWork.studentSubmissions.modifyAttachments, comme indiqué dans l'exemple suivant :

Java

classroom/snippets/src/main/java/ModifyAttachmentsStudentSubmission.java
StudentSubmission studentSubmission = null;
try {
  // Create ModifyAttachmentRequest object that includes a new attachment with a link.
  Link link = new Link().setUrl("https://en.wikipedia.org/wiki/Irrational_number");
  Attachment attachment = new Attachment().setLink(link);
  ModifyAttachmentsRequest modifyAttachmentsRequest =
      new ModifyAttachmentsRequest().setAddAttachments(Arrays.asList(attachment));

  // The modified studentSubmission object is returned with the new attachment added to it.
  studentSubmission =
      service
          .courses()
          .courseWork()
          .studentSubmissions()
          .modifyAttachments(courseId, courseWorkId, id, modifyAttachmentsRequest)
          .execute();

  /* Prints the modified student submission. */
  System.out.printf(
      "Modified student submission attachments: '%s'.\n",
      studentSubmission.getAssignmentSubmission().getAttachments());
} catch (GoogleJsonResponseException e) {
  // TODO (developer) - handle error appropriately
  GoogleJsonError error = e.getDetails();
  if (error.getCode() == 404) {
    System.out.printf(
        "The courseId (%s), courseWorkId (%s), or studentSubmissionId (%s) does "
            + "not exist.\n",
        courseId, courseWorkId, id);
  } else {
    throw e;
  }
} catch (Exception e) {
  throw e;
}
return studentSubmission;

Python

classroom/snippets/classroom_add_attachment.py
def classroom_add_attachment(course_id, coursework_id, submission_id):
  """
  Adds attachment to existing course with specific course_id.
  Load pre-authorized user credentials from the environment.
  TODO(developer) - See https://developers.google.com/identity
  for guides on implementing OAuth2 for the application.
  """
  creds, _ = google.auth.default()
  # pylint: disable=maybe-no-member
  request = {
      "addAttachments": [
          {"link": {"url": "http://example.com/quiz-results"}},
          {"link": {"url": "http://example.com/quiz-reading"}},
      ]
  }

  try:
    service = build("classroom", "v1", credentials=creds)
    while True:
      coursework = service.courses().courseWork()
      coursework.studentSubmissions().modifyAttachments(
          courseId=course_id,
          courseWorkId=coursework_id,
          id=submission_id,
          body=request,
      ).execute()

  except HttpError as error:
    print(f"An error occurred: {error}")


if __name__ == "__main__":
  # Put the course_id, coursework_id and submission_id of course in which
  # attachment needs to be added.
  classroom_add_attachment("course_id", "coursework_id", "me")

Une pièce jointe Link est définie par la cible url. Classroom récupère automatiquement le title et la miniature (thumbnailUrl). Pour en savoir plus sur les supports pouvant être joints à StudentSubmissions, consultez Material.

Seul un enseignant du cours ou l'élève qui en est propriétaire peut modifier le StudentSubmission. Vous ne pouvez associer Materials que si le CourseWorkType de StudentSubmission est ASSIGNMENT.

Le niveau d'accès requis dépend du rôle de l'utilisateur qui en fait la demande dans le cours. Si l'utilisateur est un enseignant, utilisez le champ d'application suivant :

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

Si l'utilisateur est un élève, utilisez le champ d'application suivant :

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