Управление курсовой работой

Приложение Classroom поддерживает три типа элементов потока: CourseWork , CourseWorkMaterials и Announcements . В этом руководстве описывается, как управлять CourseWork , но API для всех элементов потока одинаковы. См. ресурсы API , чтобы узнать больше о типах элементов потока и их различиях.

Ресурс CourseWork представляет собой рабочий элемент, назначенный учащимся определенного курса, включая любые дополнительные материалы и сведения, такие как срок сдачи или максимальный балл. Существует четыре подтипа CourseWork : задания , тестовые задания , вопросы с короткими ответами и вопросы с несколькими вариантами ответов . API Класса поддерживает три из этих подтипов: задания, вопросы с коротким ответом и вопросы с несколькими вариантами ответов. Эти типы представлены полем CourseWork.workType .

Помимо ресурса CourseWork , вы можете управлять выполненной работой с помощью ресурса StudentSubmission .

Создать курсовую работу

CourseWork может быть создан только от имени преподавателя курса. Попытка создать CourseWork от имени учащегося или администратора домена, который не является преподавателем курса, приводит к ошибке PERMISSION_DENIED . Ознакомьтесь с типами пользователей , чтобы узнать больше о различных ролях в Классе.

При создании CourseWork с помощью courses.courseWork.create вы можете прикреплять ссылки в качестве materials , как показано в примере кода ниже:

Ява

класс/фрагменты/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;

Питон

класс/фрагменты/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)

Поля title и workType являются обязательными. Все остальные поля являются необязательными. Если state не указано, CourseWork создается в состоянии черновика.

Используйте ресурс Link с указанным целевым url , чтобы включить связанные материалы в CourseWork . Класс автоматически получает URL-адрес title и миниатюры изображения ( thumbnailUrl ). API Classroom также изначально поддерживает материалы Google Диска и YouTube, которые можно аналогичным образом включить в ресурс DriveFile или ресурс YouTubeVideo .

Чтобы указать дату выполнения, установите в полях dueDate и dueTime соответствующее время в формате UTC. Срок исполнения должен быть в будущем.

Ответ CourseWork включает назначенный сервером идентификатор, который можно использовать для ссылки на назначение в других запросах API.

Получить курсовую работу

Вы можете получить CourseWork от имени студентов и преподавателей соответствующего курса. Вы также можете получить CourseWork от имени администраторов домена, даже если они не являются преподавателями курса. Чтобы получить конкретный CourseWork , используйте courses.courseWork.get . Чтобы получить все CourseWork (необязательно соответствующие некоторым критериям), courses.courseWork.list .

Требуемая область зависит от роли, которую запрашивающий пользователь имеет в курсе. Если пользователь является студентом, используйте одну из следующих областей:

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

Если пользователь является учителем или администратором домена, используйте одну из следующих областей:

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

Наличие разрешения на получение CourseWork не подразумевает разрешения на доступ к материалам или метаданным материалов. На практике это означает, что администратор может не видеть название прикрепленного файла на Диске, если он не является участником курса.

Управляйте ответами учащихся

Ресурс StudentSubmission представляет работу, выполненную студентом для CourseWork . Ресурс включает метаданные, связанные с работой, такие как статус и оценка работы. StudentSubmission неявно создается для каждого учащегося при создании новой CourseWork .

В следующих разделах описаны общие действия по управлению ответами учащихся.

Получить ответы учащихся

Учащиеся могут получать свои собственные материалы, преподаватели могут получать материалы всех учащихся своих курсов, а администраторы домена могут получать все материалы всех учащихся в своем домене. Каждому StudentSubmission присваивается идентификатор. courses.courseWork.studentSubmissions.get вы знаете идентификатор, используйтеcourseWork.studentSubmissions.get для получения отправленного материала.

Используйте метод courses.courseWork.studentSubmissions.list , чтобы получить все ресурсы StudentSubmission , соответствующие некоторым критериям, как показано в следующем примере:

Ява

класс/фрагменты/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;

Питон

класс/фрагменты/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)

Получите ресурсы StudentSubmission , принадлежащие конкретному учащемуся, указав параметр userId , как показано в следующем примере:

Ява

класс/фрагменты/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());
    }
  }

Питон

класс/фрагменты/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")

Студенты идентифицируются по уникальному идентификатору или адресу электронной почты, представленному в ресурсе Student . Текущий пользователь также может ссылаться на свой собственный идентификатор, используя сокращение "me" .

Также можно получить работы учащихся по всем заданиям курса. Для этого используйте литерал "-" в качестве courseWorkId , как показано в следующем примере:

Ява

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

Питон

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

Требуемая область зависит от роли, которую запрашивающий пользователь имеет в курсе. Если пользователь является учителем или администратором домена, используйте следующую область:

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

Если пользователь является студентом, используйте следующую область:

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

Наличие разрешения на получение StudentSubmission не подразумевает разрешения на доступ к вложениям или метаданным вложений. На практике это означает, что администратор может не видеть название прикрепленного файла на Диске, если он не является участником курса.

Добавление вложений к ответу учащегося

Вы можете прикрепить ссылки к материалам учащихся, прикрепив ресурс Link , DriveFile или YouTubeVideo . Это делается с помощью courses.courseWork.studentSubmissions.modifyAttachments , как показано в следующем примере:

Ява

класс/фрагменты/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;

Питон

класс/фрагменты/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")

Вложение Link определяется целевым url ; Класс автоматически извлекает title и миниатюру ( thumbnailUrl ). См. Material , чтобы узнать о материалах, которые можно прикрепить к StudentSubmissions .

StudentSubmission может быть изменен только преподавателем курса или студентом, которому он принадлежит. Вы можете прикреплять Materials только в том случае, если CourseWorkType объекта StudentSubmission имеет значение ASSIGNMENT .

Требуемая область зависит от роли, которую запрашивающий пользователь имеет в курсе. Если пользователь является учителем, используйте следующую область:

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

Если пользователь является студентом, используйте следующую область:

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