Administra el trabajo del curso y las calificaciones

La IU de Classroom admite cinco tipos de trabajo en clase: Tareas, Tareas con cuestionario, preguntas de respuesta corta, preguntas de opción múltiple y Materiales. Actualmente, la API de Classroom admite tres de estos tipos, que se conocen como CourseWorkType para la API: Tareas, Respuesta breve preguntas de opción múltiple y de opción múltiple.

Para acceder a esta función, puedes usar la Recurso de CourseWork, que representa una tarea o una pregunta que se asignó a los estudiantes en un curso en particular, incluidos los materiales y detalles adicionales, como plazos fecha o puntuación máxima.

Además del recurso CourseWork, puedes administrar las tareas completadas. con el recurso StudentSubmission. En las siguientes secciones, se describen estos en más detalle.

Cómo crear tareas

Las tareas solo se pueden crear en nombre de los profesores del curso y intentar crear tareas en un curso en nombre de un estudiante tendrá como resultado en un error 403 PERMISSION_DENIED. Los administradores de dominio tampoco pueden crear tareas para cursos que no enseñan y que intentan hacerlo a través de la API también generará un error 403 PERMISSION_DENIED.

Cuando creas tareas con el método courses.courseWork.create, puedes adjuntar vínculos como materials, como se muestra en el siguiente código de ejemplo:

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)

El resultado incluye un identificador asignado por el servidor que se puede usar como referencia la asignación en otras solicitudes a la API.

Para incluir materiales vinculados en una tarea creada con la API de Classroom, sigue estos pasos: usa un Recurso de vínculo que especifique la URL de destino. Classroom recupera automáticamente el título y la imagen de la miniatura. La API de Classroom también es compatible de forma nativa con los materiales de Google Drive y YouTube, que pueden Se incluyen con un recurso DriveFile o recurso YouTubeVideo de forma similar de una nueva manera.

Para especificar una fecha límite, configura los campos dueDate y dueTime de la siguiente manera: hora UTC correspondiente. La fecha límite debe ser futura.

Recuperar tareas y preguntas

Puedes recuperar tareas y preguntas para los estudiantes y profesores de la el curso correspondiente o el administrador de un dominio. Para recuperar un bucket tarea o pregunta, usa courses.courseWork.get. Para recuperar todas tareas o preguntas (que, de manera opcional, coincidan con algunos criterios), usa courses.courseWork.list.

El permiso requerido depende del rol que tenga el usuario solicitante en la en este curso. Si el usuario es estudiante, usa uno de los siguientes alcances:

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

Si el usuario es profesor o administrador de dominio, utiliza una de las siguientes opciones alcances:

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

Tener permiso para recuperar una tarea o pregunta no implica permisos para acceder a materiales o metadatos de materiales. En la práctica, esto significa es posible que un administrador no vea el título de un archivo adjunto de Drive si que no es miembro del curso. Si quieres permitir que los administradores accedan a consulta la documentación de información del dominio delegación .

Administra las respuestas de los estudiantes

Un objeto StudentSubmission “Recurso” representa el trabajo realizado y la calificación de un estudiante para una tarea o pregunta. Un objeto StudentSubmission recurso se crea implícitamente para cada estudiante cuando se crea una nueva pregunta o se crea la asignación.

En las siguientes secciones, se explican las acciones comunes relacionadas con las respuestas de los alumnos.

Recupera las respuestas de los estudiantes

Los alumnos pueden recuperar sus propias entregas y los profesores pueden recuperarlas. para todos los estudiantes de sus cursos, y los administradores de dominios pueden las entregas para todos los estudiantes de su dominio. Cada entrega de un estudiante Se le asignó un identificador. si conoces el identificador, usa courses.courseWork.studentSubmissions.get para recuperarla.

Usa el método courses.courseWork.studentSubmissions.list para obtener StudentSubmission que coinciden con algunos criterios, como se muestra en el siguiente ejemplo:

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)

Recuperar StudentSubmission recursos que pertenecen a un estudiante en particular especifica el parámetro userId, como se muestra en el siguiente ejemplo:

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")

Los estudiantes se identifican con el ID único o la dirección de correo electrónico del usuario, como que devuelve el SDK de Google Admin. El usuario actual también puede referirse a su propio ID con la abreviatura "me"

También es posible recibir las entregas de los estudiantes para todas las tareas de una en este curso. Para hacerlo, usa el "-" literal como courseWorkId, como se muestra en el siguiente ejemplo:

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()

El permiso requerido depende del rol que tenga el usuario solicitante en la en este curso. Usa el siguiente alcance si el usuario es profesor o dominio. administrador:

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

Usa el siguiente alcance si el usuario es estudiante:

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

Tener permiso para recuperar una entrega de un estudiante no implica permisos para acceder a los archivos adjuntos o sus metadatos. En la práctica, esto significa que es posible que un administrador no vea el título de un archivo de Drive adjunto si si no es miembro del curso. Si quieres permitir el acceso de los administradores a los archivos del usuario, consulta la delegación de todo el dominio.

Agregar archivos adjuntos a la respuesta de un estudiante

Puedes adjuntar vínculos a la entrega de un estudiante adjuntando un Link. DriveFile o YouTubeVideo. Esto se hace con courses.courseWork.studentSubmissions.modifyAttachments, como se muestra en la siguiente ejemplo:

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")

Un archivo adjunto de vínculo se define mediante la URL de destino. Classroom automáticamente recupera el título y la imagen en miniatura. Puedes obtener más información sobre el resto de los materiales en sus respectivas páginas de referencia.

Solo el profesor del curso o el usuario pueden modificar la StudentSubmission al estudiante propietario. Solo puedes adjuntar Materials si el elemento El CourseWorkType del envío del estudiante es ASSIGNMENT.

El permiso requerido depende del rol que tenga el usuario solicitante en la en este curso. Usa el siguiente alcance si el usuario es profesor:

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

Usa el siguiente alcance si el usuario es estudiante:

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

Cómo administrar el estado de las respuestas de los alumnos

La respuesta de un estudiante puede anularse, entregarse o devolverse. El campo de estado en StudentSubmission indica el estado actual. Para cambiar el estado, llama a uno de los siguientes métodos:

Todos estos métodos toman un cuerpo vacío. Ejemplo:

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()

Solo el estudiante que posee una StudentSubmission puede entregarla o reclamarla. Solo se puede reclamar una entrega que se haya entregado. Los profesores de cursos solo pueden devolver un StudentSubmission, que tiene el estado entregado

Califica las respuestas de los estudiantes

El recurso StudentSubmission tiene dos campos para almacenar las calificaciones: assignedGrade, que es la calificación que se informó a los estudiantes, y draftGrade, que es una calificación tentativa que solo pueden ver los profesores. Estos campos se actualizan usando courses.courseWork.studentSubmissions.patch con una máscara de campo que contenga los campos adecuados, como se muestra en el siguiente ejemplo.

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()

Cuando trabajan con la IU de Classroom, los profesores no pueden asignar una calificación hasta que primero guardó una calificación preliminar. La calificación asignada se puede devolver a como estudiante. Las aplicaciones deben emular este comportamiento. Tu aplicación puede calificar la tarea de un estudiante de una de estas dos maneras:

  • Asigna solo el draftGrade. Esto es útil, por ejemplo, para que el profesor revisar manualmente las calificaciones antes de finalizarlas. Los estudiantes no pueden ver las calificaciones preliminares.

  • Asigna las draftGrade y la assignedGrade para calificar completamente una tarea.

Enumerar las calificaciones asignadas

Puedes enumerar todas las calificaciones de un elemento de trabajo de curso en particular explorando la Objeto de respuesta del método 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'))}")