Archivos adjuntos de tipo de actividad

Esta es la quinta explicación de la serie sobre complementos de Classroom.

En esta explicación, modificarás el ejemplo del paso anterior para producir un archivo adjunto de tipo de actividad. Estos son todos los archivos adjuntos que requieren la entrega del estudiante, como una respuesta escrita, un cuestionario o algún otro artefacto generado por el estudiante.

La distinción entre los archivos adjuntos de tipo de contenido y tipo de actividad es importante. Los archivos adjuntos de tipo de actividad difieren del tipo de contenido en las siguientes maneras:

  • El botón “Entregar” aparece en la esquina superior derecha del iframe de vista de alumno.
  • Proporcionan un identificador único para el trabajo de los estudiantes.
  • Su tarjeta adjunta aparecerá en la IU de calificación de Classroom.
  • Puede establecer una calificación para la tarea a la que pertenece.

Consulta la siguiente explicación para ver un debate sobre las calificaciones. En el transcurso de esta explicación, completarás lo siguiente:

  • Modifica las solicitudes de creación de archivos adjuntos anteriores a la API de Classroom para crear un archivo adjunto de tipo de actividad.
  • Implementa el almacenamiento persistente para las entregas de los estudiantes.
  • Modifica la ruta anterior de la vista de estudiante para aceptar las entradas de los estudiantes.
  • Proporciona una ruta para entregar el iframe de la Revisión del trabajo de los estudiantes.

Cuando termines, puedes crear archivos adjuntos de tipo de actividad en las tareas mediante la IU de Google Classroom cuando accedas como profesor. Los alumnos de la clase también pueden completar la actividad en el iframe y enviar una respuesta. El profesor puede ver la entrega del alumno en la IU de calificación de Classroom.

Para los fines de este ejemplo, vuelve a usar la plantilla de archivos adjuntos de la explicación anterior, en la que se muestra una imagen de un punto de referencia famoso y una leyenda con su nombre. La actividad consiste en pedirle al estudiante que proporcione el nombre del punto de referencia.

Modifica la solicitud de creación del adjunto

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 previamente se especificaba el elemento teacherViewUri, studentViewUri y title para el adjunto.

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

La única modificación que debes hacer a esta solicitud es propagar el campo studentWorkReviewUri. Agrega una ruta con el nombre adecuado aquí; la implementarás en un paso posterior.

Python

En nuestro ejemplo proporcionado, 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 archivos adjuntos de tipo de contenido

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

Configura un esquema de base de datos para un Submission. En el ejemplo proporcionado, 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 archivo adjunto. Lo asigna Classroom y se muestra en la respuesta cuando se crea un archivo adjunto.
  • submission_id: Es el identificador de la entrega de un estudiante. Lo asigna Classroom y lo muestra en la respuesta getAddOnContext en la Vista de alumno.
  • student_response: Es la respuesta proporcionada por el estudiante.

Python

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

Navega hasta el archivo en el que definiste las tablas anteriores (models.py si sigues el ejemplo proporcionado). Agrega lo siguiente al final 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 clase Submission nueva al archivo de servidor con las rutas de control de archivos adjuntos.

Cómo modificar la ruta de la vista de estudiante

A continuación, modifica la ruta anterior de la vista de estudiante para mostrar un formulario pequeño y aceptar los comentarios del estudiante. Puedes volver a usar la mayor parte del código de la explicación anterior.

Ubica el código del servidor que proporciona la ruta a la vista de alumno. Esta es la ruta que se especifica en el campo studentViewUri cuando se crea un adjunto. El primer cambio que debes hacer es extraer el submissionId de la respuesta getAddOnContext.

Python

En nuestro ejemplo proporcionado, 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 entrega de los estudiantes. 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 entregada o si te interesa proporcionar información sobre el progreso de los estudiantes:

Python

En nuestro ejemplo proporcionado, 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 entrega un formulario de entrada. El formulario de nuestro ejemplo proporcionado consta de un campo de entrada de string y un botón de envío. Muestra la imagen del punto de referencia y pídele al estudiante que ingrese su nombre. Una vez que te proporcionen una respuesta, regístrala en nuestra base de datos.

Python

En nuestro ejemplo proporcionado, 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 entre los usuarios, considera inhabilitar la función de envío y, en su lugar, muestra la respuesta correcta en la vista de profesores.

Agregar una ruta para el iframe de Revisión del trabajo de los estudiantes

Por último, agrega una ruta para entregar el iframe de Revisión del trabajo de los estudiantes. El nombre de esta ruta debe coincidir con el que se proporcionó para studentWorkReviewUri cuando se crea un adjunto. Esta ruta se abre cuando el profesor ve la entrega del estudiante en la IU de la calificación de Classroom.

Recibirás el parámetro de búsqueda submissionId cuando Classroom abra el iframe de la revisión del trabajo de los estudiantes. Úsalo para recuperar el trabajo del estudiante de tu base de datos local:

Python

En nuestro ejemplo proporcionado, esto 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 los pasos del complemento de la explicación anterior. Debes tener un archivo adjunto que el estudiante pueda abrir.

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

  • Accede a Google Classroom como uno de los usuarios de prueba de estudiantes en la misma clase que el usuario de prueba de profesor.
  • Navega a la pestaña Trabajo en clase y expande la prueba Tarea.
  • Haz clic en la tarjeta de archivo adjunto del complemento para abrir la vista de alumno 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 la Revisión del trabajo de los alumnos:

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

Confirma que aparezca la entrega correcta para el estudiante.

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