1. Obiettivi
Lo scopo di questo workshop è fornire agli utenti e ai professionisti una formazione pratica su Duet AI.
In questo codelab imparerai a:
- Attiva Duet AI nel tuo progetto GCP e configuralo per l'utilizzo in un IDE e nella console Cloud.
- Utilizza Duet AI per la generazione, il completamento e la spiegazione del codice.
- Utilizza Duet AI per spiegare e risolvere un problema dell'applicazione.
- Funzionalità di Duet AI come chat IDE e chat multigiro, chat e generazione di codice in linea, azioni intelligenti come spiegazione del codice e riconoscimento della recitazione e altro ancora.
Presentazione narrativa
Per mostrare come Duet AI per gli sviluppatori viene utilizzato in modo autentico nello sviluppo quotidiano, le attività di questo workshop si svolgono in un contesto narrativo.
Un nuovo sviluppatore entra a far parte di un'azienda di e-commerce. Il loro compito è aggiungere un nuovo servizio all'applicazione e-commerce esistente (che è composta da più servizi). Il nuovo servizio fornisce informazioni aggiuntive (dimensioni, peso e così via) sui prodotti nel catalogo prodotti. Questo servizio consentirà costi di spedizione migliori/più economici in base a dimensioni e peso del prodotto.
Poiché lo sviluppatore è nuovo in azienda, utilizzerà Duet AI per la generazione, la spiegazione e la documentazione del codice.
Una volta codificato il servizio, un amministratore della piattaforma utilizzerà Duet AI (chat) per creare l'artefatto (container Docker) e le risorse necessarie per il deployment dell'artefatto su GCP (ad esempio Artifact Registry, autorizzazioni IAM, un repository di codice, infrastruttura di calcolo, ad es. GKE o Cloud Run e così via).
Una volta che l'applicazione viene implementata su GCP, un operatore dell'applicazione/SRE utilizzerà Duet AI (e Cloud Ops) per risolvere un errore nel nuovo servizio.
Utente tipo
Il workshop tratta il seguente personaggio:
- Sviluppatore di applicazioni: sono richieste alcune conoscenze di programmazione e sviluppo software.
Questa variante del workshop su Duet AI è riservata agli sviluppatori. Non è richiesta alcuna conoscenza delle risorse cloud Google Cloud. Gli script per creare le risorse GCP necessarie per eseguire questa applicazione sono disponibili qui. Per eseguire il deployment delle risorse GCP richieste, puoi seguire le istruzioni riportate in questa guida.
2. Preparazione dell'ambiente
Attivare Duet AI
Puoi attivare Duet AI in un progetto GCP tramite API (gcloud o strumenti IaC come Terraform) o tramite la UI della console Cloud.
Per attivare Duet AI in un progetto Google Cloud, devi abilitare l'API Cloud AI Companion e concedere i ruoli Identity and Access Management (IAM) Cloud AI Companion User e Service Usage Viewer agli utenti.
Tramite gcloud
Attiva Cloud Shell:
Configura PROJECT_ID, USER e abilita l'API Cloud AI Companion.
export PROJECT_ID=<YOUR PROJECT ID>
export USER=<YOUR USERNAME> # Use your full LDAP, e.g. name@example.com
gcloud config set project ${PROJECT_ID}
gcloud services enable cloudaicompanion.googleapis.com --project ${PROJECT_ID}
L'output è simile al seguente:
Updated property [core/project]. Operation "operations/acat.p2-60565640195-f37dc7fe-b093-4451-9b12-934649e2a435" finished successfully.
Concedi i ruoli Identity and Access Management (IAM) Cloud AI Companion User e Service Usage Viewer all'account UTENTE. L'API Cloud Companion si trova dietro le funzionalità dell'IDE e della console che utilizzeremo. L'autorizzazione Visualizzatore utilizzo servizio viene utilizzata come controllo rapido prima di attivare la UI nella console (in modo che la UI di Duet venga visualizzata solo nei progetti in cui l'API è abilitata).
gcloud projects add-iam-policy-binding ${PROJECT_ID} \
--member=user:${USER} --role=roles/cloudaicompanion.user
gcloud projects add-iam-policy-binding ${PROJECT_ID} \
--member=user:${USER} --role=roles/serviceusage.serviceUsageViewer
L'output è simile al seguente:
... - members: - user:<YOUR USER ACCOUNT> role: roles/cloudaicompanion.user ... - members: - user:<YOUR USER ACCOUNT> role: roles/serviceusage.serviceUsageViewer
Tramite la console Cloud
Per abilitare l'API, vai alla pagina dell'API Cloud AI Companion nella console Google Cloud.
Nel selettore dei progetti, seleziona un progetto.
Fai clic su Abilita.
La pagina si aggiorna e mostra lo stato Attivato. Duet AI è ora disponibile nel progetto Google Cloud selezionato per tutti gli utenti che dispongono dei ruoli IAM richiesti.
Per concedere i ruoli IAM necessari per utilizzare Duet AI, vai alla pagina IAM.
Nella colonna Entità, trova l'UTENTE per cui vuoi attivare l'accesso a Duet AI, quindi fai clic sull'icona a forma di matita ✏️ Modifica entità in quella riga.
Nel riquadro di accesso Modifica, fai clic su Aggiungi Aggiungi un altro ruolo.
In Seleziona un ruolo, seleziona Utente Cloud AI Companion.
Fai clic su Aggiungi un altro ruolo e seleziona Visualizzatore utilizzo servizio.
Fai clic su Salva.
Configurazione dell'IDE
Gli sviluppatori possono scegliere tra una serie di IDE più adatti alle loro esigenze. L'assistenza per il codice di Duet AI è disponibile in più IDE come Visual Studio Code, IDE JetBrains (IntelliJ, PyCharm, GoLand, WebStorm e altri), Cloud Workstations e Cloud Shell Editor.
In questo lab puoi utilizzare Cloud Workstations o Cloud Shell Editor.
Questo workshop utilizza l'editor di Cloud Shell.
Tieni presente che la configurazione di Cloud Workstations può richiedere 20-30 minuti.
Per utilizzarlo immediatamente, usa l'editor di Cloud Shell.
Apri l'editor di Cloud Shell facendo clic sull'icona a forma di matita ✏️ nella barra dei menu in alto di Cloud Shell.
L'editor di Cloud Shell ha un'interfaccia utente e un'esperienza utente molto simili a VSCode.

Fai clic su CTRL (in Windows)/CMD (in Mac) + , (virgola) per accedere al riquadro Impostazioni.
Nella barra di ricerca, digita "Duet AI".
Assicurati di attivare Cloudcode › Duet AI: Enable e Cloudcode › Duet AI › Inline Suggestions: Enable Auto

Nella barra di stato in basso, fai clic su Cloud Code - Sign In (Cloud Code - Accedi) e segui il flusso di lavoro di accesso.
Se hai già eseguito l'accesso, la barra di stato mostra Cloud Code - No project.
Fai clic su Cloud Code - No project (Cloud Code - Nessun progetto) e nella parte superiore verrà visualizzato un riquadro a discesa delle azioni. Fai clic su Seleziona un progetto Google Cloud.

Inizia a digitare l'ID PROGETTO e il progetto dovrebbe essere visualizzato nell'elenco.

Seleziona PROJECT_ID dall'elenco dei progetti.
La barra di stato inferiore si aggiorna per mostrare l'ID progetto. In caso contrario, potrebbe essere necessario aggiornare la scheda dell'editor di Cloud Shell.
Fai clic sull'icona di Duet AI
nella barra dei menu a sinistra e verrà visualizzata la finestra di chat di Duet AI. Se ricevi un messaggio che ti chiede di selezionare un progetto Google Cloud. Fai clic e seleziona di nuovo il progetto.
Ora vedi la finestra della chat di Duet AI

3. Configurazione dell'infrastruttura

Per eseguire il nuovo servizio di spedizione in Google Cloud, hai bisogno delle seguenti risorse Google Cloud:
- Un'istanza Cloud SQL con un database.
- Un cluster GKE per eseguire il servizio containerizzato.
- Un Artifact Registry per archiviare l'immagine Docker.
- Un repository Cloud Source per il codice.
Nel terminale Cloud Shell, clona il seguente repository ed esegui questi comandi per configurare l'infrastruttura nel tuo progetto GCP.
# Set your project
export PROJECT_ID=<INSERT_YOUR_PROJECT_ID>
gcloud config set core/project ${PROJECT_ID}
# Enable Cloudbuild and grant Cloudbuild SA owner role
export PROJECT_NUMBER=$(gcloud projects describe ${PROJECT_ID} --format 'value(projectNumber)')
gcloud services enable cloudbuild.googleapis.com
gcloud projects add-iam-policy-binding ${PROJECT_ID} --member serviceAccount:${PROJECT_NUMBER}@cloudbuild.gserviceaccount.com --role roles/owner
# Clone the repo
git clone https://github.com/duetailabs/dev.git ~/duetaidev
cd ~/duetaidev
# Run Cloudbuild to create the necessary resources
gcloud builds submit --substitutions=_PROJECT_ID=${PROJECT_ID}
# To destroy all GCP resources, run the following
# gcloud builds submit --substitutions=_PROJECT_ID=${PROJECT_ID} --config=cloudbuild_destroy.yaml
4. Sviluppo di un servizio Flask Python

Il servizio che creeremo sarà composto dai seguenti file. Non devi creare questi file ora, ma li creerai uno alla volta seguendo le istruzioni riportate di seguito:
package-service.yaml: una specifica API aperta per il servizio di pacchi che contiene dati come altezza, larghezza, peso e istruzioni speciali di gestione.data_model.py: modello di dati per la specifica dell'API package-service. Crea anche la tabellapackagesnel database product_details.connect_connector.py- Connessione CloudSQL (definisce il motore, la sessione e l'ORM di base)db_init.py: genera dati di esempio nella tabellapackages.main.py: un servizio Python Flask con un endpointGETper recuperare i dettagli del pacchetto dai datipackagesin base a product_id.test.py- Test delle unitàrequirement.txt- Requisiti PythonDockerfile: per containerizzare questa applicazione
Se riscontri problemi durante gli esercizi, i file finali si trovano tutti nell'APPENDICE di questo codelab come riferimento.
Nel passaggio precedente, hai creato un repository Cloud Source. Clona il repository. Creerai i file dell'applicazione nella cartella del repository clonato.
Nel terminale Cloud Shell, esegui questo comando per clonare il repository.
cd ~ gcloud source repos clone shipping shipping cd ~/shipping
Apri la barra laterale della chat di Duet AI dal menu a sinistra dell'editor di Cloud Shell. L'icona ha l'aspetto di
. Ora puoi utilizzare Duet AI per l'assistenza per il codice.
package-service.yaml
Senza file aperti, chiedi a Duet di generare una specifica OpenAPI per il servizio di spedizione.
Prompt 1: genera una specifica OpenAPI yaml per un servizio che fornisce informazioni su spedizione e pacco dato un ID prodotto numerico. Il servizio deve includere informazioni su altezza, larghezza, profondità, peso e istruzioni speciali per la gestione dei pacchi.

Nella parte superiore destra della finestra del codice generato sono elencate tre opzioni.
Puoi COPY
il codice e INCOLLARLO in un file.
Puoi ADD
il codice nel file attualmente aperto nell'editor.
In alternativa, puoi OPEN
il codice in un nuovo file.
Fai clic su OPEN
il codice in un nuovo file.
Fai clic su CTRL/CMD + s per salvare il file e archiviarlo nella cartella dell'applicazione con il nome package-service.yaml. Fai clic su OK.

Il file finale si trova nella sezione APPENDICE di questo codelab. In caso contrario, apporta manualmente le modifiche necessarie.
Puoi anche provare vari prompt per vedere le risposte di Duet AI.
Reimposta la cronologia della chat di Duet AI facendo clic sull'icona del cestino
nella parte superiore della barra laterale di Duet AI.
data_model.py
Il passaggio successivo consiste nella creazione del file Python del modello di dati per il servizio in base alla specifica OpenAPI.
Con il file package-service.yaml aperto, inserisci il seguente prompt.
Prompt 1: utilizzando l'ORM sqlalchemy di Python, genera un modello di dati per questo servizio API. Includi anche una funzione separata e un punto di ingresso principale che crea le tabelle del database.

Diamo un'occhiata a ogni parte generata. Duet AI è ancora un assistente e, sebbene possa aiutarti a scrivere rapidamente il codice, devi comunque rivedere e comprendere i contenuti generati man mano che procedi.
Innanzitutto, esiste una classe denominata Package di tipo Base che definisce il modello dei dati per il database packages come segue:
class Package(Base):
__tablename__ = 'packages'
id = Column(Integer, primary_key=True)
product_id = Column(String(255))
height = Column(Float)
width = Column(Float)
depth = Column(Float)
weight = Column(Float)
special_handling_instructions = Column(String(255))
Successivamente, devi creare una funzione che crei la tabella nel database, come la seguente:
def create_tables(engine):
Base.metadata.create_all(engine)
Infine, devi creare una funzione principale che esegua la funzione create_tables per creare effettivamente la tabella nel database CloudSQL, come segue:
if __name__ == '__main__':
from sqlalchemy import create_engine
engine = create_engine('sqlite:///shipping.db')
create_tables(engine)
print('Tables created successfully.')
Tieni presente che la funzione main crea un motore utilizzando un database sqlite locale. Per utilizzare CloudSQL, dovrai modificarlo. Lo farai un po' più tardi.
Utilizza OPEN
il codice in un nuovo flusso di lavoro dei file come prima. Salva il codice in un file denominato data_model.py (nota il carattere di sottolineatura nel nome e non il trattino).
Reimposta la cronologia della chat di Duet AI facendo clic sull'icona del cestino
nella parte superiore della barra laterale di Duet AI.
connect-connector.py
Crea il connettore Cloud SQL.
Con il file data_model.py aperto, inserisci i seguenti prompt.
Prompt 1: utilizzando la libreria cloud-sql-python-connector, genera una funzione che inizializza un pool di connessioni per un'istanza Cloud SQL di Postgres.

Tieni presente che la risposta non utilizza la libreria cloud-sql-python-connector. Puoi perfezionare i prompt, per dare un piccolo suggerimento a Duet, aggiungendo dettagli alla stessa chat.
Usiamo un altro prompt.
Prompt 2: deve utilizzare la libreria cloud-sql-python-connector.

Assicurati che utilizzi la libreria cloud-sql-python-connector.
Utilizza OPEN
il codice in un nuovo flusso di lavoro dei file come prima. Salva il codice in un file denominato connect_conector.py. Potresti dover importare manualmente la libreria pg8000. Consulta il file riportato di seguito.
Cancella la cronologia della chat di Duet AI e, con il file connect_connector.py aperto, genera l'ORM DB engine, sessionmaker e base da utilizzare nell'applicazione.
Prompt 1: crea un motore, una classe sessionmaker e Base ORM utilizzando il metodo connect_with_connector

La risposta potrebbe aggiungere engine, Session e Base al file connect_connector.py.
Il file finale si trova nella sezione APPENDICE di questo codelab. In caso contrario, apporta manualmente le modifiche necessarie.
Puoi anche provare vari prompt per vedere la potenziale variazione delle risposte di Duet AI.
Reimposta la cronologia della chat di Duet AI facendo clic sull'icona del cestino
nella parte superiore della barra laterale di Duet AI.
Aggiornamento di data_model.py
Per creare una tabella nel database Cloud SQL, devi utilizzare il motore creato nel passaggio precedente (nel file connect_connector.py).
Cancella la cronologia della chat Duet AI. Apri il file data_model.py. Prova il seguente prompt.
Prompt 1: nella funzione principale, importa e utilizza il motore da connect_connector.py

Dovresti vedere la risposta che importa engine da connect_connector (per Cloud SQL). create_table utilizza questo motore (anziché il database locale sqlite predefinito).
Aggiorna il file data_model.py.
Il file finale si trova nella sezione APPENDICE di questo codelab. In caso contrario, apporta manualmente le modifiche necessarie.
Puoi anche provare vari prompt per vedere le diverse risposte di Duet AI.
Reimposta la cronologia della chat di Duet AI facendo clic sull'icona del cestino
nella parte superiore della barra laterale di Duet AI.
requirements.txt
Crea un file requirements.txt per l'applicazione.
Apri sia connect_connector.py sia il file data_model.py e inserisci il seguente prompt.
Prompt 1: genera un file dei requisiti pip per questo modello di dati e servizio
Prompt 2: genera un file dei requisiti pip per questo modello di dati e servizio utilizzando le versioni più recenti

Verifica che i nomi e le versioni siano corretti. Ad esempio, nella risposta riportata sopra, il nome e la versione di google-cloud-sql-connecter non sono corretti. Correggi manualmente le versioni e crea un file requirements.txt simile a questo:
cloud-sql-python-connector==1.2.4
sqlalchemy==1.4.36
pg8000==1.22.0
Nel terminale dei comandi, esegui questo comando:
pip3 install -r requirements.txt
Reimposta la cronologia della chat di Duet AI facendo clic sull'icona del cestino
nella parte superiore della barra laterale di Duet AI.
Creazione della tabella dei pacchetti in Cloud SQL
Imposta le variabili di ambiente per il connettore del database Cloud SQL.
export INSTANCE_NAME=$(gcloud sql instances list --format='value(name)')
export INSTANCE_CONNECTION_NAME=$(gcloud sql instances describe ${INSTANCE_NAME} --format="value(connectionName)")
export DB_USER=evolution
export DB_PASS=evolution
export DB_NAME=product_details
Ora esegui data_model.py.
python data_model.py
L'output è simile al seguente (controlla il codice per vedere cosa è effettivamente previsto):
Tables created successfully.
Connettiti all'istanza Cloud SQL e verifica che il database sia stato creato.
gcloud sql connect ${INSTANCE_NAME} --user=evolution --database=product_details
Dopo aver inserito la password (anche evolution), recupera le tabelle.
product_details=> \dt
L'output è simile al seguente:
List of relations Schema | Name | Type | Owner --------+----------+-------+----------- public | packages | table | evolution (1 row)
Puoi anche controllare il modello di dati e i dettagli della tabella.
product_details=> \d+ packages
L'output è simile al seguente:
Table "public.packages"
Column | Type | Collation | Nullable | Default | Storage | Compression | Stats target | Description
-------------------------------+-------------------+-----------+----------+--------------------------------------+----------+-------------+--------------+-------------
id | integer | | not null | nextval('packages_id_seq'::regclass) | plain | | |
product_id | integer | | not null | | plain | | |
height | double precision | | not null | | plain | | |
width | double precision | | not null | | plain | | |
depth | double precision | | not null | | plain | | |
weight | double precision | | not null | | plain | | |
special_handling_instructions | character varying | | | | extended | | |
Indexes:
"packages_pkey" PRIMARY KEY, btree (id)
Access method: heap
Digita \q per uscire da Cloud SQL.
db_init.py
A questo punto, aggiungiamo alcuni dati di esempio alla tabella packages.
Cancella la cronologia della chat Duet AI. Con il file data_model.py aperto, prova i seguenti prompt.
Prompt 1: genera una funzione che crea 10 righe di pacchetti di esempio e le inserisce nella tabella dei pacchetti
Prompt 2: utilizzando la sessione di connect_connector, genera una funzione che crea 10 righe di pacchetti di esempio e le inserisce nella tabella dei pacchetti

Utilizza OPEN
il codice in un nuovo flusso di lavoro dei file come prima. Salva il codice in un file denominato db_init.py.
Il file finale si trova nella sezione APPENDICE di questo codelab. In caso contrario, apporta manualmente le modifiche necessarie.
Puoi anche provare vari prompt per vedere le diverse risposte di Duet AI.
Reimposta la cronologia della chat di Duet AI facendo clic sull'icona del cestino
nella parte superiore della barra laterale di Duet AI.
Creazione di dati di esempio sui pacchetti
Esegui db_init.py dalla riga di comando.
python db_init.py
L'output è simile al seguente:
Packages created successfully.
Connettiti di nuovo all'istanza Cloud SQL e verifica che i dati di esempio siano stati aggiunti alla tabella dei pacchetti.
Connettiti all'istanza Cloud SQL e verifica che il database sia stato creato.
gcloud sql connect ${INSTANCE_NAME} --user=evolution --database=product_details
Dopo aver inserito la password (anche evolution), recupera tutti i dati dalla tabella dei pacchetti.
product_details=> SELECT * FROM packages;
L'output è simile al seguente:
id | product_id | height | width | depth | weight | special_handling_instructions ----+------------+--------+-------+-------+--------+----------------------------------- 1 | 0 | 10 | 10 | 10 | 10 | No special handling instructions. 2 | 1 | 10 | 10 | 10 | 10 | No special handling instructions. 3 | 2 | 10 | 10 | 10 | 10 | No special handling instructions. 4 | 3 | 10 | 10 | 10 | 10 | No special handling instructions. 5 | 4 | 10 | 10 | 10 | 10 | No special handling instructions. 6 | 5 | 10 | 10 | 10 | 10 | No special handling instructions. 7 | 6 | 10 | 10 | 10 | 10 | No special handling instructions. 8 | 7 | 10 | 10 | 10 | 10 | No special handling instructions. 9 | 8 | 10 | 10 | 10 | 10 | No special handling instructions. 10 | 9 | 10 | 10 | 10 | 10 | No special handling instructions. (10 rows)
Digita \q per uscire da Cloud SQL.
main.py
Con i file data_model.py, package-service.yaml e connect_connector.py aperti, crea un main.py per l'applicazione.
Prompt 1: Using the python flask library - create an implementation that uses http rest endpoints for this service
Prompt 2: utilizzando la libreria Flask di Python, crea un'implementazione che utilizzi endpoint REST HTTP per questo servizio. Importa e utilizza SessionMaker da connect_conector.py per i dati dei pacchetti.
Prompt 3: utilizzando la libreria Python Flask, crea un'implementazione che utilizzi endpoint REST HTTP per questo servizio. Importa e utilizza Package da data_model.py e SessionMaker da connect_conector.py per i dati dei pacchetti.
Prompt 4: Using the python flask library - create an implementation that uses http rest endpoints for this service. import and use Package from the data_model.py and the SessionMaker from connect_conector.py to for packages data. Utilizza l'IP host 0.0.0.0 per app.run

Aggiorna i requisiti per main.py.
Prompt: crea il file requirements per main.py

Aggiungi questo al file requirements.txt. Assicurati di utilizzare Flask versione 3.0.0.
Utilizza OPEN
il codice in un nuovo flusso di lavoro dei file come prima. Salva il codice in un file denominato main.py.
Il file finale si trova nella sezione APPENDICE di questo codelab. In caso contrario, apporta manualmente le modifiche necessarie.
Reimposta la cronologia della chat di Duet AI facendo clic sull'icona del cestino
nella parte superiore della barra laterale di Duet AI.
5. Testare ed eseguire l'applicazione
Installa i requisiti.
pip3 install -r requirements.txt
Esegui main.py.
python main.py
L'output è simile al seguente:
* Serving Flask app 'main' * Debug mode: off 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:5000 * Running on http://10.88.0.3:5000 Press CTRL+C to quit
Da un secondo terminale, testa l'endpoint /packages/<product_id>.
curl localhost:5000/packages/1
L'output è simile al seguente:
{"depth":10.0,"height":10.0,"special_handling_instructions":"No special handling instructions.","weight":10.0,"width":10.0}
Puoi anche testare qualsiasi altro ID prodotto nei dati di esempio.
Inserisci CTRL_C per uscire dal container Docker in esecuzione nel terminale.
Generazione di test delle unità
Con il file main.py aperto, genera i test delle unità.
Prompt 1: genera test delle unità.

Utilizza OPEN
il codice in un nuovo flusso di lavoro dei file come prima. Salva il codice in un file denominato test.py.
Nella funzione test_get_package, è necessario definire un product_id. Puoi aggiungerlo manualmente.
Il file finale si trova nella sezione APPENDICE di questo codelab. In caso contrario, apporta manualmente le modifiche necessarie.
Reimposta la cronologia della chat di Duet AI facendo clic sull'icona del cestino
nella parte superiore della barra laterale di Duet AI.
Esecuzione dei test delle unità
Esegui il test delle unità.
python test.py
L'output è simile al seguente:
. ---------------------------------------------------------------------- Ran 1 test in 1.061s OK
Chiudi tutti i file nell'editor di Cloud Shell e cancella la cronologia della chat facendo clic sull'icona del cestino
nella barra di stato in alto.
Dockerfile
Crea un Dockerfile per questa applicazione.
Apri main.py e prova i seguenti prompt.
Prompt 1: genera un Dockerfile per questa applicazione.
Prompt 2: genera un Dockerfile per questa applicazione. Copia tutti i file nel container.

Devi anche impostare ENVARS per INSTANCE_CONNECTION_NAME, DB_USER, DB_PASS e DB_NAME. Puoi farlo manualmente. Il Dockerfile dovrebbe avere il seguente aspetto:
FROM python:3.10-slim
WORKDIR /app
COPY . ./
RUN pip install -r requirements.txt
# Add these manually for your project
ENV INSTANCE_CONNECTION_NAME=YOUR_INSTANCE_CONNECTION_NAME
ENV DB_USER=evolution
ENV DB_PASS=evolution
ENV DB_NAME=product_details
CMD ["python", "main.py"]
Utilizza OPEN
il codice in un nuovo flusso di lavoro dei file come prima. Salva il codice in un file denominato Dockerfile.
Il file finale si trova nella sezione APPENDICE di questo codelab. In caso contrario, apporta manualmente le modifiche necessarie.
Esecuzione locale dell'applicazione
Con Dockerfile aperto, prova il seguente prompt.
Prompt 1: come faccio a eseguire localmente un container utilizzando questo Dockerfile?

Segui le istruzioni.
# Build docker build -t shipping . # And run docker run -p 5000:5000 -it shipping
L'output è simile al seguente:
* Serving Flask app 'main' * Debug mode: off 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:5000 * Running on http://172.17.0.2:5000 Press CTRL+C to quit
Da una seconda finestra del terminale, accedi al container.
curl localhost:5000/packages/1
L'output è simile al seguente:
{"depth":10.0,"height":10.0,"special_handling_instructions":"No special handling instructions.","weight":10.0,"width":10.0}
L'applicazione containerizzata funziona.
Inserisci CTRL_C per uscire dal container Docker in esecuzione nel terminale.
Creazione dell'immagine container in Artifact Registry
Crea l'immagine container ed eseguine il push in Artifact Registry.
cd ~/shipping
gcloud auth configure-docker us-central1-docker.pkg.dev
docker build -t us-central1-docker.pkg.dev/${PROJECT_ID}/shipping/shipping .
docker push us-central1-docker.pkg.dev/${PROJECT_ID}/shipping/shipping
Il container dell'applicazione ora si trova in us-central1-docker.pkg.dev/${PROJECT_ID}/shipping/shipping, che può essere sottoposto a deployment in GKE.
6. Deployment dell'applicazione nel cluster GKE
Quando hai creato le risorse GCP per questo workshop, è stato creato un cluster GKE Autopilot. Connettiti al cluster GKE.
gcloud container clusters get-credentials gke1 \
--region=us-central1
Annota il service account Kubernetes predefinito con il service account Google.
kubectl annotate serviceaccount default iam.gke.io/gcp-service-account=cloudsqlsa@${PROJECT_ID}.iam.gserviceaccount.com
L'output è simile al seguente:
serviceaccount/default annotated
Prepara e applica il file k8s.yaml.
cp ~/duetaidev/k8s.yaml_tmpl ~/shipping/.
export INSTANCE_NAME=$(gcloud sql instances list --format='value(name)')
export INSTANCE_CONNECTION_NAME=$(gcloud sql instances describe ${INSTANCE_NAME} --format="value(connectionName)")
export IMAGE_REPO=us-central1-docker.pkg.dev/${PROJECT_ID}/shipping/shipping
envsubst < ~/shipping/k8s.yaml_tmpl > k8s.yaml
kubectl apply -f k8s.yaml
L'output è simile al seguente:
deployment.apps/shipping created service/shipping created
Attendi che i pod siano in esecuzione e che al servizio sia assegnato un indirizzo IP del bilanciatore del carico esterno.
kubectl get pods kubectl get service shipping
L'output è simile al seguente:
# kubectl get pods NAME READY STATUS RESTARTS AGE shipping-f5d6f8d5-56cvk 1/1 Running 0 4m47s shipping-f5d6f8d5-cj4vv 1/1 Running 0 4m48s shipping-f5d6f8d5-rrdj2 1/1 Running 0 4m47s # kubectl get service shipping NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE shipping LoadBalancer 34.118.225.125 34.16.39.182 80:30076/TCP 5m41s
Per i cluster GKE Autopilot, attendi qualche istante finché le risorse non sono pronte.
Accedi al servizio tramite l'indirizzo EXTERNAL-IP.
export EXTERNAL_IP=$(kubectl get svc shipping --output jsonpath='{.status.loadBalancer.ingress[0].ip}')
curl http://${EXTERNAL_IP}/packages/1
L'output è simile al seguente:
{"depth":10.0,"height":10.0,"special_handling_instructions":"No special handling instructions.","weight":10.0,"width":10.0}
7. Crediti extra: risoluzione dei problemi dell'applicazione
Rimuovi il ruolo IAM Client Cloud SQL dal service account cloudsqlsa. Ciò causa un errore di connessione al database Cloud SQL.
gcloud projects remove-iam-policy-binding ${PROJECT_ID} \
--member="serviceAccount:cloudsqlsa@${PROJECT_ID}.iam.gserviceaccount.com" \
--role="roles/cloudsql.client"
Riavvia il pod di spedizione.
kubectl rollout restart deployment shipping
Dopo il riavvio del pod, prova ad accedere di nuovo al servizio shipping.
export EXTERNAL_IP=$(kubectl get svc shipping --output jsonpath='{.status.loadBalancer.ingress[0].ip}')
curl http://${EXTERNAL_IP}/packages/1
L'output è simile al seguente:
... <title>500 Internal Server Error</title> <h1>Internal Server Error</h1> <p>The server encountered an internal error and was unable to complete your request. Either the server is overloaded or there is an error in the application.</p>
Esamina i log andando a Kubernetes Engine > Workload.

Fai clic sul deployment shipping e poi sulla scheda Log.

Fai clic sull'icona Visualizza in Esplora log
sul lato destro della barra di stato. Si apre una nuova finestra di Esplora log.

Fai clic su una delle voci di errore Traceback, quindi fai clic su Spiega questa voce di log.

Puoi leggere la spiegazione dell'errore.
Ora chiediamo a Duet AI di aiutarci a risolvere l'errore.
Prova il seguente prompt.
Prompt 1: Aiutami a risolvere questo errore

Inserisci il messaggio di errore nel prompt.
Prompt 2: Forbidden: Authenticated IAM principal does not seem authorized to make API request. Verifica che l'API Cloud SQL Admin sia abilitata nel tuo progetto GCP e che il ruolo "Client Cloud SQL" sia stato concesso all'entità IAM

E poi
Prompt 3: come faccio ad assegnare il ruolo Client Cloud SQL a un service account Google utilizzando gcloud?

Assegna il ruolo Client Cloud SQL a cloudsqlsa.
gcloud projects add-iam-policy-binding ${PROJECT_ID} \
--member="serviceAccount:cloudsqlsa@${PROJECT_ID}.iam.gserviceaccount.com" \
--role="roles/cloudsql.client"
Attendi qualche istante e prova ad accedere di nuovo all'applicazione.
export EXTERNAL_IP=$(kubectl get svc shipping --output jsonpath='{.status.loadBalancer.ingress[0].ip}')
curl http://${EXTERNAL_IP}/packages/1
L'output è simile al seguente:
{"depth":10.0,"height":10.0,"special_handling_instructions":"No special handling instructions.","weight":10.0,"width":10.0}
Hai utilizzato correttamente Duet AI in Cloud Logging, Esplora log e nella funzionalità Spiegazione log per risolvere il problema.
8. Conclusione
Complimenti! Hai completato correttamente questo codelab.
In questo codelab hai imparato:
- Attiva Duet AI nel tuo progetto GCP e configuralo per l'utilizzo in un IDE e nella console Cloud.
- Utilizza Duet AI per la generazione, il completamento e la spiegazione del codice.
- Utilizza Duet AI per spiegare e risolvere un problema dell'applicazione.
- Funzionalità di Duet AI come chat IDE e chat multigiro, chat e generazione di codice in linea, azioni intelligenti come spiegazione del codice e riconoscimento della recitazione e altro ancora.
9. Appendice
package-service.yaml
swagger: "2.0"
info:
title: Shipping and Package Information API
description: This API provides information about shipping and packages.
version: 1.0.0
host: shipping.googleapis.com
schemes:
- https
produces:
- application/json
paths:
/packages/{product_id}:
get:
summary: Get information about a package
description: This method returns information about a package, including its height, width, depth, weight, and any special handling instructions.
parameters:
- name: product_id
in: path
required: true
type: integer
format: int64
responses:
"200":
description: A successful response
schema:
type: object
properties:
height:
type: integer
format: int64
width:
type: integer
format: int64
depth:
type: integer
format: int64
weight:
type: integer
format: int64
special_handling_instructions:
type: string
"404":
description: The product_id was not found
data_model.py
from sqlalchemy import Column, Integer, String, Float
from sqlalchemy.ext.declarative import declarative_base
from connect_connector import engine
Base = declarative_base()
class Package(Base):
__tablename__ = 'packages'
id = Column(Integer, primary_key=True)
product_id = Column(Integer, nullable=False)
height = Column(Float, nullable=False)
width = Column(Float, nullable=False)
depth = Column(Float, nullable=False)
weight = Column(Float, nullable=False)
special_handling_instructions = Column(String, nullable=True)
def create_tables():
Base.metadata.create_all(engine)
if __name__ == '__main__':
create_tables()
print('Tables created successfully.')
connect_connector.py
import os
from google.cloud.sql.connector import Connector, IPTypes
import sqlalchemy
# You may need to manually import pg8000 and Base as follows
import pg8000
from sqlalchemy.ext.declarative import declarative_base
def connect_with_connector() -> sqlalchemy.engine.base.Engine:
"""Initializes a connection pool for a Cloud SQL instance of Postgres."""
# Note: Saving credentials in environment variables is convenient, but not
# secure - consider a more secure solution such as
# Cloud Secret Manager (https://cloud.google.com/secret-manager) to help
# keep secrets safe.
instance_connection_name = os.environ[
"INSTANCE_CONNECTION_NAME"
] # e.g. 'project:region:instance'
db_user = os.environ["DB_USER"] # e.g. 'my-database-user'
db_pass = os.environ["DB_PASS"] # e.g. 'my-database-password'
db_name = os.environ["DB_NAME"] # e.g. 'my-database'
ip_type = IPTypes.PRIVATE if os.environ.get("PRIVATE_IP") else IPTypes.PUBLIC
connector = Connector()
def getconn() -> sqlalchemy.engine.base.Engine:
conn: sqlalchemy.engine.base.Engine = connector.connect(
instance_connection_name,
"pg8000",
user=db_user,
password=db_pass,
db=db_name,
ip_type=ip_type,
)
return conn
pool = sqlalchemy.create_engine(
"postgresql+pg8000://",
creator=getconn,
# ...
)
return pool
# Create a connection pool
engine = connect_with_connector()
# Create a sessionmaker class to create new sessions
SessionMaker = sqlalchemy.orm.sessionmaker(bind=engine)
# Create a Base class for ORM
# You may need to manually fix the following
Base = declarative_base()
db_init.py
from sqlalchemy import create_engine
from sqlalchemy.orm import sessionmaker
from connect_connector import engine
from data_model import Package
def create_packages():
# Create a session
session = sessionmaker(bind=engine)()
# Create 10 sample packages
for i in range(10):
package = Package(
product_id=i,
height=10.0,
width=10.0,
depth=10.0,
weight=10.0,
special_handling_instructions="No special handling instructions."
)
# Add the package to the session
session.add(package)
# Commit the changes
session.commit()
if __name__ == '__main__':
create_packages()
print('Packages created successfully.')
main.py
from flask import Flask, request, jsonify
from data_model import Package
from connect_connector import SessionMaker
app = Flask(__name__)
session_maker = SessionMaker()
@app.route("/packages/<int:product_id>", methods=["GET"])
def get_package(product_id):
"""Get information about a package."""
session = session_maker
package = session.query(Package).filter(Package.product_id == product_id).first()
if package is None:
return jsonify({"message": "Package not found."}), 404
return jsonify(
{
"height": package.height,
"width": package.width,
"depth": package.depth,
"weight": package.weight,
"special_handling_instructions": package.special_handling_instructions,
}
), 200
if __name__ == "__main__":
app.run(host="0.0.0.0")
test.py
import unittest
from data_model import Package
from connect_connector import SessionMaker
from main import app
class TestPackage(unittest.TestCase):
def setUp(self):
self.session_maker = SessionMaker()
def tearDown(self):
self.session_maker.close()
def test_get_package(self):
"""Test the `get_package()` function."""
package = Package(
product_id=11, # Ensure that the product_id different from the sample data
height=10,
width=10,
depth=10,
weight=10,
special_handling_instructions="Fragile",
)
session = self.session_maker
session.add(package)
session.commit()
response = app.test_client().get("/packages/11")
self.assertEqual(response.status_code, 200)
self.assertEqual(
response.json,
{
"height": 10,
"width": 10,
"depth": 10,
"weight": 10,
"special_handling_instructions": "Fragile",
},
)
if __name__ == "__main__":
unittest.main()
requirements.txt
cloud-sql-python-connector==1.2.4
sqlalchemy==1.4.36
pg8000==1.22.0
Flask==3.0.0
gunicorn==20.1.0
psycopg2-binary==2.9.3
Dockerfile
FROM python:3.10-slim
WORKDIR /app
COPY . ./
RUN pip install -r requirements.txt
# Add these manually for your project
ENV INSTANCE_CONNECTION_NAME=YOUR_INSTANCE_CONNECTION_NAME
ENV DB_USER=evolution
ENV DB_PASS=evolution
ENV DB_NAME=product_details
CMD ["python", "main.py"]