Gérer les devoirs et les notes

L'interface utilisateur de Classroom accepte cinq types de travaux et devoirs: Devoirs, les devoirs avec quiz, les questions à réponse courte, les questions à choix multiples et Supports de cours. L'API Classroom est actuellement compatible avec trois de ces types : sont appelées CourseWorkType pour l'API: Devoirs, réponse courte et des questions à choix multiples.

Pour accéder à cette fonctionnalité, vous pouvez utiliser le Ressource CourseWork qui représente un devoir ou une question qui a été attribué aux élèves un cours particulier, y compris tout support ou toute information supplémentaire, comme la la date 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 décrivent plus en détail.

Créer des devoirs

Les devoirs peuvent uniquement être créés au nom du ou des enseignants du cours. tenter de créer des devoirs dans un cours au nom d'un élève aura pour conséquence dans une erreur 403 PERMISSION_DENIED. De même, les administrateurs de domaine ne peuvent pas non plus créer devoirs pour les cours qu'il n'enseigne pas et qui tentent de le faire via l'API génère également une erreur 403 PERMISSION_DENIED.

Lorsque vous créez des devoirs à l'aide de la méthode courses.courseWork.create, vous pouvez joindre des liens au format materials, comme illustré 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 API.

Pour inclure des supports associés dans un devoir créé via l'API Classroom : utilisez une ressource "Link", en spécifiant l'URL cible. Classroom récupère automatiquement le titre et la vignette. De plus, l'API Classroom est compatible de manière native avec les supports Google Drive et YouTube, ce qui permet dans une ressource DriveFile ; ou ressource YouTubeVideo dans une ressource de la même façon.

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

Récupérer les devoirs et les questions

Vous pouvez récupérer les devoirs et les questions des élèves et des enseignants du cours correspondant ou par un administrateur du domaine. Pour récupérer un type d'un devoir ou d'une question, utilisez courses.courseWork.get. Pour tout récupérer, procédez comme suit : ou questions (correspondant éventuellement à certains critères), utilisez courses.courseWork.list.

<ph type="x-smartling-placeholder">

Le champ d'application requis dépend du rôle de l'utilisateur à l'origine de la demande dans de ce cours. Si l'utilisateur est un élève, utilisez l'une des portées suivantes:

  • 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 éléments suivants : champs d'application:

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

Avoir l'autorisation de récupérer un devoir ou une question n'implique pas autorisations d'accès à des contenus ou à leurs métadonnées. En pratique, cela signifie qu'un administrateur ne voie pas le titre d'un fichier Drive joint s'il n'est pas membre du cours. Pour autoriser les administrateurs à accéder aux comptes consultez la liste des paramètres d'un domaine délégation .

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

Un StudentSubmission ressource représente le travail effectué et la note d'un élève pour un devoir ou cette question. Un StudentSubmission ressource est créée implicitement pour chaque élève lorsqu'une nouvelle question ou l'attribution est créée.

Les sections suivantes décrivent 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 devoirs, et les enseignants pour tous les élèves de leurs cours. De leur côté, les administrateurs du domaine peuvent récupérer les devoirs rendus par tous les élèves de son domaine. Le travail de chaque élève est lui attribuer un identifiant ; si vous connaissez l'identifiant, utilisez courses.courseWork.studentSubmissions.get pour le récupérer.

Utilisez la méthode courses.courseWork.studentSubmissions.list pour obtenir StudentSubmission ressources correspondant à certains critères, comme indiqué dans la 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 StudentSubmission les ressources appartenant à un élève en particulier en 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'identifiant unique ou l'adresse e-mail de l'utilisateur, comme renvoyées par Google Admin SDK. L'utilisateur actuel peut également faire référence à ses propres ID à l'aide du raccourci "me".

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

  • 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

Avoir l'autorisation de récupérer le travail d'un élève n'implique pas autorisations d'accès aux pièces jointes ou aux métadonnées des pièces jointes. En pratique, signifie qu'il est possible qu'un administrateur ne voie pas le titre d'un fichier Drive joint : ils ne sont pas membres du cours. Si vous souhaitez autoriser les administrateurs à accéder aux fichiers utilisateur, consultez la délégation au niveau du domaine.

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

Vous pouvez joindre des liens au devoir d'un élève en joignant un Link, Ressource DriveFile ou YouTubeVideo. Cela se fait avec courses.courseWork.studentSubmissions.modifyAttachments, comme indiqué dans les 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 va automatiquement récupérer le titre et l'image de la miniature. Pour en savoir plus sur les autres supports, consultez la page leurs pages de référence respectives.

Le StudentSubmission ne peut être modifié que par l'enseignant du cours ou par l'élève qui en est le propriétaire. Vous ne pouvez joindre Materials que si le CourseWorkType du devoir 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 de ce 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

Gérer l'état des réponses des élèves

La réponse d'un élève peut être annulée, rendue ou rendue. Le champ État dans StudentSubmission indique l'état actuel. Pour modifier l'état, appelez l'une des méthodes suivantes:

Toutes ces méthodes utilisent un corps vide. Exemple :

Java

classroom/snippets/src/main/java/ReturnStudentSubmission.java
try {
  service
      .courses()
      .courseWork()
      .studentSubmissions()
      .classroomReturn(courseId, courseWorkId, id, null)
      .execute();
} 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;
}

Python

service.courses().courseWork().studentSubmission().turnIn(
    courseId=<course ID or alias>,
    courseWorkId=<courseWork ID>,
    id=<studentSubmission ID>,
    body={}).execute()

Seul l'élève propriétaire d'un StudentSubmission peut le rendre ou le récupérer. Vous ne pouvez récupérer qu'un devoir remis. Les enseignants du cours ne peuvent renvoyer StudentSubmission à l'état remis.

Noter les réponses des élèves

La ressource StudentSubmission comporte deux champs pour stocker les notes: assignedGrade, qui est la note transmise aux élèves, et draftGrade, Il s'agit d'une note provisoire visible uniquement par les enseignants. Ces champs sont mis à jour Utiliser courses.courseWork.studentSubmissions.patch avec un masque de champ contenant les champs appropriés, comme illustré dans l'exemple suivant.

Java

classroom/snippets/src/main/java/PatchStudentSubmission.java
StudentSubmission studentSubmission = null;
try {
  // Updating the draftGrade and assignedGrade fields for the specific student submission.
  StudentSubmission content =
      service
          .courses()
          .courseWork()
          .studentSubmissions()
          .get(courseId, courseWorkId, id)
          .execute();
  content.setAssignedGrade(90.00);
  content.setDraftGrade(80.00);

  // The updated studentSubmission object is returned with the new draftGrade and assignedGrade.
  studentSubmission =
      service
          .courses()
          .courseWork()
          .studentSubmissions()
          .patch(courseId, courseWorkId, id, content)
          .set("updateMask", "draftGrade,assignedGrade")
          .execute();

  /* Prints the updated student submission. */
  System.out.printf(
      "Updated student submission draft grade (%s) and assigned grade (%s).\n",
      studentSubmission.getDraftGrade(), studentSubmission.getAssignedGrade());
} 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

studentSubmission = {
  'assignedGrade': 99,
  'draftGrade': 80
}
service.courses().courseWork().studentSubmissions().patch(
    courseId=<course ID or alias>,
    courseWorkId=<courseWork ID>,
    id=<studentSubmission ID>,
    updateMask='assignedGrade,draftGrade',
    body=studentSubmission).execute()

Dans l'interface utilisateur de Classroom, les enseignants ne peuvent pas attribuer de notes tant qu'ils n'ont pas ont d'abord enregistré une note temporaire. La note attribuée peut ensuite être renvoyée à un élève. Les applications doivent émuler ce comportement. Votre application peut Pour noter le devoir d'un élève, deux possibilités s'offrent à vous:

  • Attribuez uniquement l'élément draftGrade. Cela permet, par exemple, à l'enseignant revoir manuellement les notes avant de les finaliser. Les élèves ne peuvent pas voir les notes temporaires.

  • Attribuez à la fois les draftGrade et les assignedGrade pour noter complètement un devoir.

Lister les notes attribuées

Vous pouvez lister toutes les notes d’un élément de travail particulier en explorant les Objet de réponse de la méthode courses.courseWork.studentSubmissions.list:

Java

classroom/snippets/src/main/java/ListStudentSubmissions.java
  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 submissions found.");
} else {
  for (StudentSubmission submission : studentSubmissions) {
    System.out.printf(
        "User ID %s, Assigned grade: %s\n",
        submission.getUserId(), submission.getAssignedGrade());
  }
}

Python

response = coursework.studentSubmissions().list(
    courseId=course_id,
    courseWorkId=coursework_id,
    pageSize=10).execute()
submissions.extend(response.get('studentSubmissions', []))

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

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