Questo è il quarto tutorial della serie di tutorial sui componenti aggiuntivi di Classroom.
In questo tutorial, interagisci con l'API Google Classroom per creare allegati. Fornisci route per consentire agli utenti di visualizzare i contenuti degli allegati. Le visualizzazioni variano a seconda del ruolo dell'utente nel corso. Questa procedura dettagliata riguarda gli allegati di tipo di contenuti, che non richiedono l'invio di contenuti da parte degli studenti.
Nel corso di questo tutorial, completerai le seguenti operazioni:
- Recuperare e utilizzare i seguenti parametri di query dei componenti aggiuntivi:
addOnToken: un token di autorizzazione passato alla visualizzazione di rilevamento degli allegati.itemId: un identificatore univoco per CourseWork, CourseWorkMaterial o Announcement che riceve l'allegato del componente aggiuntivo.itemType: "courseWork", "courseWorkMaterials" o "announcement".courseId: un identificatore univoco per il corso Google Classroom in cui viene creato il compito.attachmentId: un identificatore univoco assegnato da Google Classroom a un allegato del componente aggiuntivo dopo la creazione.
- Implementare l'archiviazione permanente per gli allegati di tipo di contenuti.
- Fornire route per creare allegati e pubblicare gli iframe della visualizzazione dell'insegnante e della visualizzazione dello studente.
- Inviare le seguenti richieste all'API dei componenti aggiuntivi di Google Classroom:
- Creare un nuovo allegato.
- Ottenere il contesto del componente aggiuntivo, che identifica se l'utente che ha eseguito l'accesso è uno studente o un insegnante.
Al termine, puoi creare allegati di tipo di contenuti nei compiti tramite l'interfaccia utente di Google Classroom quando hai eseguito l'accesso come insegnante. Anche gli insegnanti e gli studenti del corso possono visualizzare i contenuti.
Abilitare l'API Classroom
A partire da questo passaggio, effettua chiamate all'API Classroom. L'API deve essere abilitata per il tuo progetto Google Cloud prima di poter effettuare chiamate. Vai alla voce della libreria dell'API Google Classroom e scegli Abilita.
Gestire i parametri di query della visualizzazione di rilevamento degli allegati
Come discusso in precedenza, Google Classroom passa i parametri di query durante il caricamento della visualizzazione di rilevamento degli allegati nell'iframe:
courseId: l'ID del corso Classroom corrente.itemId: un identificatore univoco per CourseWork, CourseWorkMaterial o Announcement che riceve l'allegato del componente aggiuntivo.itemType: "courseWork", "courseWorkMaterials" o "announcement".addOnToken: un token utilizzato per autorizzare determinate azioni dei componenti aggiuntivi di Classroom.login_hint: l'ID Google dell'utente corrente.
Questo tutorial riguarda courseId, itemId, itemType e addOnToken.
Mantieni e passa questi parametri quando effettui chiamate all'API Classroom.
Come nel passaggio precedente della procedura dettagliata, memorizza i valori dei parametri di query passati nella nostra sessione. È importante farlo quando la visualizzazione di rilevamento degli allegati viene aperta per la prima volta, poiché è l'unica opportunità per Classroom di passare questi parametri di query.
Python
Vai al file del server Flask che fornisce le route per la visualizzazione di rilevamento degli allegati (attachment-discovery-routes.py se segui l'esempio fornito). Nella parte superiore della route di destinazione del componente aggiuntivo (/classroom-addon nell'esempio fornito), recupera e memorizza i parametri di query courseId, itemId, itemType e addOnToken.
# Retrieve the itemId, courseId, and addOnToken query parameters.
if flask.request.args.get("itemId"):
flask.session["itemId"] = flask.request.args.get("itemId")
if flask.request.args.get("itemType"):
flask.session["itemType"] = flask.request.args.get("itemType")
if flask.request.args.get("courseId"):
flask.session["courseId"] = flask.request.args.get("courseId")
if flask.request.args.get("addOnToken"):
flask.session["addOnToken"] = flask.request.args.get("addOnToken")
Scrivi questi valori nella sessione solo se sono presenti; non vengono passati di nuovo se l'utente torna alla visualizzazione di rilevamento degli allegati in un secondo momento senza chiudere l'iframe.
Aggiungere l'archiviazione permanente per gli allegati di tipo di contenuti
Devi avere un record locale di tutti gli allegati creati. In questo modo puoi cercare i contenuti selezionati dall'insegnante utilizzando gli identificatori forniti da Classroom.
Configura uno schema di database per un Attachment. L'esempio fornito presenta allegati che mostrano un'immagine e una didascalia. Un Attachment contiene i seguenti attributi:
attachment_id: un identificatore univoco per un allegato. Assegnato da Classroom e restituito nella risposta durante la creazione di un allegato.image_filename: il nome file locale dell'immagine da visualizzare.image_caption: la didascalia da mostrare con l'immagine.
Python
Estendi l'implementazione di SQLite e flask_sqlalchemy dai passaggi precedenti.
Vai al file in cui hai definito la tabella Utente (models.py se segui l'esempio fornito). Aggiungi quanto segue nella parte inferiore del file sotto la classe User.
class Attachment(db.Model):
# The attachmentId is the unique identifier for the attachment.
attachment_id = db.Column(db.String(120), primary_key=True)
# The image filename to store.
image_filename = db.Column(db.String(120))
# The image caption to store.
image_caption = db.Column(db.String(120))
Importa la nuova classe Attachment nel file del server con le route di gestione degli allegati.
Configurare nuove route
Inizia questo passaggio del tutorial configurando alcune nuove pagine nella nostra applicazione. In questo modo, un utente può creare e visualizzare i contenuti tramite il nostro componente aggiuntivo.
Aggiungere route di creazione degli allegati
Sono necessarie pagine per consentire all'insegnante di selezionare i contenuti ed emettere richieste di creazione degli allegati. Implementa la route /attachment-options per visualizzare le opzioni di contenuti che l'insegnante può selezionare. Sono necessari anche modelli per le pagine di selezione dei contenuti e di conferma della creazione. Gli esempi forniti contengono modelli per questi elementi e possono anche visualizzare le richieste e le risposte dell'API Classroom.
Tieni presente che, in alternativa, puoi modificare la pagina di destinazione della visualizzazione di rilevamento degli allegati esistente per visualizzare le opzioni di contenuti anziché creare la nuova pagina /attachment-options. Ti consigliamo di creare una nuova pagina per questo esercizio in modo da mantenere il comportamento SSO implementato nel secondo
passaggio del tutorial, ad esempio la revoca delle autorizzazioni dell'app. Questi elementi dovrebbero essere utili durante la creazione e il test del componente aggiuntivo.
Nel nostro esempio fornito, un insegnante può selezionare un piccolo insieme di immagini con didascalie. Abbiamo fornito quattro immagini di punti di riferimento paesaggistici famosi le cui didascalie derivano dai nomi dei file.
Python
Nel nostro esempio fornito, questo si trova nel file webapp/attachment_routes.py.
@app.route("/attachment-options", methods=["GET", "POST"])
def attachment_options():
"""
Render the attachment options page from the "attachment-options.html"
template.
This page displays a grid of images that the user can select using
checkboxes.
"""
# A list of the filenames in the static/images directory.
image_filenames = os.listdir(os.path.join(app.static_folder, "images"))
# The image_list_form_builder method creates a form that displays a grid
# of images, checkboxes, and captions with a Submit button. All images
# passed in image_filenames will be shown, and the captions will be the
# title-cased filenames.
# The form must be built dynamically due to limitations in WTForms. The
# image_list_form_builder method therefore also returns a list of
# attribute names in the form, which will be used by the HTML template
# to properly render the form.
form, var_names = image_list_form_builder(image_filenames)
# If the form was submitted, validate the input and create the attachments.
if form.validate_on_submit():
# Build a dictionary that maps image filenames to captions.
# There will be one dictionary entry per selected item in the form.
filename_caption_pairs = construct_filename_caption_dictionary_list(
form)
# Check that the user selected at least one image, then proceed to
# make requests to the Classroom API.
if len(filename_caption_pairs) > 0:
return create_attachments(filename_caption_pairs)
else:
return flask.render_template(
"create-attachment.html",
message="You didn't select any images.",
form=form,
var_names=var_names)
return flask.render_template(
"attachment-options.html",
message=("You've reached the attachment options page. "
"Select one or more images and click 'Create Attachment'."),
form=form,
var_names=var_names,
)
Viene generata una pagina "Crea allegati" simile alla seguente:
L'insegnante può selezionare più immagini. Crea un allegato per ogni immagine selezionata dall'insegnante nel metodo create_attachments.
Emettere richieste di creazione degli allegati
Ora che sai quali contenuti l'insegnante vuole allegare, invia richieste all'API Classroom per creare allegati nel nostro compito. Memorizza i dettagli degli allegati nel database dopo aver ricevuto una risposta dall'API Classroom.
Inizia recuperando un'istanza del servizio Classroom:
Python
Nel nostro esempio fornito, questo si trova nel file webapp/attachment_routes.py.
def create_attachments(filename_caption_pairs):
"""
Create attachments and show an acknowledgement page.
Args:
filename_caption_pairs: A dictionary that maps image filenames to
captions.
"""
# Get the Google Classroom service.
classroom_service = googleapiclient.discovery.build(
serviceName="classroom",
version="v1",
credentials=credentials)
Emetti una CREATE richiesta all'courses.courseWork.addOnAttachments
endpoint. Per ogni immagine selezionata dall'insegnante, crea prima un
AddOnAttachment oggetto:
Python
Nel nostro esempio fornito, questa è una continuazione del metodo create_attachments.
# Create a new attachment for each image that was selected.
attachment_count = 0
for key, value in filename_caption_pairs.items():
attachment_count += 1
# Create a dictionary with values for the AddOnAttachment object fields.
attachment = {
# Specifies the route for a teacher user.
"teacherViewUri": {
"uri":
flask.url_for(
"load_content_attachment", _scheme='https', _external=True),
},
# Specifies the route for a student user.
"studentViewUri": {
"uri":
flask.url_for(
"load_content_attachment", _scheme='https', _external=True)
},
# The title of the attachment.
"title": f"Attachment {attachment_count}",
}
Per ogni allegato devono essere forniti almeno i campi teacherViewUri, studentViewUri e title. teacherViewUri e studentViewUri rappresentano gli URL caricati quando l'allegato viene aperto dal rispettivo tipo di utente.
Invia l'oggetto AddOnAttachment nel corpo di una richiesta all'endpoint addOnAttachments appropriato. Fornisci gli identificatori courseId, itemId, itemType e addOnToken con ogni richiesta.
Python
Nel nostro esempio fornito, questa è una continuazione del metodo create_attachments.
# Use the itemType to determine which stream item type the teacher created
match flask.session["itemType"]:
case "announcements":
parent = classroom_service.courses().announcements()
case "courseWorkMaterials":
parent = classroom_service.courses().courseWorkMaterials()
case _:
parent = classroom_service.courses().courseWork()
# Issue a request to create the attachment.
resp = parent.addOnAttachments().create(
courseId=flask.session["courseId"],
itemId=flask.session["itemId"],
addOnToken=flask.session["addOnToken"],
body=attachment).execute()
Crea una voce per questo allegato nel database locale in modo da poter caricare i contenuti corretti in un secondo momento. Classroom restituisce un valore id univoco nella risposta alla richiesta di creazione, quindi utilizzalo come chiave primaria nel nostro database. Tieni presente che Classroom passa anche il parametro di query attachmentId quando apre le visualizzazioni dell'insegnante e dello studente:
Python
Nel nostro esempio fornito, questa è una continuazione del metodo create_attachments.
# Store the value by id.
new_attachment = Attachment(
# The new attachment's unique ID, returned in the CREATE response.
attachment_id=resp.get("id"),
image_filename=key,
image_caption=value)
db.session.add(new_attachment)
db.session.commit()
A questo punto, valuta la possibilità di indirizzare l'utente a una pagina di conferma, riconoscendo che ha creato correttamente gli allegati.
Consentire gli allegati dal componente aggiuntivo
Ora è un buon momento per aggiungere gli indirizzi appropriati al campo Prefissi URI degli allegati consentiti nella pagina Configurazione app dell'SDK Google Workspace Marketplace. Il componente aggiuntivo può creare allegati solo da uno dei prefissi URI elencati in questa pagina. Si tratta di una misura di sicurezza per ridurre la possibilità di attacchi man-in-the-middle.
L'approccio più semplice consiste nel fornire il dominio di primo livello in questo campo, ad esempio https://example.com. https://localhost:<your port number>/ funzionerebbe se utilizzi la tua macchina locale come server web.
Aggiungere route per le visualizzazioni dell'insegnante e dello studente
Esistono quattro iframe in cui è possibile caricare un componente aggiuntivo di Google Classroom. Finora hai creato solo route che pubblicano l'iframe della visualizzazione di rilevamento degli allegati. Aggiungi ora anche le route per pubblicare gli iframe della visualizzazione dell'insegnante e della visualizzazione dello studente.
L'iframe della visualizzazione dell'insegnante è necessario per mostrare un'anteprima dell'esperienza dello studente, ma può includere facoltativamente informazioni aggiuntive o funzionalità di modifica.
La visualizzazione dello studente è la pagina presentata a ogni studente quando apre un allegato del componente aggiuntivo.
Ai fini di questo esercizio, crea una singola route /load-content-attachment che pubblica sia la visualizzazione dell'insegnante sia la visualizzazione dello studente. Utilizza i metodi dell'API Classroom per determinare se l'utente è un insegnante o uno studente quando la pagina viene caricata.
Python
Nel nostro esempio fornito, questo si trova nel file webapp/attachment_routes.py.
@app.route("/load-content-attachment")
def load_content_attachment():
"""
Load the attachment for the user's role."""
# Since this is a landing page for the Teacher and Student View iframes, we
# need to preserve the incoming query parameters.
if flask.request.args.get("itemId"):
flask.session["itemId"] = flask.request.args.get("itemId")
if flask.request.args.get("itemType"):
flask.session["itemType"] = flask.request.args.get("itemType")
if flask.request.args.get("courseId"):
flask.session["courseId"] = flask.request.args.get("courseId")
if flask.request.args.get("attachmentId"):
flask.session["attachmentId"] = flask.request.args.get("attachmentId")
Tieni presente che a questo punto devi anche autenticare l'utente. Devi anche gestire il parametro di query login_hint qui e indirizzare l'utente al flusso di autorizzazione, se necessario. Per ulteriori informazioni su questo flusso, consulta i dettagli delle indicazioni di accesso descritti
nei tutorial precedenti.
Quindi, invia una richiesta all'endpoint getAddOnContext che corrisponde al tipo di elemento.
Python
Nel nostro esempio fornito, questa è una continuazione del metodo load_content_attachment.
# Create an instance of the Classroom service.
classroom_service = googleapiclient.discovery.build(
serviceName="classroom"
version="v1",
credentials=credentials)
# Use the itemType to determine which stream item type the teacher created
match flask.session["itemType"]:
case "announcements":
parent = classroom_service.courses().announcements()
case "courseWorkMaterials":
parent = classroom_service.courses().courseWorkMaterials()
case _:
parent = classroom_service.courses().courseWork()
addon_context_response = parent.getAddOnContext(
courseId=flask.session["courseId"],
itemId=flask.session["itemId"]).execute()
Questo metodo restituisce informazioni sul ruolo dell'utente corrente nel corso.
Modifica la visualizzazione presentata all'utente a seconda del suo ruolo. Nel corpo della risposta
oggetto viene compilato esattamente uno dei
studentContext o teacherContext campi. Esaminali per determinare come rivolgerti all'utente.
In ogni caso, utilizza il valore parametro di query attachmentId per sapere quale allegato recuperare dal nostro database. Questo parametro di query viene fornito quando si aprono gli URI della visualizzazione dell'insegnante o dello studente.
Python
Nel nostro esempio fornito, questa è una continuazione del metodo load_content_attachment.
# Determine which view we are in by testing the returned context type.
user_context = "student" if addon_context_response.get(
"studentContext") else "teacher"
# Look up the attachment in the database.
attachment = Attachment.query.get(flask.session["attachmentId"])
# Set the text for the next page depending on the user's role.
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 enjoy this image of a famous landmark!")
# Show the content with the customized message text.
return flask.render_template(
"show-content-attachment.html",
message=message_str,
image_filename=attachment.image_filename,
image_caption=attachment.image_caption,
responses=response_strings)
Testare il componente aggiuntivo
Per testare la creazione degli allegati:
- Accedi a [Google Classroom] come uno dei tuoi utenti di test insegnanti.
- Vai alla scheda Lavori del corso e crea un nuovo compito.
- Fai clic sul pulsante Componenti aggiuntivi sotto l'area di testo, quindi seleziona il componente aggiuntivo. L'iframe si apre e il componente aggiuntivo carica l'URI di configurazione degli allegati che hai specificato nella pagina Configurazione app dell'SDK Google Workspace Marketplace.
- Scegli un contenuto da allegare al compito.
- Chiudi l'iframe al termine del flusso di creazione degli allegati.
Dovresti visualizzare una scheda dell'allegato nell'interfaccia utente di creazione dei compiti in Google Google Classroom. Fai clic sulla scheda per aprire l'iframe della visualizzazione dell'insegnante e verificare che venga visualizzato l'allegato corretto. Fai clic sul pulsante Assegna.
Per testare l'esperienza dello studente:
- Accedi a Classroom come utente di test studente nello stesso corso dell'utente di test insegnante.
- Trova il compito di test nella scheda Lavori del corso.
- Espandi il compito e fai clic sulla scheda dell'allegato per aprire l'iframe della visualizzazione dello studente.
Verifica che venga visualizzato l'allegato corretto per lo studente.
Complimenti! Ora puoi passare al passaggio successivo: creare allegati di tipo attività.