Pièces jointes liées à l'activité

Il s'agit du cinquième tutoriel de la série sur les modules complémentaires Classroom.

Dans ce tutoriel, vous allez modifier l'exemple de l'étape précédente pour produire une pièce jointe de type activité. Il s'agit de toutes les pièces jointes qui nécessitent un devoir de la part de l'élève, comme une réponse écrite, un quiz ou tout autre élément créé par l'élève.

Il est important de faire la distinction entre les pièces jointes de type contenu et de type activité. Les pièces jointes de type activité diffèrent de celles de type contenu de la manière suivante :

  • Un bouton "Rendre le devoir" s'affiche en haut à droite de l'iFrame de la vue de l'élève.
  • Ils fournissent un identifiant unique pour le travail des élèves.
  • La fiche de leur pièce jointe s'affiche dans l'interface utilisateur de l'outil de notation Classroom.
  • Ils peuvent attribuer une note au devoir auquel ils appartiennent.

Pour en savoir plus sur la notation, consultez la procédure pas à pas suivante. Au cours de ce tutoriel, vous allez effectuer les opérations suivantes :

  • Modifiez les requêtes de création de pièces jointes précédentes pour l'API Classroom afin de créer une pièce jointe de type activité.
  • Implémentez un stockage persistant pour les devoirs des élèves.
  • Modifiez l'itinéraire de la vue de l'élève précédente pour accepter les saisies des élèves.
  • Fournissez un itinéraire pour diffuser l'iFrame "Examen des devoirs des élèves".

Une fois terminé, vous pouvez créer des pièces jointes de type activité dans les devoirs via l'interface utilisateur Google Classroom lorsque vous êtes connecté en tant qu'enseignant. Les élèves du cours peuvent également effectuer l'activité dans l'iFrame et envoyer une réponse. L'enseignant peut consulter le devoir de l'élève dans l'interface utilisateur de notation de Classroom.

Pour cet exemple, réutilisez le modèle de pièce jointe du tutoriel précédent, qui montre une image d'un monument célèbre et une légende avec le nom du monument. L'activité consiste à demander à l'élève de fournir le nom du point de repère.

Modifier la demande de création de pièce jointe

Accédez à la section de votre code dans laquelle vous avez créé une pièce jointe de type contenu dans le tutoriel précédent. L'élément clé ici est une instance d'un objet AddOnAttachment, dans lequel nous avons précédemment spécifié teacherViewUri, studentViewUri et title pour le rattachement.

Bien que ces trois champs soient obligatoires pour toutes les pièces jointes de modules complémentaires, la présence ou l'absence d'un studentWorkReviewUri détermine si la pièce jointe est de type activité ou contenu. Une requête CREATE avec un studentWorkReviewUri renseigné devient une pièce jointe de type activité, tandis qu'une requête CREATE sans studentWorkReviewUri devient une pièce jointe de type contenu.

La seule modification à apporter à cette requête consiste à renseigner le champ studentWorkReviewUri. Ajoutez ici un itinéraire portant un nom approprié. Vous l'implémenterez lors d'une étape ultérieure.

Python

Dans l'exemple fourni, il s'agit de la méthode create_attachments dans le fichier 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}",
}

Ajouter un stockage persistant pour les pièces jointes de type contenu

Enregistrez la réponse de l'élève à notre activité. Vous pourrez la consulter ultérieurement lorsque l'enseignant affichera le devoir dans l'iFrame "Examen des devoirs des élèves".

Configurez un schéma de base de données pour un Submission. L'exemple fourni attend des élèves qu'ils saisissent le nom du point de repère affiché dans une image. Un Submission contient donc les attributs suivants :

  • attachment_id : identifiant unique d'une pièce jointe. Attribué par Classroom et renvoyé dans la réponse lors de la création d'une pièce jointe.
  • submission_id : identifiant d'un devoir d'élève. Attribué par Classroom et renvoyé dans la réponse getAddOnContext dans la vue de l'élève.
  • student_response : réponse fournie par l'élève.

Python

Étendez l'implémentation SQLite et flask_sqlalchemy des étapes précédentes.

Accédez au fichier dans lequel vous avez défini les tableaux précédents (models.py si vous suivez l'exemple fourni). Ajoutez les lignes suivantes en bas du fichier.

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

Importez la nouvelle classe Submission dans le fichier serveur avec vos routes de gestion des pièces jointes.

Modifier le parcours de la vue de l'élève

Ensuite, modifiez l'itinéraire de la vue de l'élève précédente pour afficher un petit formulaire et accepter les saisies de l'élève. Vous pouvez réutiliser la majeure partie du code de la procédure pas à pas précédente.

Localisez le code du serveur qui fournit l'itinéraire pour votre vue Étudiant. Il s'agit de la route spécifiée dans le champ studentViewUri lors de la création d'une pièce jointe. La première modification à apporter consiste à extraire submissionId de la réponse getAddOnContext.

Python

Dans l'exemple fourni, il s'agit de la méthode load_activity_attachment dans le fichier 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")

Vous pouvez également envoyer une requête pour obtenir l'état des devoirs des élèves. La réponse contient une valeur SubmissionState, qui indique des états tels que l'ouverture ou le dépôt de la pièce jointe par l'élève. Cela peut être utile si vous souhaitez interdire les modifications sur un devoir rendu ou si vous souhaitez fournir aux enseignants des informations sur les progrès de leurs élèves :

Python

Dans l'exemple fourni, il s'agit d'une continuation de la méthode load_activity_attachment ci-dessus.

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

Enfin, récupérez les informations sur la pièce jointe dans notre base de données et affichez un formulaire de saisie. Le formulaire de notre exemple fourni se compose d'un champ de saisie de chaîne et d'un bouton d'envoi. Affichez l'image du monument et demandez à l'élève de saisir son nom. Une fois qu'ils ont fourni une réponse, enregistrez-la dans notre base de données.

Python

Dans l'exemple fourni, il s'agit d'une continuation de la méthode load_activity_attachment ci-dessus.

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

Pour différencier les utilisateurs, envisagez de désactiver la fonction d'envoi et d'afficher plutôt la bonne réponse dans la vue de l'enseignant.

Ajouter un itinéraire pour l'iFrame "Examen des devoirs"

Enfin, ajoutez un itinéraire pour diffuser l'iFrame de l'outil d'examen des travaux des élèves. Le nom de cette route doit correspondre à celui fourni pour studentWorkReviewUri lors de la création d'une pièce jointe. Cet itinéraire s'ouvre lorsque l'enseignant consulte le devoir de l'élève dans l'interface utilisateur de notation Classroom.

Vous recevez le paramètre de requête submissionId lorsque Classroom ouvre l'iFrame "Examen des devoirs des élèves". Utilisez-le pour récupérer le devoir de l'élève à partir de votre base de données locale :

Python

Dans l'exemple fourni, il se trouve dans le fichier 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)

Tester le module complémentaire

Répétez les étapes de test du module complémentaire de la procédure pas à pas précédente. Vous devez avoir une pièce jointe que l'élève peut ouvrir.

Pour tester la pièce jointe de l'activité, procédez comme suit :

  • Connectez-vous à Google Classroom en tant qu'élève test dans la même classe que l'enseignant test.
  • Accédez à l'onglet Travaux et devoirs, puis développez le devoir de test.
  • Cliquez sur la fiche de pièce jointe du module complémentaire pour ouvrir la vue de l'élève et envoyer une réponse à l'activité.
  • Fermez l'iFrame une fois l'activité terminée. Vous pouvez également cliquer sur le bouton Rendre le devoir.

Une fois l'activité terminée, vous ne devriez constater aucun changement dans Classroom. Testez maintenant l'iFrame de correction des devoirs :

  • Connectez-vous à Classroom en tant qu'utilisateur test enseignant.
  • Recherchez la colonne correspondant à votre devoir de test dans l'onglet Notes. Cliquez sur le nom de votre devoir test.
  • Recherchez la fiche de l'utilisateur test. Cliquez sur la pièce jointe de la fiche.

Vérifiez que le devoir correct s'affiche pour l'élève.

Félicitations ! Vous êtes prêt à passer à l'étape suivante : synchroniser les notes des pièces jointes.