Un rubric
est un modèle que les enseignants peuvent utiliser pour noter les devoirs des élèves. L'API Classroom vous permet d'agir au nom de l'enseignant pour gérer ces grilles d'évaluation.
Figure 1 : Exemple de grille d'évaluation sur un devoir Classroom.
Ce guide explique les concepts et les fonctionnalités de base de l'API Rubrics. Consultez ces articles du centre d'aide pour en savoir plus sur la structure générale d'une grille d'évaluation et sur la notation avec une grille d'évaluation dans l'interface utilisateur de Classroom.
Prérequis
Ce guide suppose que vous disposez des éléments suivants:
- Python 3.8.6 ou version ultérieure
- Outil de gestion des paquets pip
- un projet Google Cloud ;
- disposer d'un compte Google Workspace for Education pour lequel Google Classroom est activé ;
- Un cours test avec au moins un compte élève test Si vous ne disposez pas d'un cours Classroom que vous pouvez utiliser pour les tests, créez-en un dans l'interface utilisateur et ajoutez un élève de test.
Autoriser des identifiants pour une application de bureau
Pour vous authentifier en tant qu'utilisateur final et accéder aux données utilisateur dans votre application, vous devez créer un ou plusieurs ID client OAuth 2.0. Un ID client sert à identifier une application unique auprès des serveurs OAuth de Google. Si votre application s'exécute sur plusieurs plates-formes, vous devez créer un ID client distinct pour chaque plate-forme.
- Accédez à la page "Identifiants" de Google Cloud dans la console Google Cloud.
- Cliquez sur Créer des identifiants > ID client OAuth.
- Cliquez sur Type d'application > Application de bureau.
- Dans le champ Nom, saisissez un nom pour l'identifiant. Ce nom ne s'affiche que dans la console Google Cloud. Par exemple, "Client de la prévisualisation des grilles d'évaluation".
- Cliquez sur Créer. L'écran "Client OAuth créé" s'affiche, avec votre nouvel ID client et votre nouveau code secret.
- Cliquez sur Télécharger JSON, puis sur OK. Les identifiants nouvellement créés s'affichent sous "ID client OAuth 2.0".
- Enregistrez le fichier JSON téléchargé sous le nom
credentials.json
, puis déplacez-le dans votre répertoire de travail. - Cliquez sur Créer des identifiants > Clé API, puis notez la clé API.
Pour en savoir plus, consultez Créer des identifiants d'accès.
Configurer les champs d'application OAuth
Selon les champs d'application OAuth existants de votre projet, vous devrez peut-être configurer des champs d'application supplémentaires.
- Accédez à l'écran de consentement OAuth.
- Cliquez sur Modifier l'application > Enregistrer et continuer pour accéder à l'écran "Champs d'application".
- Cliquez sur Ajouter ou supprimer des habilitations.
- Ajoutez les champs d'application suivants si vous ne les avez pas déjà :
https://www.googleapis.com/auth/classroom.coursework.students
https://www.googleapis.com/auth/classroom.courses
- Cliquez ensuite sur Mettre à jour > Enregistrer et continuer > Enregistrer et continuer > Revenir au tableau de bord.
Pour en savoir plus, consultez Configurer l'écran de consentement OAuth.
Le champ d'application classroom.coursework.students
permet d'accéder aux grilles de notation en lecture et en écriture (ainsi qu'à CourseWork
), tandis que le champ d'application classroom.courses
permet de lire et d'écrire des cours.
Les champs d'application requis pour une méthode donnée sont répertoriés dans la documentation de référence de la méthode. Consultez les champs d'application d'autorisation courses.courseWork.rubrics.create
pour en savoir plus. Vous pouvez consulter tous les champs d'application Classroom dans la section Champs d'application OAuth 2.0 pour les API Google. Les rubriques ne sont pas mentionnées ici, car l'API est toujours en version Preview.
Configurer l'exemple
Dans votre répertoire de travail, installez la bibliothèque cliente Google pour Python:
pip install --upgrade google-api-python-client google-auth-httplib2 google-auth-oauthlib
Créez un fichier nommé main.py
qui crée la bibliothèque cliente et autorise l'utilisateur, en utilisant votre clé API à la place de YOUR_API_KEY
:
import json
import os.path
from google.auth.transport.requests import Request
from google.oauth2.credentials import Credentials
from google_auth_oauthlib.flow import InstalledAppFlow
from googleapiclient.discovery import build
from googleapiclient.errors import HttpError
# If modifying these scopes, delete the file token.json.
SCOPES = ['https://www.googleapis.com/auth/classroom.courses',
'https://www.googleapis.com/auth/classroom.coursework.students']
def build_authenticated_service(api_key):
"""Builds the Classroom service."""
creds = None
# The file token.json stores the user's access and refresh tokens, and is
# created automatically when the authorization flow completes for the first
# time.
if os.path.exists('token.json'):
creds = Credentials.from_authorized_user_file('token.json', SCOPES)
# If there are no (valid) credentials available, let the user log in.
if not creds or not creds.valid:
if creds and creds.expired and creds.refresh_token:
creds.refresh(Request())
else:
flow = InstalledAppFlow.from_client_secrets_file(
'credentials.json', SCOPES)
creds = flow.run_local_server(port=0)
# Save the credentials for the next run.
with open('token.json', 'w') as token:
token.write(creds.to_json())
try:
# Build the Classroom service.
service = build(
serviceName="classroom",
version="v1",
credentials=creds,
discoveryServiceUrl=f"https://classroom.googleapis.com/$discovery/rest?labels=DEVELOPER_PREVIEW&key={api_key}")
return service
except HttpError as error:
print('An error occurred: %s' % error)
if __name__ == '__main__':
service = build_authenticated_service(YOUR_API_KEY)
Exécutez le script à l'aide de python main.py
. Vous devriez être invité à vous connecter et à accepter les champs d'application OAuth.
Créer une attribution
Une grille d'évaluation est associée à un devoir, ou CourseWork
, et n'a de sens que dans le contexte de ce CourseWork
. Les grilles d'évaluation ne peuvent être créées que par le projet Google Cloud qui a créé l'élément CourseWork
parent. Pour les besoins de ce guide, créez une affectation CourseWork
avec un script.
Ajoutez le code suivant à main.py
:
def get_latest_course(service):
"""Retrieves the last created course."""
try:
response = service.courses().list(pageSize=1).execute()
courses = response.get("courses", [])
if not courses:
print("No courses found. Did you remember to create one in the UI?")
return
course = courses[0]
return course
except HttpError as error:
print(f"An error occurred: {error}")
return error
def create_coursework(service, course_id):
"""Creates and returns a sample coursework."""
try:
coursework = {
"title": "Romeo and Juliet analysis.",
"description": """Write a paper arguing that Romeo and Juliet were
time travelers from the future.""",
"workType": "ASSIGNMENT",
"state": "PUBLISHED",
}
coursework = service.courses().courseWork().create(
courseId=course_id, body=coursework).execute()
return coursework
except HttpError as error:
print(f"An error occurred: {error}")
return error
Mettez à jour main.py
pour récupérer le course_id
de la classe de test que vous venez de créer, créez un exemple de devoir et récupérez le coursework_id
du devoir:
if __name__ == '__main__':
service = build_authenticated_service(YOUR_API_KEY)
course = get_latest_course(service)
course_id = course.get("id")
course_name = course.get("name")
print(f"'{course_name}' course ID: {course_id}")
coursework = create_coursework(service, course_id)
coursework_id = coursework.get("id")
print(f"Assignment created with ID {coursework_id}")
#TODO(developer): Save the printed course and coursework IDs.
Enregistrez les course_id
et coursework_id
. Celles-ci sont nécessaires pour toutes les opérations CRUD pour les grilles d'évaluation.
Vous devriez maintenant avoir un exemple de CourseWork
dans Classroom.
Figure 2 : Aperçu d'un exemple de devoir dans Classroom.
Créer une grille d'évaluation
Vous êtes maintenant prêt à commencer à gérer les grilles d'évaluation.
Une grille d'évaluation peut être créée sur un CourseWork
avec un appel Create
contenant l'objet de grille d'évaluation complet, où les propriétés d'ID des critères et des niveaux sont omises (elles sont générées lors de la création).
Ajoutez la fonction suivante à main.py
:
def create_rubric(service, course_id, coursework_id):
"""Creates an example rubric on a coursework."""
try:
body = {
"criteria": [
{
"title": "Argument",
"description": "How well structured your argument is.",
"levels": [
{"title": "Convincing",
"description": "A compelling case is made.", "points": 30},
{"title": "Passable",
"description": "Missing some evidence.", "points": 20},
{"title": "Needs Work",
"description": "Not enough strong evidence..", "points": 0},
]
},
{
"title": "Spelling",
"description": "How well you spelled all the words.",
"levels": [
{"title": "Perfect",
"description": "No mistakes.", "points": 20},
{"title": "Great",
"description": "A mistake or two.", "points": 15},
{"title": "Needs Work",
"description": "Many mistakes.", "points": 5},
]
},
{
"title": "Grammar",
"description": "How grammatically correct your sentences are.",
"levels": [
{"title": "Perfect",
"description": "No mistakes.", "points": 20},
{"title": "Great",
"description": "A mistake or two.", "points": 15},
{"title": "Needs Work",
"description": "Many mistakes.", "points": 5},
]
},
]
}
rubric = service.courses().courseWork().rubrics().create(
courseId=course_id, courseWorkId=coursework_id, body=body,
# Specify the preview version. Rubrics CRUD capabilities are
# supported in V1_20231110_PREVIEW and later.
previewVersion="V1_20231110_PREVIEW"
).execute()
print(f"Rubric created with ID {rubric.get('id')}")
return rubric
except HttpError as error:
print(f"An error occurred: {error}")
return error
Mettez ensuite à jour et exécutez main.py
pour créer l'exemple de grille d'évaluation, en utilisant vos ID Course
et CourseWork
précédents:
if __name__ == '__main__':
service = build_authenticated_service(YOUR_API_KEY)
rubric = create_rubric(service, YOUR_COURSE_ID, YOUR_COURSEWORK_ID)
print(json.dumps(rubric, indent=4))
Quelques points à noter concernant la représentation de la grille d'évaluation:
- Les critères et l'ordre des niveaux sont reflétés dans l'interface utilisateur de Classroom.
- Les niveaux avec score (ceux avec la propriété
points
) doivent être triés par points dans l'ordre croissant ou décroissant (ils ne peuvent pas être triés de manière aléatoire). - Les enseignants peuvent réorganiser les critères et les niveaux de notation (mais pas les niveaux sans notation) dans l'interface utilisateur. Cela modifie leur ordre dans les données.
Pour en savoir plus sur les limites de la structure des grilles d'évaluation, consultez la section correspondante.
De retour dans l'interface utilisateur, vous devriez voir la grille d'évaluation de l'exercice.
Figure 3 : Exemple de grille d'évaluation pour un devoir Classroom.
Lire une grille d'évaluation
Les grilles d'évaluation peuvent être lues à l'aide des méthodes List
et Get
standards.
Une devoir ne peut contenir qu'une seule grille d'évaluation. List
peut donc sembler peu intuitif, mais il est utile si vous ne disposez pas déjà de l'ID de la grille d'évaluation. Si aucune grille d'évaluation n'est associée à un CourseWork
, la réponse List
est vide.
Ajoutez la fonction suivante à main.py
:
def get_rubric(service, course_id, coursework_id):
"""
Get the rubric on a coursework. There can only be at most one.
Returns null if there is no rubric.
"""
try:
response = service.courses().courseWork().rubrics().list(
courseId=course_id, courseWorkId=coursework_id,
# Specify the preview version. Rubrics CRUD capabilities are
# supported in V1_20231110_PREVIEW and later.
previewVersion="V1_20231110_PREVIEW"
).execute()
rubrics = response.get("rubrics", [])
if not rubrics:
print("No rubric found for this assignment.")
return
rubric = rubrics[0]
return rubric
except HttpError as error:
print(f"An error occurred: {error}")
return error
Mettez à jour et exécutez main.py
pour récupérer la grille d'évaluation que vous avez ajoutée:
if __name__ == '__main__':
service = build_authenticated_service(YOUR_API_KEY)
rubric = get_rubric(service, YOUR_COURSE_ID, YOUR_COURSEWORK_ID)
print(json.dumps(rubric, indent=4))
#TODO(developer): Save the printed rubric ID.
Notez la propriété id
dans la grille d'évaluation pour les étapes suivantes.
Get
fonctionne bien lorsque vous disposez de l'ID de la grille d'évaluation. L'utilisation de Get
dans la fonction peut se présenter comme suit:
def get_rubric(service, course_id, coursework_id, rubric_id):
"""
Get the rubric on a coursework. There can only be at most one.
Returns a 404 if there is no rubric.
"""
try:
rubric = service.courses().courseWork().rubrics().get(
courseId=course_id,
courseWorkId=coursework_id,
id=rubric_id,
# Specify the preview version. Rubrics CRUD capabilities are
# supported in V1_20231110_PREVIEW and later.
previewVersion="V1_20231110_PREVIEW"
).execute()
return rubric
except HttpError as error:
print(f"An error occurred: {error}")
return error
Cette implémentation renvoie un code 404 si aucune grille d'évaluation n'est disponible.
Mettre à jour une grille d'évaluation
Les mises à jour d'une grille d'évaluation sont effectuées à l'aide d'appels Patch
. En raison de la structure complexe d'une grille d'évaluation, les mises à jour doivent être effectuées à l'aide d'un modèle lecture-modification-écriture, où l'ensemble de la propriété criteria
est remplacé.
Les règles de mise à jour sont les suivantes:
- Les critères ou niveaux ajoutés sans ID sont considérés comme des ajouts.
- Les critères ou niveaux manquants par rapport à la version précédente sont considérés comme des suppressions.
- Les critères ou niveaux avec un ID existant, mais des données modifiées sont considérés comme des modifications. Les propriétés non modifiées sont laissées telles quelles.
- Les critères ou les niveaux fournis avec des identifiants nouveaux ou inconnus sont considérés comme des erreurs.
- L'ordre des nouveaux critères et niveaux est considéré comme l'ordre de la nouvelle interface utilisateur (avec les limites mentionnées ci-dessus).
Ajoutez une fonction pour mettre à jour une grille d'évaluation:
def update_rubric(service, course_id, coursework_id, rubric_id, body):
"""
Updates the rubric on a coursework.
"""
try:
rubric = service.courses().courseWork().rubrics().patch(
courseId=course_id,
courseWorkId=coursework_id,
id=rubric_id,
body=body,
updateMask='criteria',
# Specify the preview version. Rubrics CRUD capabilities are
# supported in V1_20231110_PREVIEW and later.
previewVersion="V1_20231110_PREVIEW"
).execute()
return rubric
except HttpError as error:
print(f"An error occurred: {error}")
return error
Dans cet exemple, le champ criteria
est spécifié pour être modifié à l'aide d'un updateMask
.
Modifiez ensuite main.py
pour apporter une modification à chacune des règles de mise à jour mentionnées ci-dessus:
if __name__ == '__main__':
service = build_authenticated_service(YOUR_API_KEY)
# Get the latest rubric.
rubric = get_rubric(service, YOUR_COURSE_ID, YOUR_COURSEWORK_ID)
criteria = rubric.get("criteria")
"""
The "criteria" property should look like this:
[
{
"id": "NkEyMdMyMzM2Nxkw",
"title": "Argument",
"description": "How well structured your argument is.",
"levels": [
{
"id": "NkEyMdMyMzM2Nxkx",
"title": "Convincing",
"description": "A compelling case is made.",
"points": 30
},
{
"id": "NkEyMdMyMzM2Nxky",
"title": "Passable",
"description": "Missing some evidence.",
"points": 20
},
{
"id": "NkEyMdMyMzM2Nxkz",
"title": "Needs Work",
"description": "Not enough strong evidence..",
"points": 0
}
]
},
{
"id": "NkEyMdMyMzM2Nxk0",
"title": "Spelling",
"description": "How well you spelled all the words.",
"levels": [...]
},
{
"id": "NkEyMdMyMzM2Nxk4",
"title": "Grammar",
"description": "How grammatically correct your sentences are.",
"levels": [...]
}
]
"""
# Make edits. This example will make one of each type of change.
# Add a new level to the first criteria. Levels must remain sorted by
# points.
new_level = {
"title": "Profound",
"description": "Truly unique insight.",
"points": 50
}
criteria[0]["levels"].insert(0, new_level)
# Remove the last criteria.
del criteria[-1]
# Update the criteria titles with numeric prefixes.
for index, criterion in enumerate(criteria):
criterion["title"] = f"{index}: {criterion['title']}"
# Resort the levels from descending to ascending points.
for criterion in criteria:
criterion["levels"].sort(key=lambda level: level["points"])
# Update the rubric with a patch call.
new_rubric = update_rubric(
service, YOUR_COURSE_ID, YOUR_COURSEWORK_ID, YOUR_RUBRIC_ID, rubric)
print(json.dumps(new_rubric, indent=4))
Les modifications devraient maintenant être répercutées dans Classroom pour l'enseignant.
Figure 4. Vue de la grille d'évaluation mise à jour.
Afficher les devoirs notés par une grille d'évaluation
Pour le moment, l'API ne peut pas noter les devoirs des élèves avec une grille d'évaluation, mais vous pouvez lire les notes attribuées avec une grille d'évaluation dans l'interface utilisateur de Classroom.
En tant qu'élève, terminez et remettez votre exemple de devoir dans l'interface utilisateur de Classroom. En tant qu'enseignant, notez manuellement le devoir à l'aide de la grille d'évaluation.
Figure 5. Vue de la grille d'évaluation par l'enseignant lors de la notation.
Les devoirs des élèves notés à l'aide d'une grille d'évaluation comportent deux nouvelles propriétés: draftRubricGrades
et assignedRubricGrades
, qui représentent respectivement les points et les niveaux choisis par l'enseignant lors de la rédaction et les états de notation attribués.
De plus, les devoirs des élèves avec une grille d'évaluation associée contiennent un champ rubricId
, même avant la notation. Il s'agit de la dernière grille d'évaluation associée à CourseWork
. Cette valeur peut changer si les enseignants suppriment et recréent une grille d'évaluation.
Vous pouvez utiliser les méthodes studentSubmissions.Get
et studentSubmissions.List
existantes pour afficher les devoirs notés.
Ajoutez la fonction suivante à main.py
pour afficher les devoirs des élèves:
def get_latest_submission(service, course_id, coursework_id):
"""Retrieves the last submission for an assignment."""
try:
response = service.courses().courseWork().studentSubmissions().list(
courseId = course_id,
courseWorkId = coursework_id,
pageSize=1,
# Specify the preview version. Rubrics CRUD capabilities are
# supported in V1_20231110_PREVIEW and later.
previewVersion="V1_20231110_PREVIEW"
).execute()
submissions = response.get("studentSubmissions", [])
if not submissions:
print(
"""No submissions found. Did you remember to turn in and grade
the assignment in the UI?""")
return
submission = submissions[0]
return submission
except HttpError as error:
print(f"An error occurred: {error}")
return error
Mettez ensuite à jour et exécutez main.py
pour afficher les notes des devoirs.
if __name__ == '__main__':
service = build_authenticated_service(YOUR_API_KEY)
submission = get_latest_submission(
service, YOUR_COURSE_ID, YOUR_COURSEWORK_ID)
print(json.dumps(submission, indent=4))
draftRubricGrades
et assignedRubricGrades
contiennent:
criterionId
des critères de la grille d'évaluation correspondants.points
attribué par l'enseignant pour chaque critère. Cela peut provenir du niveau sélectionné, mais l'enseignant peut également l'avoir écrasé.levelId
du niveau choisi pour chaque critère. Si l'enseignant n'a pas choisi de niveau, mais a quand même attribué des points pour le critère, ce champ n'est pas présent.
Ces listes ne contiennent que des entrées pour les critères pour lesquels un enseignant a sélectionné un niveau ou défini des points. Par exemple, si un enseignant choisit de n'interagir qu'avec un seul critère lors de la notation, draftRubricGrades
et assignedRubricGrades
ne comporteront qu'un seul élément, même si la grille comporte de nombreux critères.
Supprimer une grille d'évaluation
Vous pouvez supprimer une grille d'évaluation à l'aide d'une requête Delete
standard. Le code suivant montre un exemple de fonction d'exhaustivité, mais vous ne pouvez pas supprimer la grille d'évaluation actuelle, car la notation a déjà commencé:
def delete_rubric(service, course_id, coursework_id, rubric_id):
"""Deletes the rubric on a coursework."""
try:
service.courses().courseWork().rubrics().delete(
courseId=course_id,
courseWorkId=coursework_id,
id=rubric_id,
# Specify the preview version. Rubrics CRUD capabilities are
# supported in V1_20231110_PREVIEW and later.
previewVersion="V1_20231110_PREVIEW"
).execute()
except HttpError as error:
print(f"An error occurred: {error}")
return error
Exporter et importer des grilles d'évaluation
Les grilles d'évaluation peuvent être exportées manuellement vers Google Sheets pour être réutilisées par les enseignants.
En plus de spécifier les critères des grilles d'évaluation dans le code, vous pouvez créer et mettre à jour des grilles d'évaluation à partir de ces feuilles exportées en spécifiant le sourceSpreadsheetId
dans le corps de la grille au lieu de criteria
:
def create_rubric_from_sheet(service, course_id, coursework_id, sheet_id):
"""Creates an example rubric on a coursework."""
try:
body = {
"sourceSpreadsheetId": sheet_id
}
rubric = service.courses().courseWork().rubrics().create(
courseId=course_id, courseWorkId=coursework_id, body=body,
# Specify the preview version. Rubrics CRUD capabilities are
# supported in V1_20231110_PREVIEW and later.
previewVersion="V1_20231110_PREVIEW"
).execute()
print(f"Rubric created with ID {rubric.get('id')}")
return rubric
except HttpError as error:
print(f"An error occurred: {error}")
return error
Commentaires
Si vous rencontrez des problèmes ou si vous souhaitez nous faire part de vos commentaires, envoyez-nous vos commentaires.