Gérer les documents de travail

L'interface utilisateur de Classroom prend en charge cinq types de travaux et devoirs: devoirs, devoirs sous forme de quiz, questions à réponse courte, questions à choix multiples et supports de cours. L'API Classroom accepte actuellement trois de ces types, appelés CourseWorkType pour l'API: devoirs, questions à réponse courte et questions à choix multiples.

Pour accéder à cette fonctionnalité, vous pouvez utiliser la ressource CourseWork, qui représente un devoir ou une question attribué à des élèves dans un cours particulier, y compris les ressources et les détails supplémentaires, comme la date limite ou le score maximal.

En plus de la ressource CourseWork, vous pouvez gérer les devoirs terminés avec la ressource StudentSubmission. Les sections suivantes les décrivent plus en détail.

Créer des devoirs

Les devoirs ne peuvent être créés que pour le compte de l'un ou des enseignants du cours. Si vous essayez de créer des devoirs dans un cours pour le compte d'un élève, une erreur 403 PERMISSION_DENIED s'affiche. De même, les administrateurs de domaine ne peuvent pas créer de devoirs pour des cours qu'ils n'enseignent pas. Toute tentative de le faire via l'API entraînera également une erreur PERMISSION_DENIED 403.

Lorsque vous créez des devoirs à l'aide de la méthode courses.courseWork.create, vous pouvez joindre 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)

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

Pour inclure des ressources associées dans un devoir créé via l'API Classroom, utilisez une ressource de lien en spécifiant l'URL cible. Classroom récupère automatiquement le titre et l'image miniature. L'API Classroom est également compatible en mode natif avec les supports Google Drive et YouTube, qui peuvent être inclus avec une ressource DriveFile ou une ressource YouTubeVideo de la même manière.

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

Récupérer les devoirs et les questions

Vous pouvez récupérer les devoirs et les questions pour les élèves et les enseignants du cours correspondant ou par un administrateur de domaine. Pour récupérer un devoir ou une question spécifique, utilisez courses.courseWork.get. Pour récupérer tous les devoirs ou toutes les questions (en fonction de certains critères, le cas échéant), utilisez courses.courseWork.list.

Le champ d'application requis dépend du rôle de l'utilisateur demandeur 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'une des portées suivantes:

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

Le fait d'avoir l'autorisation de récupérer un devoir ou une question n'implique pas d'autorisations d'accès aux supports de cours ou aux métadonnées des supports de cours. En pratique, cela signifie qu'un administrateur ne verra peut-être pas le titre d'un fichier Drive joint s'il n'est pas membre du cours. Si vous souhaitez autoriser les administrateurs à accéder aux fichiers utilisateur, consultez le guide sur la délégation au niveau du domaine.

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

Une ressource StudentSubmission représente le travail effectué et la note d'un élève pour un devoir ou une question. Une ressource StudentSubmission est créée implicitement pour chaque élève lorsqu'une question ou un devoir 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 devoir envoyé par un élève reçoit un identifiant. Si vous le connaissez, récupérez-le à l'aide de courses.courseWork.studentSubmissions.get.

Utilisez la méthode courses.courseWork.studentSubmissions.list pour obtenir les ressources StudentSubmission qui répondent à certains critères, comme illustré 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 qui appartiennent à un étudiant particulier 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 l'ID unique ou l'adresse e-mail de l'utilisateur, comme indiqué par le SDK Google Admin. L'utilisateur actuel peut également faire référence à son propre ID à l'aide de l'abréviation "me".

Il est également possible de recevoir les devoirs des élèves pour tous les devoirs d'un cours. Pour ce faire, utilisez la valeur littérale "-" comme courseWorkId, comme illustré 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 champ d'application requis dépend du rôle de l'utilisateur à l'origine de la demande dans le cours. Utilisez le champ d'application suivant si l'utilisateur est un enseignant ou un administrateur de domaine:

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

Utilisez le champ d'application suivant si l'utilisateur est un élève:

  • 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 devoir d'élève n'implique pas d'autorisations d'accéder aux pièces jointes ni aux métadonnées des pièces jointes. En pratique, cela signifie qu'un administrateur ne verra peut-être pas le titre d'un fichier Drive joint s'il n'est pas membre du cours. Si vous souhaitez autoriser les administrateurs à accéder aux fichiers des utilisateurs, consultez le guide sur la délégation au niveau du domaine.

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 illustré 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 de lien est définie par l'URL cible. Classroom extrait automatiquement le titre et l'image miniature. Pour en savoir plus sur les autres documents, consultez leurs pages de référence respectives.

Le StudentSubmission ne peut être modifié que par un enseignant ou par l'élève qui en est le propriétaire. Vous ne pouvez joindre Materials que si la valeur CourseWorkType de l'envoi de l'élève est ASSIGNMENT.

Le champ d'application requis dépend du rôle de l'utilisateur à l'origine de la demande dans le cours. Utilisez le champ d'application suivant si l'utilisateur est un enseignant:

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

Utilisez le champ d'application suivant si l'utilisateur est un élève:

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