Una rubric
es una plantilla que los profesores pueden usar cuando califiquen a los estudiantes
los envíos de datos. La API de Classroom te permite actuar en nombre del
profesor para administrar estas rúbricas.
Figura 1: Vista de una rúbrica de ejemplo en una tarea de Classroom.
En esta guía, se explican los conceptos básicos y la funcionalidad de la API de rúbricas. Consulta estos artículos del Centro de ayuda para obtener información sobre los conceptos de una rúbrica y cómo la rúbrica la calificación se realiza en la IU de Classroom.
Requisitos previos
En esta guía, se supone que tienes lo siguiente:
- Python 3.8.6 o superior
- La herramienta de administración de paquetes pip
- Un proyecto de Google Cloud
- Una cuenta de Google Workspace for Education con Google Classroom habilitada.
- Una clase de prueba con al menos una cuenta de estudiante de prueba Si no tienes un clase de Classroom que puedes usar para hacer pruebas, crear una en la IU y agrega un estudiante de prueba.
Autoriza credenciales para una aplicación de escritorio
Para autenticarte como usuario final y acceder a los datos del usuario en tu app, debes crear uno o más IDs de cliente de OAuth 2.0. Un ID de cliente se usa con el fin de identificar una sola app para los servidores de OAuth de Google. Si tu app se ejecuta en varias plataformas debes crear un ID de cliente diferente para cada plataforma.
- Navega a la página Credenciales de Google Cloud en la Consola de Google Cloud
- Haz clic en Crear credenciales > ID de cliente de OAuth.
- Haz clic en Tipo de aplicación > App para computadoras de escritorio.
- En el campo Nombre, escribe un nombre para la credencial. Este nombre solo es que se muestran en la consola de Google Cloud. Por ejemplo, "Cliente de vista previa de rúbricas".
- Haz clic en Crear. Aparecerá la pantalla de creación del cliente de OAuth que mostrará tu nuevo ID de cliente y Secreto de cliente
- Haz clic en Descargar JSON y, luego, en Aceptar. La credencial creada recientemente aparece en los IDs de cliente de OAuth 2.0.
- Guarda el archivo JSON descargado como
credentials.json
y muévelo a tu directorio de trabajo. - Haz clic en Crear credenciales > Clave de API y anota la clave de API.
Consulta Crea credenciales de acceso para obtener más información.
Configura los permisos de OAuth
Según los permisos de OAuth existentes en tu proyecto, es posible que debas configurar alcances de adición.
- Ve a la pantalla de consentimiento de OAuth.
- Haz clic en Editar aplicación > Haz clic en Guardar y continuar para ir a la pantalla Permisos.
- Haz clic en Add or Remove Scopes.
- Agrega los siguientes permisos si aún no los tienes:
https://www.googleapis.com/auth/classroom.coursework.students
https://www.googleapis.com/auth/classroom.courses
- Luego, haz clic en Actualizar > Guardar y continuar > Guardar y continuar > Volver al panel.
Consulta Configura la pantalla de consentimiento de OAuth para obtener más información más.
El permiso classroom.coursework.students
habilita el acceso de lectura y escritura a
rúbricas (junto con acceso a CourseWork
) y el permiso classroom.courses
te permite leer y escribir cursos.
Los alcances necesarios para un método determinado se enumeran en la documentación de referencia.
para el método. Consulta los permisos de autorización de courses.courseWork.rubrics.create
.
como ejemplo. Puedes ver todos los permisos de Classroom en Permisos de OAuth 2.0 para Google
APIs. Aquí no se mencionan las rúbricas porque la API todavía está en versión preliminar.
Configura la muestra
En el directorio de trabajo, instala la biblioteca cliente de Google para Python:
pip install --upgrade google-api-python-client google-auth-httplib2 google-auth-oauthlib
Crea un archivo llamado main.py
que compile la biblioteca cliente y autorice las
usuario, con tu clave de API en lugar 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)
Ejecuta la secuencia de comandos con python main.py
. Se te indicará que accedas y
consentimiento para los permisos de OAuth.
Crear una tarea
Una rúbrica está asociada a una tarea o CourseWork
, y solo es
significativo en el contexto de ese CourseWork
. Solo las personas que pueden crear rúbricas
el proyecto de Google Cloud que creó el elemento superior CourseWork
. Para los fines
de esta guía, crea una nueva tarea CourseWork
con una secuencia de comandos.
Agrega lo siguiente a 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
Ahora, actualiza main.py
para recuperar el elemento course_id
de la clase de prueba que acabas de actualizar
crear, crear una nueva tarea de muestra y recuperar los datos
coursework_id
:
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.
Guarda course_id
y coursework_id
. Estos son necesarios para todas las rúbricas: CRUD
las operaciones.
Ahora deberías tener una muestra de CourseWork
en Classroom.
Figura 2: Vista de una tarea de muestra en Classroom.
Cómo crear una rúbrica
Ya puedes comenzar a administrar las rúbricas.
Se puede crear una rúbrica en un CourseWork
con una llamada Create
que contenga lo siguiente:
objeto de rúbrica completa, en la que se omiten las propiedades de ID para criterios y niveles
(se generan durante la creación).
Agrega la siguiente función a 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
Luego, actualiza y ejecuta main.py
para crear la rúbrica de ejemplo con tu Course
.
y los IDs de CourseWork
anteriores:
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))
Estos son algunos puntos sobre la representación en la rúbrica:
- El orden de los criterios y niveles se refleja en la IU de Classroom.
- Los niveles con puntuación (los que tienen la propiedad
points
) deben ordenarse por puntos en orden ascendente o descendente (no se pueden ordenar de forma aleatoria). - Los profesores pueden volver a ordenar los criterios y los niveles con puntuación (pero no pueden tenerlos niveles) en la IU, y eso cambia su orden en los datos.
Consulta las limitaciones para obtener más advertencias sobre la estructura de las rúbricas.
De vuelta en la IU, deberías ver la rúbrica en la tarea.
Figura 3: Vista de una rúbrica de ejemplo en una tarea de Classroom.
Lee una rúbrica
Las rúbricas se pueden leer con los métodos estándar List
y Get
.
Puede haber como máximo una rúbrica en una tarea, por lo que puede parecer que List
no intuitivo, pero es útil si aún no tienes el ID de rúbrica. Si
no hay rúbricas asociadas a una CourseWork
, por lo que la respuesta de List
está vacía.
Agrega la siguiente función a 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
Actualiza y ejecuta main.py
para recuperar la rúbrica que agregaste:
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.
Presta atención a la propiedad id
en la rúbrica para los pasos posteriores.
Get
funciona bien cuando tienes el ID de la rúbrica. Cómo usar Get
en la función
en su lugar podría verse así:
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
Esta implementación devuelve un error 404 si no hay rúbrica.
Cómo actualizar una rúbrica
Las actualizaciones de una rúbrica se realizan con llamadas a Patch
. Debido a la compleja estructura
de una rúbrica, las actualizaciones deben realizarse con un patrón de lectura-modificación-escritura, en el que
se reemplaza toda la propiedad criteria
.
Las reglas de actualización son las siguientes:
- Los criterios o niveles agregados sin un ID se consideran adiciones.
- Se considerarán los criterios o niveles que faltan anteriormente. eliminaciones.
- Se consideran criterios o niveles con un ID existente, pero datos modificados ediciones. Las propiedades sin modificar se mantienen como están.
- Se consideran los criterios o niveles proporcionados con un ID nuevo o desconocido. errores.
- El orden de los nuevos criterios y niveles se considera el nuevo orden de la IU. (con las limitaciones antes mencionadas).
Agrega una función para actualizar una rúbrica:
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
En este ejemplo, el campo criteria
se especifica para su modificación con un
updateMask
Luego, modifica main.py
para realizar un cambio en cada una de las actualizaciones mencionadas anteriormente.
reglas:
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))
Los cambios ahora deberían reflejarse para el profesor en Classroom.
Figura 4: Vista de la rúbrica actualizada.
Ver las entregas calificadas por rúbricas
Por ahora, la API no puede calificar las entregas de los estudiantes con una rúbrica, pero puede leer las calificaciones de las rúbricas de las entregas que han sido calificadas con una rúbrica en la IU de Classroom.
Como alumno en la IU de Classroom, completa y entrega una tarea de muestra. Luego, como profesor, califica la tarea con la rúbrica de forma manual.
Figura 5: Vista de la rúbrica del profesor durante la calificación.
Las entregas de estudiantes que se calificaron con una rúbrica tienen dos nuevos
propiedades: draftRubricGrades
y assignedRubricGrades
, que representan el
puntos y niveles que eligió el profesor durante el borrador y la calificación asignada
respectivamente.
Además, las entregas de los estudiantes con una rúbrica asociada incluyen un rubricId
de la aplicación, incluso antes de la calificación. Esto representa la última rúbrica asociada con
CourseWork
. Este valor podría cambiar si los profesores borran y vuelven a crear una
una matriz de evaluación.
Puedes usar el studentSubmissions.Get
existente y
studentSubmissions.List
métodos para ver las entregas calificadas.
Agrega la siguiente función a main.py
para enumerar las entregas de los estudiantes:
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
Luego, actualiza y ejecuta main.py
para ver las calificaciones de las entregas.
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
y assignedRubricGrades
contienen lo siguiente:
- La
criterionId
de los criterios de la rúbrica correspondientes. - Es la
points
que el profesor asignó para cada criterio. Esto podría provenir de la pero el profesor también podría haberlo sobrescrito. - El
levelId
del nivel elegido para cada criterio. Si el profesor no elegir un nivel, pero seguir asignando puntos para el criterio, este campo no está presente.
Estas listas solo contienen entradas según los criterios en los que un profesor
o seleccionar un nivel o establecer puntos. Por ejemplo, si un profesor elige solo
interactuarán con un criterio durante la calificación: draftRubricGrades
y
assignedRubricGrades
solo tendría un elemento, incluso si la rúbrica tiene muchos
con tus criterios.
Cómo borrar una rúbrica
Se puede borrar una rúbrica mediante una solicitud Delete
estándar. El siguiente código
muestra un ejemplo de función de integridad, pero como la calificación ya ha
empezaste, no puedes eliminar la rúbrica actual:
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
Cómo importar y exportar rúbricas
Las rúbricas se pueden exportar manualmente a Google Hojas de cálculo que los profesores pueden volver a utilizar
Además de especificar los criterios de las rúbricas en el código, es posible crear y
actualizar rúbricas de estas hojas exportadas especificando
sourceSpreadsheetId
en el cuerpo de una rúbrica en lugar 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
Comentarios
Si encuentras algún problema o quieres aportar una opinión, comparte tus comentarios.