Archivos adjuntos de tipo de actividad

Este es el quinto instructivo de la serie de instructivos sobre los complementos de Classroom.

En este instructivo, modificarás el ejemplo del paso anterior para producir un adjunto de tipo de actividad. Son los archivos adjuntos que requieren que el estudiante envíe una respuesta, como una respuesta escrita, un cuestionario o cualquier otro artefacto generado por el estudiante.

Es importante distinguir entre los archivos adjuntos de tipo de contenido y de tipo de actividad. Los adjuntos de tipo de actividad difieren de los de tipo de contenido de las siguientes maneras:

  • Aparecerá un botón "Entregar" en la parte superior derecha del iframe de la vista del estudiante.
  • Proporcionan un identificador único para el trabajo de los estudiantes.
  • Su tarjeta de archivo adjunto aparecerá en la IU del calificador de Classroom.
  • Pueden establecer una calificación para la tarea a la que pertenecen.

Consulta la siguiente explicación para obtener información sobre la calificación. En el transcurso de este instructivo, completarás lo siguiente:

  • Modifica las solicitudes anteriores de creación de adjuntos a la API de Classroom para crear un adjunto de tipo actividad.
  • Implementa almacenamiento persistente para los envíos de los estudiantes.
  • Modifica la ruta anterior de Vista del estudiante para aceptar la entrada del estudiante.
  • Proporciona una ruta para publicar el iframe de Student Work Review.

Cuando termines, podrás crear archivos adjuntos de tipo actividad en las tareas a través de la IU de Google Classroom cuando accedas como profesor. Los estudiantes de la clase también pueden completar la actividad en el iframe y enviar una respuesta. El profesor puede ver el trabajo que envió el estudiante en la IU de calificaciones de Classroom.

Para los fines de este ejemplo, reutiliza la plantilla de adjunto de la explicación anterior, que muestra una imagen de un monumento famoso y una leyenda con el nombre del monumento. La actividad consiste en pedirle al estudiante que proporcione el nombre del punto de referencia.

Modifica la solicitud de creación de adjuntos

Navega a la sección de tu código en la que creaste un adjunto de tipo de contenido en la explicación anterior. El elemento clave aquí es una instancia de un objeto AddOnAttachment, en el que especificamos previamente teacherViewUri, studentViewUri y title para el adjunto.

Si bien todos los adjuntos de complementos requieren estos tres campos, la presencia o ausencia de un studentWorkReviewUri determina si el adjunto es de tipo actividad o de tipo contenido. Una solicitud CREATE con un studentWorkReviewUri completado se convierte en un adjunto de tipo actividad, mientras que una solicitud CREATE sin un studentWorkReviewUri se convierte en un adjunto de tipo contenido.

La única modificación que se debe realizar en esta solicitud es completar el campo studentWorkReviewUri. Agrega aquí una ruta con un nombre adecuado. La implementarás en un paso posterior.

Python

En el ejemplo que proporcionamos, esto se encuentra en el método create_attachments del archivo 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}",
}

Agrega almacenamiento persistente para los archivos adjuntos de tipo de contenido

Registrar la respuesta del estudiante a nuestra actividad Puedes buscarla más tarde cuando el profesor vea la entrega en el iframe de Revisión del trabajo del estudiante.

Configura un esquema de base de datos para un Submission. En el ejemplo que proporcionamos, se espera que los estudiantes ingresen el nombre del punto de referencia que se muestra en una imagen. Por lo tanto, un Submission contiene los siguientes atributos:

  • attachment_id: Es un identificador único para un adjunto. Classroom lo asigna y se devuelve en la respuesta cuando se crea un adjunto.
  • submission_id: Es un identificador para el envío de un estudiante. Classroom lo asigna y se devuelve en la respuesta getAddOnContext en la vista del estudiante.
  • student_response: Es la respuesta que proporcionó el estudiante.

Python

Extiende la implementación de SQLite y flask_sqlalchemy de los pasos anteriores.

Navega al archivo en el que definiste las tablas anteriores (models.py si sigues nuestro ejemplo proporcionado). Agrega lo siguiente en la parte inferior del archivo.

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

Importa la nueva clase Submission en el archivo del servidor con tus rutas de controladores de archivos adjuntos.

Cómo modificar la ruta de la vista del estudiante

A continuación, modifica la ruta anterior de la vista del estudiante para mostrar un formulario pequeño y aceptar la entrada del estudiante. Puedes reutilizar la mayor parte del código de la guía anterior.

Ubica el código del servidor que proporciona la ruta para la Vista del estudiante. Esta es la ruta especificada en el campo studentViewUri cuando se crea un adjunto. El primer cambio que debes realizar es extraer el submissionId de la respuesta de getAddOnContext.

Python

En el ejemplo que proporcionamos, esto se encuentra en el método load_activity_attachment del archivo 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")

También puedes enviar una solicitud para obtener el estado de envío del estudiante. La respuesta contiene un valor SubmissionState, que indica estados como si el estudiante abrió el archivo adjunto o lo entregó. Esto puede ser útil si quieres inhabilitar las ediciones en una entrega o si te interesa proporcionar estadísticas a los profesores sobre el progreso de sus estudiantes:

Python

En el ejemplo proporcionado, esta es una continuación del método load_activity_attachment anterior.

# 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 último, recupera la información del adjunto de nuestra base de datos y muestra un formulario de entrada. El formulario de nuestro ejemplo proporcionado consta de un campo de entrada de cadena y un botón de envío. Mostrar la imagen del punto de referencia y pedirle al estudiante que ingrese su nombre Una vez que proporcionen una respuesta, regístrala en nuestra base de datos.

Python

En el ejemplo proporcionado, esta es una continuación del método load_activity_attachment anterior.

# 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 a los usuarios, considera inhabilitar la función de envío y, en su lugar, mostrar la respuesta correcta en la vista del profesor.

Agrega una ruta para el iframe de Student Work Review

Por último, agrega una ruta para publicar el iframe de Student Work Review. El nombre de esta ruta debe coincidir con el que se proporcionó para studentWorkReviewUri cuando se creó una vinculación. Esta ruta se abre cuando el profesor ve la entrega del estudiante en la IU del calificador de Classroom.

Recibes el parámetro de consulta submissionId cuando Classroom abre el iframe de Student Work Review. Úsala para recuperar el trabajo del estudiante de tu base de datos local:

Python

En el ejemplo que proporcionamos, se encuentra en el archivo 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)

Prueba el complemento

Repite los pasos para probar el complemento de la guía anterior. Deberías tener un archivo adjunto que el estudiante pueda abrir.

Para probar el adjunto de la actividad, completa los siguientes pasos:

  • Accede a Google Classroom como uno de tus usuarios de prueba estudiantes en la misma clase que el usuario de prueba profesor.
  • Navega a la pestaña Trabajo en clase y expande la Tarea de prueba.
  • Haz clic en la tarjeta de archivo adjunto del complemento para abrir la vista del estudiante y enviar una respuesta para la actividad.
  • Cierra el iframe después de completar la actividad. De manera opcional, haz clic en el botón Entregar.

No deberías ver ningún cambio en Classroom después de completar la actividad. Ahora, prueba el iframe de Student Work Review:

  • Accede a Classroom como el usuario de prueba profesor.
  • Busca la columna de tu tarea de prueba en la pestaña Calificaciones. Haz clic en el nombre de la tarea de prueba.
  • Busca la tarjeta del usuario de prueba del estudiante. Haz clic en el archivo adjunto de la tarjeta.

Confirma que aparezca el envío correcto para el estudiante.

¡Felicitaciones! Ya puedes continuar con el siguiente paso: sincronizar las calificaciones de los archivos adjuntos.