Anexos de tipo de atividade

Este é o quinto tutorial da série 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. São os anexos que exigem o envio de um estudante, como uma resposta por escrito, um teste ou outro artefato.

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

  • O botão "Entregar" aparece no canto superior direito do iframe do Student View.
  • Eles oferecem um identificador exclusivo para os trabalhos dos estudantes.
  • O card de anexo aparece na interface de avaliação do Google Sala de Aula.
  • Eles podem definir uma nota para a tarefa a que pertencem.

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

  • Modifique as solicitações de criação de anexos anteriores para a API Classroom para criar um anexo do tipo atividade.
  • Implemente armazenamento permanente para os arquivos enviados pelos estudantes.
  • Modifique o trajeto anterior da visualização dos estudantes para aceitar a entrada deles.
  • Indique uma rota para exibir o iframe de avaliação dos trabalhos dos alunos.

Quando terminar, você poderá criar anexos do tipo atividade nas atividades pela interface do Google Sala de Aula quando tiver feito login como professor. Os alunos 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.

Neste 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 informe 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 principal aqui é uma instância de um objeto AddOnAttachment, em que especificamos anteriormente teacherViewUri, studentViewUri e title para o anexo.

Embora todos os anexos de complementos exijam esses três campos, a presença ou a ausência de um studentWorkReviewUri determina se o anexo é 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 ser feita nessa solicitação é preencher o campo studentWorkReviewUri. Adicione aqui uma rota com nome apropriado. Você a implementará em uma etapa posterior.

Python

Em nosso 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

Registre a resposta do estudante à nossa atividade. Você pode pesquisar mais tarde, quando o professor abrir o envio, no iframe de avaliação dos trabalhos dos estudantes.

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

  • attachment_id: identificador exclusivo de um anexo. Atribuído pelo 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 na visualização do estudante.
  • student_response: a resposta fornecida pelo estudante.

Python

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

Navegue até o arquivo em que você definiu as tabelas anteriores (models.py se estiver seguindo nosso 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 o anexo que processa as rotas.

Modificar o trajeto da visualização dos estudantes

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

Localize o código do servidor que fornece a rota para sua visualização dos alunos. 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

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

Também é possível emitir uma solicitação para receber o status de envio do estudante. A resposta contém um valor SubmissionState, que indica estados, por exemplo, se o aluno abriu ou entregou o anexo. Isso pode ser útil se você quiser proibir edições em um envio entregue ou se quiser fornecer insights aos professores sobre o progresso dos alunos:

Python

No exemplo fornecido, essa é 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 em nosso banco de dados e disponibilize um formulário de entrada. O formulário do exemplo fornecido consiste em um campo de entrada de string e um botão "Enviar". Mostre a imagem do ponto de referência e peça para o estudante digitar o nome. Assim que ela enviar uma resposta, registre-a em nosso banco de dados.

Python

No exemplo fornecido, essa é 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 do professor.

Adicionar uma rota para o iframe de avaliação dos trabalhos dos alunos

Por fim, adicione uma rota para exibir o iframe de avaliação dos trabalhos dos alunos. O nome dessa rota precisa corresponder ao fornecido para o studentWorkReviewUri ao criar um anexo. Esse trajeto abre quando o professor visualiza o envio do estudante na interface de usuário do avaliador do Google Sala de Aula.

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

Python

Em nosso 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 em Testar as etapas complementares do tutorial anterior. É necessário 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 de estudantes na mesma turma que o usuário de teste para professores.
  • Acesse a guia Atividades e expanda a Atividade do teste.
  • Clique no card de anexo de complementos para abrir a visualização do estudante e enviar uma resposta para a atividade.
  • Feche o iframe depois de concluir a atividade. Se quiser, clique no botão Entregar.

Não vai haver mudanças no Google Sala de Aula depois que você concluir a atividade. Agora teste o iframe de avaliação dos trabalhos dos alunos:

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

Confirme se o envio correto é exibido para o estudante.

Parabéns! Você está pronto para prosseguir para a próxima etapa: sincronizar notas de anexos.