Anexos de tipo de atividade

Este é o quinto tutorial da série de instruções de complementos do Google Sala de Aula.

Neste tutorial, você vai modificar o exemplo da etapa anterior para produzir um anexo de tipo de atividade. Esses são os anexos que exigem o envio do estudante, como uma resposta por escrito, um teste ou outro artefato gerado pelo estudante.

A distinção entre os anexos do tipo de conteúdo e de atividade é importante. Anexos de tipo de atividade diferem de tipo de conteúdo das seguintes maneiras:

  • Um botão "Entregar" é exibido no canto superior direito do iframe da visualização do estudante.
  • Eles fornecem um identificador exclusivo para o trabalho do estudante.
  • O card de anexo aparece na interface de notas do Google Sala de Aula.
  • Eles podem dar uma nota para a atividade à qual pertencem.

Consulte o próximo tutorial para saber mais sobre a avaliação. Neste tutorial, você concluirá o seguinte:

  • Modifique as solicitações anteriores de criação de anexo para a API Classroom para criar um anexo de tipo de atividade.
  • Implementar um armazenamento permanente para os envios dos estudantes.
  • Modifique o trajeto anterior "Visualização de estudante" para aceitar as entradas dele.
  • Indique uma rota para disponibilizar o iframe "Revisão dos trabalhos dos alunos".

Depois de terminar, você poderá criar anexos do tipo atividade em atividades na interface do Google Sala de Aula quando fizer login como professor. Os estudantes da turma também podem concluir a atividade no iframe e enviar uma resposta. O professor pode ver o trabalho enviado pelo aluno na interface de avaliação do Google Sala de Aula.

Para este exemplo, reutilize o modelo de anexo do tutorial anterior, que mostra a imagem de um ponto de referência famoso e uma legenda com o nome dele. A atividade consiste em pedir que o estudante dê o nome do ponto de referência.

Modificar a solicitação de criação de anexo

Navegue até a seção do código em que você criou um anexo de tipo de conteúdo no tutorial anterior. O item-chave aqui é uma instância de um objeto AddOnAttachment, em que já especificamos teacherViewUri, studentViewUri e title para o anexo.

Embora todos os anexos de complementos exijam esses três campos, a presença ou ausência de um studentWorkReviewUri determina se o anexo é do tipo de atividade ou de conteúdo. Uma solicitação CREATE com um studentWorkReviewUri preenchido se torna um anexo de tipo de atividade, enquanto uma solicitação CREATE sem um studentWorkReviewUri se torna um anexo de tipo de conteúdo.

A única modificação a fazer nessa solicitação é preencher o campo studentWorkReviewUri. Adicione uma rota com nome apropriado aqui. Você a implementará em uma etapa posterior.

Python

No exemplo fornecido, isso está no método create_attachments no arquivo webapp/attachment_routes.py.

attachment = {
    # Specifies the route for a teacher user.
    "teacherViewUri": {
        "uri":
            flask.url_for(
                "load_activity_attachment",
                _scheme='https',
                _external=True),
    },
    # Specifies the route for a student user.
    "studentViewUri": {
        "uri":
            flask.url_for(
                "load_activity_attachment",
                _scheme='https',
                _external=True)
    },
    # Specifies the route for a teacher user when the attachment is
    # loaded in the Classroom grading view.
    # The presence of this field marks this as an activity-type attachment.
    "studentWorkReviewUri": {
        "uri":
            flask.url_for(
                "view_submission", _scheme='https', _external=True)
    },
    # The title of the attachment.
    "title": f"Attachment {attachment_count}",
}

Adicionar armazenamento permanente para anexos de tipo de conteúdo

Registrar a resposta do estudante à nossa atividade. É possível procurá-lo mais tarde, quando o professor visualizar o envio no iframe "Revisão dos trabalhos dos alunos".

Configure um esquema de banco de dados para um Submission. No exemplo fornecido, os estudantes precisam inserir o nome do ponto de referência mostrado em uma imagem. Portanto, um Submission contém os seguintes atributos:

  • attachment_id: um identificador exclusivo para um anexo. Atribuído pelo Google Sala de Aula e retornado na resposta ao criar um anexo.
  • submission_id: identificador do envio de um estudante. Atribuído pelo Google Sala de Aula e retornado na resposta getAddOnContext da visualização do estudante.
  • student_response: a resposta fornecida pelo estudante.

Python

Estenda a implementação do SQLite e da flask_sqlalchemy das etapas anteriores.

Navegue até o arquivo em que você definiu as tabelas anteriores (models.py se estiver seguindo o exemplo fornecido). Adicione o seguinte na parte inferior do arquivo:

# Database model to represent a student submission.
class Submission(db.Model):
    # The attachmentId is the unique identifier for the attachment.
    submission_id = db.Column(db.String(120), primary_key=True)

    # The unique identifier for the student's submission.
    attachment_id = db.Column(db.String(120), primary_key=True)

    # The student's response to the question prompt.
    student_response = db.Column(db.String(120))

Importe a nova classe Submission para o arquivo do servidor com as rotas de processamento de anexos.

Modificar o trajeto da visualização de estudantes

Em seguida, modifique o trajeto anterior "Visualização do estudante" para mostrar um pequeno formulário e aceitar a entrada do aluno. É possível reutilizar a maior parte do código do tutorial anterior.

Localize o código de servidor que fornece o trajeto para o Student View. Essa é a rota especificada no campo studentViewUri ao criar um anexo. A primeira mudança a ser feita é extrair o submissionId da resposta getAddOnContext.

Python

No exemplo fornecido, isso está no método load_activity_attachment no arquivo webapp/attachment_routes.py.

# Issue a request to the courseWork.getAddOnContext endpoint
addon_context_response = classroom_service.courses().courseWork(
).getAddOnContext(
    courseId=flask.session["courseId"],
    itemId=flask.session["itemId"]).execute()

# One of studentContext or teacherContext will be populated.
user_context = "student" if addon_context_response.get(
    "studentContext") else "teacher"

# If the user is a student...
if user_context == "student":
    # Extract the submissionId from the studentContext object.
    # This value is provided by Google Classroom.
    flask.session["submissionId"] = addon_context_response.get(
            "studentContext").get("submissionId")

Você também pode enviar uma solicitação para verificar o status de envio do estudante. A resposta contém um valor SubmissionState, que indica, por exemplo, se o estudante abriu ou entregou o anexo. Isso pode ser útil se você quiser proibir edições em um envio entregue ou se tiver interesse em fornecer insights de professor sobre o progresso dos alunos:

Python

No exemplo fornecido, isso é uma continuação do método load_activity_attachment acima.

# Issue a request to get the status of the student submission.
submission_response = classroom_service.courses().courseWork(
).addOnAttachments().studentSubmissions().get(
    courseId=flask.session["courseId"],
    itemId=flask.session["itemId"],
    attachmentId=flask.session["attachmentId"],
    submissionId=flask.session["submissionId"]).execute()

Por fim, busque as informações do anexo do nosso banco de dados e disponibilize um formulário de entrada. O formulário no exemplo fornecido consiste em um campo de entrada de string e um botão de envio. Mostre a imagem do ponto de referência e peça para o estudante digitar o nome dela. Assim que ele responder, registre em nosso banco de dados.

Python

No exemplo fornecido, isso é uma continuação do método load_activity_attachment acima.

# Look up the attachment in the database.
attachment = Attachment.query.get(flask.session["attachmentId"])

message_str = f"I see that you're a {user_context}! "
message_str += (
    f"I've loaded the attachment with ID {attachment.attachment_id}. "
    if user_context == "teacher" else
    "Please complete the activity below.")

form = activity_form_builder()

if form.validate_on_submit():
    # Record the student's response in our database.

    # Check if the student has already submitted a response.
    # If so, update the response stored in the database.
    student_submission = Submission.query.get(flask.session["submissionId"])

    if student_submission is not None:
        student_submission.student_response = form.student_response.data
    else:
        # Store the student's response by the submission ID.
        new_submission = Submission(
            submission_id=flask.session["submissionId"],
            attachment_id=flask.session["attachmentId"],
            student_response=form.student_response.data)
        db.session.add(new_submission)

    db.session.commit()

    return flask.render_template(
        "acknowledge-submission.html",
        message="Your response has been recorded. You can close the " \
            "iframe now.",
        instructions="Please Turn In your assignment if you have " \
            "completed all tasks."
    )

# Show the activity.
return flask.render_template(
    "show-activity-attachment.html",
    message=message_str,
    image_filename=attachment.image_filename,
    image_caption=attachment.image_caption,
    user_context=user_context,
    form=form,
    responses=response_strings)

Para diferenciar os usuários, desative a função de envio e mostre a resposta correta na Visualização de professor.

Adicionar uma rota para o iframe "Revisão dos trabalhos dos alunos"

Por fim, adicione um caminho para exibir o iframe "Revisão dos trabalhos dos alunos". O nome dessa rota precisa corresponder ao nome fornecido para o studentWorkReviewUri ao criar um anexo. Esse trajeto é aberto quando o professor visualiza o envio do aluno na interface de notas do Google Sala de Aula.

Você recebe o parâmetro de consulta submissionId quando o Google Sala de Aula abre o iframe "Revisão dos trabalhos dos alunos". Use-o para recuperar o trabalho do estudante do banco de dados local:

Python

No exemplo fornecido, isso está no arquivo webapp/attachment_routes.py.

@app.route("/view-submission")
def view_submission():
    """
    Render a student submission using the show-student-submission.html template.
    """

    # Save the query parameters passed to the iframe in the session, just as we did
    # in previous routes. Abbreviated here for readability.
    add_iframe_query_parameters_to_session(flask.request.args)

    # For the sake of brevity in this example, we'll skip the conditional logic
    # to see if we need to authorize the user as we have done in previous steps.
    # We can assume that the user that reaches this route is a teacher that has
    # already authorized and created an attachment using the add-on.

    # In production, we recommend fully validating the user's authorization at
    # this stage as well.

    # Look up the student's submission in our database.
    student_submission = Submission.query.get(flask.session["submissionId"])

    # Look up the attachment in the database.
    attachment = Attachment.query.get(student_submission.attachment_id)

    # Render the student's response alongside the correct answer.
    return flask.render_template(
        "show-student-submission.html",
        message=f"Loaded submission {student_submission.submission_id} for "\
            f"attachment {attachment.attachment_id}.",
        student_response=student_submission.student_response,
        correct_answer=attachment.image_caption)

Testar o complemento

Repita as etapas de teste do complemento do tutorial anterior. Você precisa ter um anexo que o aluno possa abrir.

Conclua as etapas a seguir para testar o anexo da atividade:

  • Faça login no Google Sala de Aula como um dos usuários de teste estudantes na mesma turma do usuário de teste professor.
  • Acesse a guia Atividades e expanda a opção Atividade do teste.
  • Clique no card de anexo de complementos para abrir a visualização do estudante e enviar uma resposta sobre a atividade.
  • Feche o iframe após concluir a atividade. Opcionalmente, clique no botão Entregar.

Nada vai mudar no Google Sala de Aula depois que você concluir a atividade. Agora teste o iframe "Revisão dos trabalhos dos alunos":

  • Faça login no Google Sala de Aula como usuário de teste professor.
  • Encontre a coluna da tarefa de teste na guia Notas. Clique no nome da atividade de teste.
  • Encontre o cartão do usuário estudante de teste. Clique no anexo no card.

Confirme se o envio correto aparece para o estudante.

Parabéns! Está tudo pronto para a próxima etapa: sincronizar notas do anexo.