1. Obiettivi
Lo scopo di questo workshop è fornire una formazione pratica su Duet AI a utenti e professionisti.
In questo codelab, imparerai quanto segue:
- Attiva Duet AI nel tuo progetto Google Cloud e configuralo per l'utilizzo in un IDE e nella console Cloud.
- Usa 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 la chat IDE e la chat multi-turno, la generazione di codice in chat e in linea, le azioni intelligenti come la spiegazione del codice e la conferma delle citazioni e altro ancora.
Narrative
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. Ha il compito di aggiungere un nuovo servizio all'applicazione di e-commerce esistente (composta da più servizi). Il nuovo servizio fornisce informazioni aggiuntive (dimensioni, peso e così via) sui prodotti presenti nel catalogo. Questo servizio consentirà costi di spedizione migliori/più economici in base alle dimensioni e al peso dei prodotti.
Poiché lo sviluppatore non ha esperienza con l'azienda, utilizzerà Duet AI per la generazione, la spiegazione e la documentazione del codice.
Dopo la codifica del servizio, un amministratore di piattaforma utilizzerà Duet AI (chat) per creare l'artefatto (container Docker) e le risorse necessarie per il deployment dell'artefatto in Google Cloud (ad esempio Artifact Registry, autorizzazioni IAM, un repository di codice, un'infrastruttura di calcolo, ad esempio GKE o CloudRun e così via)
Una volta eseguito il deployment dell'applicazione in Google Cloud, un operatore dell'applicazione/SRE utilizzerà Duet AI (e Cloud Ops) per risolvere un errore nel nuovo servizio.
Utente tipo
Il workshop riguarda i seguenti utenti tipo:
- Sviluppatore di applicazioni: è richiesta una certa conoscenza della programmazione e dello sviluppo software.
Questa variante del workshop Duet AI è riservata agli sviluppatori. Non è richiesta alcuna conoscenza delle risorse cloud di Google Cloud. Gli script per la creazione delle risorse Google Cloud richieste per l'esecuzione dell'applicazione sono disponibili qui. Puoi seguire le istruzioni in questa guida per eseguire il deployment delle risorse Google Cloud richieste.
2. preparazione dell'ambiente
Attivazione di Duet AI
Puoi attivare Duet AI in un progetto Google Cloud tramite API (strumenti gcloud o IaC come Terraform) o tramite l'interfaccia utente della console Cloud.
Per attivare Duet AI in un progetto Google Cloud, devi abilitare l'API Cloud AI Companion e concedere agli utenti i ruoli Identity and Access Management (IAM) Cloud AI Companion User e Service Usage Viewer.
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 USER. L'API Cloud Companion è alla base delle funzionalità sia nell'IDE che nella console che utilizzeremo. L'autorizzazione Visualizzatore utilizzo dei servizi viene utilizzata come controllo rapido prima di abilitare l'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 Cloud Console
Per abilitare l'API, vai alla pagina dell'API Cloud AI Companion nella console Google Cloud.
Nel selettore di 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 USER per cui vuoi abilitare l'accesso a Duet AI, quindi fai clic sull'icona a forma di matita ✏️ Modifica entità nella riga corrispondente.
Nel riquadro di accesso Modifica, fai clic su Aggiungi Aggiungi un altro ruolo.
In Seleziona un ruolo, seleziona Cloud AI Companion User (Utente Cloud AI Companion).
Fai clic su Aggiungi un altro ruolo e seleziona Service Usage Viewer.
Fai clic su Salva.
Configurazione di IDE
Gli sviluppatori possono scegliere tra una varietà di IDE a seconda delle 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 editor di Cloud Shell.
In questo lab puoi utilizzare Cloud Workstations o l'editor di Cloud Shell.
Questo workshop utilizza l'editor di Cloud Shell.
Tieni presente che la configurazione di Cloud Workstations può richiedere 20-30 minuti.
Per utilizzarle 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 una UI e una UX molto simili a VSCode.
Fai clic su Ctrl (in Windows)/CMD (su Mac) + , (virgola) per accedere al riquadro Impostazioni.
Nella barra di ricerca, digita "duet ai".
Assicurati o abilita Cloudcode › Duet AI: Abilita e Cloudcode › Duet AI › Inline Suggestions: Abilita Auto
Nella barra di stato in basso, fai clic su Cloud Code - Accedi e segui il flusso di lavoro di accesso.
Se hai già eseguito l'accesso, la barra di stato mostra Cloud Code - Nessun progetto.
Fai clic su Cloud Code - Nessun progetto per visualizzare in alto un riquadro a discesa delle azioni. Fai clic su Seleziona un progetto Google Cloud.
Inizia a digitare l'ID PROGETTO e il progetto verrà visualizzato nell'elenco.
Seleziona il tuo PROJECT_ID dall'elenco dei progetti.
La barra di stato in basso si aggiorna mostrando il tuo ID progetto. In caso contrario, potresti dover 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 della chat di Duet AI. Se viene visualizzato il messaggio Seleziona progetto Google Cloud. Fai clic e seleziona nuovamente 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, ti occorrono le 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 di codice sorgente Cloud per il codice.
Nel terminale Cloud Shell, clona il seguente repository ed esegui i comandi seguenti per configurare l'infrastruttura nel tuo progetto Google Cloud.
# 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 Python Flask
Il servizio che creeremo sarà composto in definitiva dai seguenti file. Non è necessario creare questi file adesso; dovrai crearli uno alla volta seguendo le istruzioni riportate di seguito:
package-service.yaml
: una specifica API aperta per il servizio pacchetti e contenente dati quali altezza, larghezza, peso e istruzioni di gestione speciali.data_model.py
: modello dei dati per la specifica dell'API Package-Service. Crea anche la tabellapackages
nel database product_details.connect_connector.py
- Connessione Cloud SQL (definisce motore, sessione e ORM di base)db_init.py
- Genera dati di esempio nella tabellapackages
.main.py
- Un servizio Python Flask con un endpointGET
per recuperare i dettagli del pacchetto dai datipackages
in base a product_id.test.py
- Test delle unitàrequirement.txt
: requisiti PythonDockerfile
- Per containerizzare questa applicazione
Se riscontri problemi durante gli esercizi, tutti i file finali si trovano nell'APPENDICE di questo codelab come riferimento.
Nel passaggio precedente, hai creato un repository di codice sorgente Cloud. Clonare 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 è simile a . Ora puoi utilizzare Duet AI per l'assistenza per la programmazione.
package-service.yaml
Senza alcun file aperto, chiedi a Duet di generare una specifica OpenAPI per il servizio di spedizione.
Prompt 1: genera una specifica yaml OpenAPI per un servizio che fornisce informazioni sulla spedizione e sul pacco tramite un ID prodotto numerico. Il servizio deve includere informazioni su altezza, larghezza, profondità e peso dei pacchi ed eventuali istruzioni speciali per la gestione.
Ci sono tre opzioni elencate in alto a destra nella finestra del codice generato.
Puoi COPY
il codice e incollarlo in un file.
Puoi ADD
modificare il codice nel file attualmente aperto nell'Editor.
In alternativa, puoi OPEN
il codice in un nuovo file.
Fai clic sul OPEN
del codice in un nuovo file.
Fai clic su CTRL/CMD + s
per salvare il file e archivialo nella cartella dell'applicazione con il nome file denominato package-service.yaml
. Fai clic su OK.
Il file finale si trova nella sezione APPENDICE di questo codelab. In caso contrario, apporta le modifiche appropriate manualmente.
Puoi anche provare vari prompt per vedere le risposte di Duet AI.
Reimposta la cronologia chat di Duet AI facendo clic sull'icona del cestino nella parte superiore della barra laterale di Duet AI.
data_model.py
Quindi, creerai il file Python del modello dei dati per il servizio in base alla specifica OpenAPI.
Con il file package-service.yaml
aperto, inserisci il seguente prompt.
Prompt 1: utilizzando il mapper ORM Python sqlalchemy, genera un modello 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 codice rapidamente, dovresti comunque rivedere i contenuti generati e comprenderli man mano che procedi.
Innanzitutto, c'è una Class denominata Package
di kind 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, hai bisogno di una funzione che crei la tabella nel database come segue:
def create_tables(engine):
Base.metadata.create_all(engine)
Infine, è necessaria una funzione principale che esegua la funzione create_tables
per creare effettivamente la tabella nel database Cloud SQL, come riportato di seguito:
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 Cloud SQL, devi modificarlo. Questo sarà possibile dopo.
Utilizzando OPEN
il codice in un nuovo flusso di lavoro di file come prima. Salva il codice in un file denominato
data_model.py
(nota il trattino basso nel nome e non un trattino).
Reimposta la cronologia chat di Duet AI facendo clic sull'icona del cestino nella parte superiore della barra laterale di Duet AI.
connect-connector.py
Creare 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 a Duet un sollecito, aggiungendo specifiche allo stesso thread della chat.
Usiamo un altro prompt.
Prompt 2: devi utilizzare la libreria cloud-sql-python-connector.
Assicurati che utilizzi la raccolta cloud-sql-python-connector
.
Utilizzando OPEN
il codice in un nuovo flusso di lavoro di file come prima. Salva il codice in un file denominato
connect_conector.py
. Potresti dover importare manualmente la libreria pg8000
. Consulta il file di seguito.
Cancella la cronologia chat di Duet AI e, con il file connect_connector.py
aperto, genera gli ORM DB engine
, sessionmaker
e base
da utilizzare nell'applicazione.
Prompt 1: crea un motore, una classe sessionmaker e un ORM di base utilizzando il metodo connect_with_connector
La risposta può 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 le modifiche appropriate manualmente.
Puoi anche provare vari prompt per vedere la potenziale variazione delle risposte di Duet AI.
Reimposta la cronologia chat di Duet AI facendo clic sull'icona del cestino nella parte superiore della barra laterale di Duet AI.
Aggiornamento di data_model.py
Devi usare il motore che hai creato nel passaggio precedente (nel file connect_connector.py
) per creare una tabella nel database Cloud SQL.
Cancella la cronologia chat di 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 le modifiche appropriate manualmente.
Puoi anche provare vari prompt per vedere varie risposte di Duet AI.
Reimposta la cronologia 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 questo servizio
Prompt 2: genera un file dei requisiti pip per questo modello di dati e questo servizio utilizzando le versioni più recenti
Verifica che i nomi e le versioni siano corretti. Ad esempio, nella risposta precedente, il nome e la versione di google-cloud-sql-connecter
sono entrambi errati. Correggi manualmente le versioni e crea un file requirements.txt
simile al seguente:
cloud-sql-python-connector==1.2.4
sqlalchemy==1.4.36
pg8000==1.22.0
Nel terminale di comando, esegui questo comando:
pip3 install -r requirements.txt
Reimposta la cronologia 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 di 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 (anch'essa evolution), ottieni 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 dei 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
Successivamente, aggiungiamo alcuni dati di esempio alla tabella packages
.
Cancella la cronologia chat di 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 ne esegue il commit nella tabella pacchetti
Prompt 2: utilizzando la sessione di connect_connector, genera una funzione che crea 10 righe di pacchetti di esempio e ne esegue il commit nella tabella pacchetti.
Utilizzando OPEN
il codice in un nuovo flusso di lavoro di 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 le modifiche appropriate manualmente.
Puoi anche provare vari prompt per vedere varie risposte di Duet AI.
Reimposta la cronologia chat di Duet AI facendo clic sull'icona del cestino nella parte superiore della barra laterale di Duet AI.
Creazione di dati dei pacchetti di esempio
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 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 (anch'essa 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: Utilizzo della libreria Python Flask. Crea un'implementazione che utilizzi endpoint REST HTTP per questo servizio
Prompt 2: Utilizzo della libreria Python Flask, crea un'implementazione che utilizzi endpoint REST HTTP per questo servizio. importare e utilizzare SessionMaker da connect_conector.py a per i dati dei pacchetti.
Prompt 3: Utilizzando la libreria Python Flask, crea un'implementazione che utilizzi endpoint REST HTTP per questo servizio. importare e utilizzare Package da data_model.py e SessionMaker da connect_conector.py a per i dati dei pacchetti.
Prompt 4: Utilizzando la libreria Python Flask, crea un'implementazione che utilizzi endpoint REST HTTP per questo servizio. importare e utilizzare Package da data_model.py e SessionMaker da connect_conector.py a per i dati dei pacchetti. Utilizza l'IP host 0.0.0.0 per app.run
Aggiorna i requisiti per main.py
.
Prompt: crea il file dei requisiti per main.py
Aggiungi questo al file requirements.txt
. Assicurati di utilizzare Flask versione 3.0.0.
Utilizzando OPEN
il codice in un nuovo flusso di lavoro di 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 le modifiche appropriate manualmente.
Reimposta la cronologia 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 dei test delle unità in corso...
Con il file main.py
aperto, genera test delle unità.
Prompt 1: genera i test delle unità.
Utilizzando OPEN
il codice in un nuovo flusso di lavoro di 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 le modifiche appropriate manualmente.
Reimposta la cronologia 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 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"]
Utilizzando OPEN
il codice in un nuovo flusso di lavoro di 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 le modifiche appropriate manualmente.
Esecuzione dell'applicazione in locale
Con il Dockerfile
aperto, prova il seguente prompt.
Prompt 1: come posso 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
Accedi al container da una seconda finestra del terminale.
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 esegui il push ad 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 si trova ora in us-central1-docker.pkg.dev/${PROJECT_ID}/shipping/shipping
, di cui è possibile eseguire il deployment in GKE.
6. Deployment dell'applicazione nel cluster GKE in corso
Un cluster GKE Autopilot è stato creato quando hai creato le risorse Google Cloud per questo workshop. Connettiti al cluster GKE.
gcloud container clusters get-credentials gke1 \ --region=us-central1
Annota l'account di servizio predefinito di Kubernetes con l'account di servizio 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 venga 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. Credito aggiuntivo: risoluzione dei problemi relativi alla richiesta di partecipazione
Rimuovi il ruolo IAM Client Cloud SQL dall'account di servizio cloudsqlsa
. Questo 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>
Ispeziona i log da Kubernetes Engine > Carichi di lavoro
Fai clic sul deployment shipping
e quindi sulla scheda Log.
Fai clic sull'icona Visualizza in Esplora log sul lato destro della barra di stato. Si apre una nuova finestra 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.
Chiedi a Duet AI di aiutarti a risolvere l'errore.
Prova il seguente prompt.
Prompt 1: aiutami a risolvere questo errore
Inserisci il messaggio di errore nella richiesta.
Prompt 2: accesso vietato: l'entità IAM autenticata non sembra autorizzata a effettuare una richiesta API. Verifica "API Cloud SQL Admin" sia abilitato all'interno del tuo progetto Google Cloud e "Client Cloud SQL" è stato concesso il ruolo IAM all'entità IAM
E poi...
Prompt 3: come posso assegnare il ruolo Client Cloud SQL a un account di servizio 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 riprova ad accedere 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 dei log per risolvere il problema.
8. Conclusione
Complimenti! Hai completato questo codelab.
In questo codelab hai appreso quanto segue:
- Attiva Duet AI nel tuo progetto Google Cloud e configuralo per l'utilizzo in un IDE e nella console Cloud.
- Usa 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 la chat IDE e la chat multi-turno, la generazione di codice in chat e in linea, le azioni intelligenti come la spiegazione del codice e la conferma delle citazioni 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"]