1. Introduzione

In questo codelab, vedrai come Gemini Code Assist può supportarti nelle fasi chiave del ciclo di vita dello sviluppo software (SDLC), come progettazione, creazione e test e deployment. Progetteremo e svilupperemo un'intera applicazione e la implementeremo su Google Cloud.
Creeremo un'API e un'applicazione per eseguire ricerche nelle sessioni di un evento tecnico. Ogni sessione avrà un titolo, un riepilogo, una durata, delle categorie e uno o più relatori.
Attività previste
- Progetta, crea, testa ed esegui il deployment di un'applicazione web basata su una specifica OpenAPI da zero
Cosa imparerai a fare
- Come utilizzare Gemini Code Assist per generare una specifica OpenAPI
- Come utilizzare le funzionalità di generazione del codice di Gemini Code Assist per sviluppare un'applicazione Python Flask per la specifica OpenAPI
- Come utilizzare Gemini Code Assist per generare un front-end web per l'applicazione Python Flask
- Come utilizzare Gemini Code Assist per ricevere assistenza su come eseguire il deployment dell'applicazione in Google Cloud Run
- Utilizza le funzionalità di Gemini Code Assist, come la spiegazione del codice e la generazione di scenari di test, durante la creazione e il test dell'applicazione
Che cosa ti serve
- Browser web Chrome
- Un account Gmail
- Un progetto cloud con fatturazione abilitata
- Gemini Code Assist abilitato per il tuo progetto cloud
Questo lab è rivolto a sviluppatori di tutti i livelli, inclusi i principianti. Sebbene l'applicazione di esempio sia in linguaggio Python, non è necessario avere familiarità con la programmazione in Python per capire cosa sta succedendo. Ci concentreremo sull'acquisizione di familiarità con le funzionalità di Gemini Code Assist.
2. Configura Gemini Code Assist
Questa sezione descrive tutto ciò che devi fare per iniziare questo lab.
Abilitare Gemini Code Assist nell'IDE di Cloud Shell
Per il resto del codelab utilizzeremo Cloud Shell IDE, un ambiente di sviluppo completamente gestito basato su Code OSS. Dobbiamo abilitare e configurare Code Assist nell'IDE di Cloud Shell. I passaggi sono riportati di seguito:
- Visita ide.cloud.google.com. Potrebbe volerci un po' di tempo prima che l'IDE venga visualizzato, quindi abbi pazienza e accetta le scelte predefinite per la configurazione. Se vedi alcune istruzioni sulla configurazione dell'IDE, completale con le impostazioni predefinite.
- Fai clic sul pulsante Cloud Code - Sign in (Cloud Code - Accedi) nella barra di stato in basso, come mostrato. Autorizza il plug-in come indicato. Se nella barra di stato vedi "Cloud Code - no project", selezionalo e poi scegli il progetto Google Cloud specifico dall'elenco dei progetti con cui prevedi di lavorare.

- Fai clic sul pulsante Code Assist nell'angolo in basso a destra, come mostrato, e seleziona un'ultima volta il progetto Google Cloud corretto. Se ti viene chiesto di abilitare l'API Cloud AI Companion, fallo e vai avanti.
- Dopo aver selezionato il progetto Google Cloud, assicurati di visualizzarlo nel messaggio di stato di Cloud Code nella barra di stato e che Code Assist sia attivato a destra, nella barra di stato, come mostrato di seguito:

Gemini Code Assist è pronto per l'uso.
3. Configura Firestore
Cloud Firestore è un database di documenti serverless completamente gestito che utilizzeremo come backend per i dati della nostra applicazione. I dati in Cloud Firestore sono strutturati in raccolte di documenti.
Dobbiamo creare una raccolta denominata sessions nel nostro database Firestore predefinito. Questa raccolta conterrà dati di esempio (documenti) che utilizzeremo nella nostra applicazione.
Apri il terminale dall'IDE Cloud Shell tramite il menu principale, come mostrato di seguito:

Dobbiamo creare una raccolta denominata sessions. Qui verrà visualizzato un elenco di documenti di sessione di esempio. Ogni documento avrà i seguenti attributi:
- title: stringa
- categories: array di stringhe
- speakers: array di stringhe
- duration: stringa
- summary: stringa
Compiliamo questa raccolta con dati di esempio copiando un file che contiene i dati di esempio in un bucket del tuo progetto, da cui puoi importare la raccolta tramite il comando gcloud firestore import.
Inizializzazione del database Firestore
Visita la pagina Firestore nella console Cloud.
Se non hai inizializzato un database Firestore in precedenza nel progetto, crea il database default. Durante la creazione del database, utilizza i seguenti valori:
- Modalità Firestore:
Native - Località: scegli il tipo di località
Regione seleziona la regione appropriata per la tua applicazione. Prendi nota di questa posizione, perché ti servirà nel passaggio successivo per la posizione del bucket. - Crea il database.

Ora creeremo la raccolta sessions seguendo i passaggi riportati di seguito:
- Crea un bucket nel tuo progetto con il comando
gsutilriportato di seguito. Sostituisci la variabile<PROJECT_ID>nel comando seguente con il tuo ID progetto Google Cloud. Sostituisci<BUCKET_LOCATION>con un nome di regione corrispondente all'area geografica del database Firestore predefinito (come indicato nel passaggio precedente), ad esempio US-WEST1, EUROPE-WEST1, ASIA-EAST1 :
gsutil mb -l <BUCKET-LOCATION> gs://<PROJECT_ID>-my-bucket
- Ora che il bucket è stato creato, dobbiamo copiarvi l'esportazione del database che abbiamo preparato prima di poterla importare nel database Firebase. Utilizza il comando riportato di seguito:
gsutil cp -r gs://sessions-master-database-bucket/2024-03-26T09:28:15_95256 gs://<PROJECT_ID>-my-bucket
Ora che abbiamo i dati da importare, possiamo passare al passaggio finale dell'importazione nel database Firebase (default) che abbiamo creato.
- Utilizza il comando gcloud riportato di seguito:
gcloud firestore import gs://<PROJECT_ID>-my-bucket/2024-03-26T09:28:15_95256
L'importazione richiederà alcuni secondi e, una volta pronta, potrai convalidare il database Firestore e la raccolta visitando la pagina https://console.cloud.google.com/firestore/databases, selezionando il database default e la raccolta sessions come mostrato di seguito:

In questo modo viene completata la creazione della raccolta Firestore che utilizzeremo nella nostra applicazione.
4. Crea il modello di applicazione
Creeremo un'applicazione di esempio (un'applicazione Python Flask) che utilizzeremo nel resto del codelab. Questa applicazione cercherà tra le sessioni offerte in una conferenza tecnica.
Procedi nel seguente modo:
- Fai clic sul nome del progetto Google Cloud nella barra di stato in basso.

- Verrà visualizzato un elenco di opzioni. Fai clic su Nuova applicazione dall'elenco di seguito.

- Seleziona Applicazione Cloud Run (questo sarà il runtime della nostra app).
- Seleziona il modello di applicazione Python (Flask): Cloud Run.
- Assegna un nome all'applicazione e salvala nella posizione che preferisci.
- Una notifica conferma la creazione della tua applicazione e si apre una nuova finestra con l'applicazione caricata, come mostrato di seguito. Viene aperto un file
README.md. Per il momento puoi chiudere questa visualizzazione.

5. Interagire con Gemini Code Assist
Ai fini di questo lab, utilizzeremo la chat di Gemini Code Assist disponibile all'interno dell'IDE Cloud Shell come parte dell'estensione Cloud Code in VS Code. Puoi visualizzarlo facendo clic sul pulsante Code Assist nella barra di navigazione a sinistra. Cerca l'icona di Code Assist
nella barra di navigazione a sinistra e fai clic.
Verrà visualizzato il riquadro della chat di Code Assist all'interno dell'IDE di Cloud Shell e potrai chattare con Code Assist.

Nota l'icona del cestino in alto: questo è il modo per reimpostare il contesto della cronologia della chat di Code Assist. Tieni presente inoltre che questa interazione via chat è contestuale ai file su cui stai lavorando nell'IDE.
6. API Design
Il nostro primo passo sarà quello di avvalerci dell'assistenza di Gemini Code Assist durante la fase di progettazione. In questo passaggio, genereremo una specifica OpenAPI per le entità (sessioni tecniche in un evento) in cui vogliamo eseguire la ricerca.
Inserisci il seguente prompt:
Generate an Open API spec that will allow me to retrieve all sessions, sessions by category, session by id. Each session has the following attributes: id, title, list of speakers, list of categories, summary and duration.
In questo modo dovrebbe essere generata una specifica OpenAPI per la ricerca tra le sessioni tramite vari parametri di query. Di seguito è riportato un esempio di specifica:
openapi: 3.0.0
info:
title: Sessions API
description: This API allows you to retrieve all sessions, sessions by category, and session by id.
version: 1.0.0
servers:
- url: https://sessions.example.com
paths:
/sessions:
get:
summary: Get all sessions
operationId: getSessions
responses:
'200':
description: OK
content:
application/json:
schema:
type: array
items:
$ref: '#/components/schemas/Session'
/sessions/{id}:
get:
summary: Get session by id
operationId: getSessionById
parameters:
- name: id
in: path
required: true
description: The id of the session
schema:
type: string
responses:
'200':
description: OK
content:
application/json:
schema:
$ref: '#/components/schemas/Session'
/sessions/categories/{category}:
get:
summary: Get sessions by category
operationId: getSessionsByCategory
parameters:
- name: category
in: path
required: true
description: The category of the sessions
schema:
type: string
responses:
'200':
description: OK
content:
application/json:
schema:
type: array
items:
$ref: '#/components/schemas/Session'
components:
schemas:
Session:
type: object
properties:
id:
type: string
description: The id of the session
title:
type: string
description: The title of the session
speakers:
type: array
items:
type: string
description: The list of speakers for the session
categories:
type: array
items:
type: string
description: The list of categories for the session
summary:
type: string
description: The summary of the session
duration:
type: string
description: The duration of the session
Puoi notare che la specifica presenta quanto segue:
- Uno schema definito per il Tipo di sessione.
- Sono definiti diversi percorsi API:
/sessions/sessions/{id}/sessions/categories/{category}
Crea un file denominato sessionsapi.yaml nella cartella principale e copia i contenuti dalla finestra di chat di Code Assist utilizzando l'opzione "Inserisci nel file corrente" (il pulsante +) e mantieni il file aperto nell'IDE Cloud Shell.
A questo punto, puoi notare una funzionalità interessante di Gemini Code Assist: la citazione. Queste informazioni vengono mostrate allo sviluppatore quando il codice generato cita direttamente e in modo esteso un'altra fonte, ad esempio un codice open source esistente. Offre la sorgente e la licenza allo sviluppatore per decidere cosa farne.
Supponendo che i contenuti generati siano accettabili, possiamo ora utilizzare questo documento di specifiche per generare un'applicazione Python Flask.
7. Genera l'applicazione
Ora chiederemo a Code Assist di generare l'applicazione. Dai il seguente prompt con il file sessionsapi.yaml aperto.
Generate a Python Application using the Flask framework, based on the sessionsapi.yaml file. This application uses a local in memory list of sessions. Do not use any Flask extensions.
In questo modo, avrai a disposizione una struttura per l'applicazione Python Flask basata sulle funzionalità e sui percorsi specificati nel file di specifica OpenAPI.
Il codice dell'applicazione Python Flask fornito dovrebbe essere simile al seguente:
from flask import Flask, jsonify, request
app = Flask(__name__)
sessions = [
{
"id": "1",
"title": "Session 1",
"speakers": ["Speaker 1", "Speaker 2"],
"categories": ["Category 1", "Category 2"],
"summary": "This is a summary of session 1.",
"duration": "1 hour",
},
{
"id": "2",
"title": "Session 2",
"speakers": ["Speaker 3", "Speaker 4"],
"categories": ["Category 3", "Category 4"],
"summary": "This is a summary of session 2.",
"duration": "1 hour 30 minutes",
},
]
@app.route('/sessions', methods=['GET'])
def get_sessions():
return jsonify(sessions)
@app.route('/sessions/<id>', methods=['GET'])
def get_session_by_id(id):
session = next((session for session in sessions if session['id'] == id), None)
if session is None:
return jsonify({}), 404
return jsonify(session)
@app.route('/sessions/categories/<category>', methods=['GET'])
def get_sessions_by_category(category):
sessions_by_category = [session for session in sessions if category in session['categories']]
return jsonify(sessions_by_category)
if __name__ == '__main__':
app.run()
Esiste un file app.py generato nell'ambito del passaggio precedente. Ti basterà sostituire i contenuti con il codice generato da Code Assist e salvare il file.
Vorremmo modificare la riga app.run() in modo che utilizzi la porta 8080, l'indirizzo host 0.0.0.0 e venga eseguita in modalità di debug durante l'esecuzione locale.Ecco come fare. Per prima cosa, evidenzia/seleziona la riga:
app.run()
Quindi, nell'interfaccia della chat di Code Assist, digita il prompt: Explain this.
Dovrebbe essere visualizzata una spiegazione dettagliata di quella riga specifica, di cui è riportato un esempio di seguito:

Ora, utilizza il seguente prompt:
update the code to run the application on port 8080, host address 0.0.0.0, and in debug mode
Il codice suggerito generato dovrebbe essere il seguente: :
app.run(host='0.0.0.0', port=8080, debug=True)
Ricordati di aggiornare il file app.py con questo snippet.
Esegui l'applicazione localmente
Eseguiamo ora l'applicazione localmente per convalidare i requisiti dell'applicazione in base a quanto avevamo iniziato.
Il primo passaggio consiste nel creare un ambiente Python virtuale con le dipendenze del pacchetto Python in requirements.txt da installare nell'ambiente virtuale. Per farlo, vai alla tavolozza dei comandi (Ctrl+Maiusc+P) in Cloud Shell IDE e digita Crea ambiente Python. Segui i prossimi passaggi per selezionare un ambiente virtuale (venv), un interprete Python 3.x e il file requirements.txt.
Una volta creato l'ambiente, avvia una nuova finestra del terminale (Ctrl+Maiusc+`) ed esegui il seguente comando:
python app.py
Di seguito è riportato un esempio di esecuzione:
(.venv) romin@cloudshell: $ python app.py
* Serving Flask app 'app'
* Debug mode: on
WARNING: This is a development server. Do not use it in a production deployment. Use a production WSGI server instead.
* Running on all addresses (0.0.0.0)
* Running on http://127.0.0.1:8080
* Running on http://10.88.0.3:8080
Press CTRL+C to quit
* Restarting with stat
* Debugger is active!
* Debugger PIN: 132-247-368
Ora puoi visualizzare l'anteprima dell'API ai seguenti URL. Presumiamo che il server di sviluppo sia in esecuzione sulla porta 8080. In caso contrario, modificalo con il numero di porta appropriato.
https://<host-name>:8080/sessionshttps://<host-name>:8080/sessions/{id}https://<host-name>:8080/sessions/categories/{category}
Segui i passaggi riportati di seguito per assicurarti di poter recuperare, utilizzando questi URL, i dati JSON contenuti nel file app.py:
Apri una nuova finestra del terminale e prova uno dei seguenti comandi:
curl -X GET http://127.0.0.1:8080/sessions
curl -X GET http://127.0.0.1:8080/sessions/<ID>
curl -X GET http://127.0.0.1:8080/sessions/categories/<CATEGORY_NAME>
8. Refactoring del codice
Anziché contenere i dati JSON di esempio codificati, probabilmente vorremmo separare/estrarre app.py in un altro modulo, in modo da mantenere una separazione chiara tra il codice e i dati. Facciamolo.
Tieni aperto il file app.py e inserisci il seguente prompt:
Can I improve this code and separate out the sessions data from this app.py file?
In questo modo, dovresti ricevere alcuni suggerimenti su come procedere. Di seguito è riportato un esempio di suggerimento che abbiamo ricevuto e che dovresti ricevere anche tu:

Seguiamo questo suggerimento e separiamo i dati in un file sessions.py come suggerito da Code Assist.
Crea un nuovo file denominato sessions.py
, il cui contenuto è l'elenco JSON, come indicato di seguito in base ai nostri dati generati:
sessions = [
{
"id": "1",
"title": "Session 1",
"speakers": ["Speaker 1", "Speaker 2"],
"categories": ["Category 1", "Category 2"],
"summary": "This is a summary of session 1.",
"duration": "1 hour",
},
{
"id": "2",
"title": "Session 2",
"speakers": ["Speaker 3", "Speaker 4"],
"categories": ["Category 3", "Category 4"],
"summary": "This is a summary of session 2.",
"duration": "1 hour 30 minutes",
},
]
Il file app.py è ora molto semplificato e viene mostrato di seguito:
from flask import Flask, jsonify, request
from sessions import sessions
app = Flask(__name__)
@app.route('/sessions', methods=['GET'])
def get_sessions():
return jsonify(sessions.sessions)
@app.route('/sessions/<id>', methods=['GET'])
def get_session_by_id(id):
session = next((session for session in sessions.sessions if session['id'] == id), None)
if session is None:
return jsonify({}), 404
return jsonify(session)
@app.route('/sessions/categories/<category>', methods=['GET'])
def get_sessions_by_category(category):
sessions_by_category = [session for session in sessions.sessions if category in session['categories']]
return jsonify(sessions_by_category)
if __name__ == '__main__':
app.run(host='0.0.0.0', port=8080, debug=True)
Assicurati di poter ancora eseguire l'applicazione localmente ed esercitare l'API con queste modifiche di refactoring. È probabile che il server di sviluppo Python sia ancora in esecuzione, quindi devi solo richiamare i comandi curl del passaggio precedente.
9. Integra con la raccolta Firestore
Il passaggio successivo consiste nell'abbandonare l'elenco JSON in memoria locale che abbiamo per le nostre sessioni e connettere la nostra applicazione alla raccolta sessions nel database Firestore, che abbiamo creato all'inizio di questo codelab.
Tieni aperto il file sessions.py e inserisci il seguente prompt:
Can you further refactor the sessions.py code to read from a Firestore database that has a collection named sessions. The collection has the same attributes as the session object that we have defined. Use the Python module google-cloud-firestore.
Abbiamo ricevuto il seguente suggerimento per leggere tutte le sessioni dalla raccolta Firestore:
import google.cloud.firestore
# Create a Firestore client
db = google.cloud.firestore.Client()
# Get the sessions collection
sessions_collection = db.collection("sessions")
# Create a list of sessions
sessions = []
# Iterate over the documents and add them to the list
for doc in sessions_collection.stream():
session = doc.to_dict()
session["id"] = doc.id
sessions.append(session)
Procedi e incorpora il codice in sessions.py.
Se il server di sviluppo Flask è in esecuzione in locale, l'applicazione potrebbe essere stata chiusa con un messaggio di errore che indica che il modulo Python non è stato trovato.
Ad esempio, puoi chiedere a Code Assist quale modulo Python deve essere aggiunto al file requirements.txt, come segue:
Which Python package needs to be installed to make the firestore code work?
In questo modo otterrai il nome del modulo Python (ad es. google-cloud-firestore). Aggiungilo al file requirements.txt.
Dovrai ricreare l'ambiente Python con il modulo appena aggiunto (google-cloud-firestore). Per farlo, esegui questo comando nella finestra del terminale esistente:
pip install -r requirements.txt
Esegui di nuovo l'applicazione (riavviala con python app.py) e visita l'URL /sessions. Ora dovresti visualizzare i documenti di esempio che abbiamo aggiunto alla raccolta sessions.

Puoi eseguire query su altri URI per recuperare sessioni specifiche o tutte le sessioni per una determinata categoria, come descritto nei passaggi precedenti.
10. Spiegazione del codice
Ora è il momento giusto per utilizzare la funzionalità "Explain this" di Gemini Code Assist per comprendere meglio il codice. Puoi accedere a uno qualsiasi dei file o selezionare snippet di codice specifici e chiedere a Code Assist con il seguente prompt: Explain this.
Come esercizio, visita il file sessions.py, evidenzia il codice specifico di Firestore e ottieni una spiegazione del codice. Prova a utilizzare questa funzionalità anche su altri file del progetto, non solo sul codice Python.
11. Genera l'applicazione web
Ora che abbiamo generato l'API e l'abbiamo integrata con una raccolta Firestore live, generiamo un frontend basato sul web per l'applicazione. Al momento, il nostro front-end web manterrà le sue funzionalità al minimo, ovvero sarà in grado di cercare sessioni appartenenti a una categoria specifica. Tieni presente che abbiamo un percorso API per questo scopo, ovvero /sessions/categories/{category}, quindi la nostra applicazione web deve richiamarlo e recuperare i risultati.
Iniziamo subito. Fornisci il seguente prompt a Code Assist:
Generate a web application that allows me to search for sessions by category and uses the Flask application that we created. Please use basic HTML, CSS and JS. Embed all the Javascript and CSS code into a single HTML file only.
In questo modo verrà generato l'HTML dell'applicazione web con JavaScript e CSS incorporati. Ti verrà anche chiesto di aggiungere una nuova route al file app.py, in modo che a qualsiasi utente che visita l'URL radice o di base venga mostrata la home page. Se non menziona queste informazioni, chiedile o utilizza lo snippet riportato di seguito:
@app.route('/')
def index():
return render_template('index.html')
Puoi salvarlo come index.html, ma potresti avere una domanda su dove deve essere salvato il file (ovvero in quale cartella). Possiamo porre una domanda di follow-up a Code Assist.
Given that I am using the flask framework, where should I put the index.html file?
Dovrebbe fornire informazioni chiare sul fatto che utilizza il framework render_template e quindi il file index.html dovrà essere inserito nella cartella templates. Troverai questa cartella disponibile perché abbiamo generato un'applicazione basata sul modello Flask all'inizio di questo codelab. Di conseguenza, esiste un file index.html e devi semplicemente sostituire i suoi contenuti con quelli nuovi generati qui. Code Assist suggerisce anche di importare render_template nel file app.py.
Salva il codice dell'applicazione web nel file index.html e ricordati di inserirlo nella cartella templates.
Esegui l'applicazione localmente
Eseguiamo ora l'applicazione localmente per convalidare i requisiti dell'applicazione in base a quanto avevamo iniziato.
Assicurati che il server Flask locale sia ancora in esecuzione e non mostri errori. In caso di errori, risolvili e avvia il server.
Una volta che l'applicazione è in esecuzione, visita l'URL della home page. Dovrebbe mostrare il file index.html pubblicato come mostrato di seguito:

Fornisci una delle categorie dei dati come input (ad es. AI) e fai clic sul pulsante Search. Dovrebbero essere visualizzate le sessioni taggate con la categoria AI.

Un esercizio facoltativo consiste nel mostrare metadati aggiuntivi come durata, categorie, relatori e riepilogo per ciascuna sessione.
12. Generazione di scenari di test
Abbiamo generato l'API Sessions ed è il momento di utilizzare Gemini Code Assist per generare casi di test unitari per i diversi percorsi API.
Tieni aperto il file app.py e inserisci il seguente prompt:
Generate unit test cases for app routes. Use unittest module.
Abbiamo ricevuto la seguente risposta:
import unittest
from app import app
class FlaskAppTestCase(unittest.TestCase):
def test_index(self):
tester = app.test_client()
response = tester.get('/')
self.assertEqual(response.status_code, 200)
def test_get_sessions(self):
tester = app.test_client()
response = tester.get('/sessions')
self.assertEqual(response.status_code, 200)
def test_get_session_by_id(self):
tester = app.test_client()
response = tester.get('/sessions/1')
self.assertEqual(response.status_code, 200)
def test_get_sessions_by_category(self):
tester = app.test_client()
response = tester.get('/sessions/categories/category1')
self.assertEqual(response.status_code, 200)
if __name__ == '__main__':
unittest.main()
Crea un file denominato tests.py con il codice riportato sopra.
Una nota sulla generazione di scenari di test
Potresti visualizzare un elenco di codici diverso da quello riportato sopra, il che potrebbe causare alcuni problemi durante l'esecuzione degli scenari di test. Ad esempio, abbiamo notato che in alcune delle nostre esecuzioni sono state omesse le seguenti parti di codice chiave:
from app import app
Il codice riportato sopra è necessario per importare l'app Flask esistente rispetto alla quale verranno richiamati gli scenari di test.
if __name__ == '__main__':
`unittest.main()`
Il codice riportato sopra è necessario per eseguire gli scenari di test.
Ti consigliamo di esaminare ogni caso di test, controllare assertEqual e altre condizioni nel codice generato per assicurarti che funzioni. Poiché i dati sono esterni nella raccolta Firestore, potrebbe non essere possibile accedervi e potrebbero essere utilizzati alcuni dati fittizi, con conseguente esito negativo dei test. Modifica di conseguenza gli scenari di test o commenta alcuni di quelli che potresti non aver bisogno immediatamente.
A titolo dimostrativo, abbiamo eseguito gli scenari di test utilizzando il seguente comando (assicurati di eseguire il server di sviluppo locale, poiché verranno effettuate chiamate agli endpoint API locali):
python tests.py
Abbiamo ottenuto il seguente risultato di riepilogo:
Ran 4 tests in 0.274s
FAILED (failures=2)
È corretto, perché l'ID sessione non era corretto nel terzo test e non esiste una categoria denominata category1
.
Quindi, modifica gli scenari di test di conseguenza e provali.
13. Sviluppo basato sui test
Ora vediamo come aggiungere un nuovo metodo di ricerca nella nostra API Sessions seguendo la metodologia di sviluppo basata sui test (TDD), che consiste nello scrivere prima i casi di test, farli non riuscire a causa della mancanza di implementazione e utilizzare Gemini Code Assist per generare l'implementazione mancante in modo che il test venga superato.
Vai al file tests.py (supponendo che tu abbia corretto il file tests.py in modo che tutti i test vengano superati). Chiedi a Code Assist il seguente prompt:
Generate a new test case to search for sessions by speaker
In questo modo abbiamo ottenuto la seguente implementazione dello scenario di test, che abbiamo inserito nel file tests.py.
def test_get_sessions_by_speaker(self):
tester = app.test_client()
response = tester.get('/sessions/speakers/speaker1')
self.assertEqual(response.status_code, 200)
self.assertEqual(response.json, [sessions.sessions[0], sessions.sessions[1]])
Se esegui i test, dovresti visualizzare il seguente errore:
$ python tests.py
.F.
======================================================================
FAIL: test_get_sessions_by_speaker (__main__.FlaskAppTestCase)
----------------------------------------------------------------------
Traceback (most recent call last):
File "/home/romin/hello-world-5/tests.py", line 21, in test_get_sessions_by_speaker
self.assertEqual(response.status_code, 200)
AssertionError: 404 != 200
----------------------------------------------------------------------
Ran 3 tests in 0.010s
FAILED (failures=1)
Questo perché lo scenario di test ha richiamato il seguente percorso (/sessions/speakers/) e non è presente alcuna implementazione in app.py.
Chiediamo a Code Assist di fornirci un'implementazione. Vai al file app.py e fornisci il seguente prompt a Code Assist:
Add a new route to search for sessions by a specific speaker
Abbiamo ricevuto la seguente implementazione suggerita da Code Assist, che abbiamo aggiunto al file app.py:
@app.route('/sessions/speakers/<speaker>', methods=['GET'])
def get_sessions_by_speaker(speaker):
sessions_by_speaker = [session for session in sessions.sessions if speaker in session['speakers']]
return jsonify(sessions_by_speaker)
Rivedi il file tests.py. Per una verifica rapida, abbiamo modificato il nostro scenario di test come segue:
def test_get_sessions_by_speaker(self):
tester = app.test_client()
response = tester.get('/sessions/speakers/Romin Irani')
self.assertEqual(response.status_code, 200)
self.assertEqual(len(response.json), 1)
Il test è stato eseguito correttamente. Ti lasciamo il compito di esaminare gli scenari di test generati, modificarli leggermente a seconda dei dati che potresti avere in Firestore e disporre dei metodi assert* appropriati negli scenari di test delle unità Python.
14. Deployment in Google Cloud Run
Ora che siamo soddisfatti della qualità del nostro sviluppo, l'ultimo passaggio sarà il deployment di questa applicazione su Google Cloud Run. Ma forse, per sicurezza, dovremmo chiedere a Code Assist se abbiamo dimenticato qualcosa. Con app.py aperto, invia il seguente prompt :
Is there something here I should change before I deploy to production?
Per fortuna che hai chiesto, perché ci siamo dimenticati di disattivare il flag di debug :

Come indicato, disattiva il debug e chiedi a Gemini Code Assist di aiutarti con il comando gcloud che può essere utilizzato per eseguire il deployment dell'applicazione su Cloud Run direttamente dall'origine (senza dover prima creare un container).
Inserisci il seguente prompt:
I would like to deploy the application to Cloud Run directly from source. What is the gcloud command to do that?
Prova alcune varianti del prompt precedente. Un altro tentativo che abbiamo fatto è stato:
I would like to deploy this application to Cloud Run. I don't want to build a container image locally but deploy directly from source to Cloud Run. What is the gcloud command for that?
Idealmente, dovresti ottenere il seguente comando gcloud:
gcloud run deploy sessions --source .
Potresti anche ricevere:
gcloud run deploy <service-name> --source . \
—-platform managed \
—-allow-unauthenticated
Esegui il comando riportato sopra dalla cartella principale dell'applicazione. Quando ti viene chiesto di inserire region, seleziona us-central1 e quando ti viene chiesto di consentire unauthenticated invocations, scegli Y. Ti potrebbe anche essere chiesto di abilitare le API Google Cloud come Artifact Registry, Cloud Build e Cloud Run e l'autorizzazione a creare un repository Artifact Registry. Concedi l'autorizzazione.
Il completamento della procedura di deployment richiede circa 2 minuti, quindi ti invitiamo ad avere pazienza.
Una volta eseguito il deployment, vedrai l'URL del servizio Cloud Run. Visita l'URL pubblico e dovresti vedere la stessa applicazione web di cui è stato eseguito il deployment e che è in esecuzione correttamente.

Congratulazioni, ottimo lavoro!
15. (Facoltativo) Utilizza Cloud Logging
Possiamo introdurre la registrazione nella nostra applicazione in modo che i log dell'applicazione siano centralizzati in uno dei servizi Google Cloud (Cloud Logging). Possiamo quindi utilizzare la funzionalità Observability Gemini per comprendere anche le voci di log.
Per farlo, dovremo prima utilizzare una libreria Python Cloud Logging esistente di Google Cloud e utilizzarla per registrare messaggi informativi, di avviso o di errore (a seconda del log / livello di gravità).
Proviamo a chiedere prima a Code Assist. Prova il seguente prompt:
How do I use the google-cloud-logging package in Python?
Dovresti ricevere una risposta che fornisca alcune informazioni, come indicato di seguito:

Aggiungiamo istruzioni di logging alla funzione che cerca le sessioni per categoria.
Per prima cosa, aggiungi il pacchetto Python google-cloud-logging al file requirements.txt.
Di seguito è riportato uno snippet di codice che mostra come abbiamo integrato il codice per implementare la registrazione:
...
from google.cloud import logging
...
app = Flask(__name__)
# Create a logger
logger = logging.Client().logger('my-log')
@app.route('/sessions/categories/<category>', methods=['GET'])
def get_sessions_by_category(category):
logger.log_text(f"Fetching sessions with category {category}")
sessions_by_category = [session for session in sessions.sessions if category in session['categories']]
logger.log_text(f'Found {len(sessions_by_category)} sessions with category {category}')
return jsonify(sessions_by_category)
# # Other App Routes
Esegui di nuovo il deployment del servizio su Cloud Run utilizzando lo stesso comando della sezione precedente e, una volta eseguito il deployment, esegui alcune chiamate all'endpoint /sessions/categories/<category>.
Vai alla Cloud Console → Logs Explorer.

...e dovresti essere in grado di filtrare queste istruzioni di logging come mostrato di seguito:

Puoi fare clic su una qualsiasi delle istruzioni di log, espanderla e poi fare clic su Explain this log entry, che utilizzerà Gemini per spiegare la voce di log. Tieni presente che se non hai abilitato Gemini in Google Cloud, ti verrà chiesto di abilitare l'API Cloud AI Companion. Procedi come indicato.
Di seguito è riportato un esempio di risposta:

16. Complimenti
Congratulazioni, hai creato correttamente un'applicazione da zero e hai utilizzato Gemini Code Assist in vari aspetti del ciclo di vita dello sviluppo del software, tra cui progettazione, creazione, test e deployment.
Passaggi successivi
Dai un'occhiata ad alcuni di questi codelab...
- Un tour di Duet AI per gli sviluppatori
- Utilizzo di Duet AI durante il ciclo di vita dello sviluppo software
- Aggiungere stile con Duet AI per gli sviluppatori