Codelab: Technischer Duet AI-Workshop für Entwickler

1. Zielsetzungen

Ziel dieses Workshops ist es, Nutzern und Fachkräften praktische Informationen zu Duet-KI zu bieten.

In diesem Codelab lernen Sie Folgendes:

  1. Aktivieren Sie Duet AI in Ihrem GCP-Projekt und konfigurieren Sie es für die Verwendung in einer IDE und in der Cloud Console.
  2. Verwenden Sie Duet-KI zum Generieren, Vervollständigen und Erklärungen von Code.
  3. Mit Duet-KI ein Anwendungsproblem erklären und beheben
  4. Duet AI-Funktionen wie IDE-Chat und Chat in mehreren Schritten, Chat- und Inline-Codegenerierung, intelligente Aktionen wie Codeerklärung und Rezitationsbestätigung.

Narrative

Um zu zeigen, wie Duet AI für Entwickler authentisch in der täglichen Entwicklung eingesetzt wird, finden die Aktivitäten in diesem Workshop in einem erzählerischen Kontext statt.

Eine neue Entwicklerin stößt in ein E-Commerce-Unternehmen. Sie sollen der bestehenden E-Commerce-Anwendung, die aus mehreren Diensten besteht, einen neuen Dienst hinzufügen. Der neue Dienst bietet zusätzliche Informationen (Abmessungen, Gewicht usw.) zu Produkten im Produktkatalog. Dieser Service ermöglicht bessere/günstigere Versandkosten je nach Produktabmessungen und -gewicht.

Da der Entwickler neu im Unternehmen ist, wird er Duet AI zum Generieren, Erklärungen und Dokumentationen von Code verwenden.

Nach der Codierung des Dienstes verwendet ein Plattformadministrator Duet-KI (Chat), um das Artefakt (Docker-Container) und die Ressourcen zu erstellen, die zum Bereitstellen des Artefakts auf der GCP erforderlich sind (z. B. Artifact Registry, IAM-Berechtigungen, ein Code-Repository, Compute-Infrastruktur wie GKE oder CloudRun usw.).

Sobald die Anwendung auf der GCP bereitgestellt wurde, verwendet ein Anwendungsoperator/SRE Duet-KI (und Cloud Ops), um einen Fehler im neuen Dienst zu beheben.

Identität

Der Workshop umfasst die folgenden Persona:

  1. Anwendungsentwickler: Es sind Programmier- und Softwarekenntnisse erforderlich.

Diese Variante des Duet AI-Workshops ist nur für Entwickler gedacht. Es sind keine Kenntnisse der GCP-Cloud-Ressourcen erforderlich. Die Skripts zum Erstellen der erforderlichen GCP-Ressourcen zum Ausführen dieser Anwendung finden Sie hier. Sie können dieser Anleitung folgen, um die erforderlichen GCP-Ressourcen bereitzustellen.

2. Umgebung vorbereiten

Duet AI aktivieren

Sie können Duet-KI in einem GCP-Projekt aktivieren, entweder über die API (gcloud- oder IaC-Tools wie Terraform) oder über die Benutzeroberfläche der Cloud Console.

Zum Aktivieren von Duet AI in einem Google Cloud-Projekt aktivieren Sie die Cloud AI Companion API und gewähren Nutzern die IAM-Rollen (Identity and Access Management) „Cloud AI Companion User“ und „Service Usage Viewer“.

Über gcloud

Aktivieren Sie Cloud Shell:

Konfigurieren Sie PROJECT_ID und USER und aktivieren Sie die Cloud AI Companion API.

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}

Die Ausgabe sieht so aus:

Updated property [core/project].
Operation "operations/acat.p2-60565640195-f37dc7fe-b093-4451-9b12-934649e2a435" finished successfully.

Gewähren Sie dem USER-Konto die IAM-Rollen „Cloud AI Companion User“ und „Service Usage Viewer“. Die Cloud Companion API befindet sich hinter den Funktionen in der IDE und in der Konsole, die wir verwenden werden. Die Berechtigung „Service Usage Viewer“ wird als Schnellprüfung verwendet, bevor die Benutzeroberfläche in der Console aktiviert wird. So wird die Duet-UI nur in Projekten angezeigt, in denen die API aktiviert ist.

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

Die Ausgabe sieht so aus:

...
- members:
  - user:<YOUR USER ACCOUNT>
  role: roles/cloudaicompanion.user

...
- members:
  - user:<YOUR USER ACCOUNT>
  role: roles/serviceusage.serviceUsageViewer

Über die Cloud Console

Rufen Sie zum Aktivieren der API in der Google Cloud Console die Seite „Cloud AI Companion API“ auf.

Wählen Sie in der Projektauswahl ein Projekt aus.

Klicken Sie auf Aktivieren.

Die Seite wird aktualisiert und der Status Aktiviert wird angezeigt. Duet AI ist jetzt im ausgewählten Google Cloud-Projekt für alle Nutzer mit den erforderlichen IAM-Rollen verfügbar.

Rufen Sie die Seite IAM auf, um die IAM-Rollen zu gewähren, die zur Verwendung von Duet AI erforderlich sind.

Suchen Sie in der Spalte Hauptkonto den NUTZER, für den Sie den Zugriff auf Duet AI aktivieren möchten, und klicken Sie dann in dieser Zeile auf das Stiftsymbol ✏️ Hauptkonto bearbeiten.

Klicken Sie im Bereich Zugriff bearbeiten auf Weitere Rolle hinzufügen.

Wählen Sie unter „Rolle auswählen“ die Option Cloud AI Companion-Nutzer aus.

Klicken Sie auf Weitere Rolle hinzufügen und wählen Sie Service Usage Viewer aus.

Klicken Sie auf Speichern.

IDE einrichten

Entwickler können aus einer Vielzahl von IDEs wählen, die am besten zu ihren Anforderungen passen. Duet AI-Codeunterstützung ist in mehreren IDEs verfügbar, z. B. in Visual Studio Code, JetBrains-IDEs (IntelliJ, PyCharm, GoLand, WebStorm und mehr), Cloud Workstations und Cloud Shell Editor.

In diesem Lab können Sie entweder Cloud Workstations oder den Cloud Shell-Editor verwenden.

In diesem Workshop wird der Cloud Shell-Editor verwendet.

Die Einrichtung von Cloud Workstations kann 20 bis 30 Minuten dauern.

Wenn Sie sie sofort verwenden möchten, verwenden Sie den Cloud Shell-Editor.

Öffnen Sie den Cloud Shell-Editor. Klicken Sie dazu in der oberen Menüleiste von Cloud Shell auf das Stiftsymbol Semikolon.

Die Benutzeroberfläche und UX des Cloud Shell-Editors sind denen von VSCode sehr ähnlich.

d6a6565f83576063.png

Drücken Sie Strg (Windows)/CMD (Mac) + , (Komma), um den Bereich „Einstellungen“ aufzurufen.

Geben Sie in der Suchleiste „duet ai“ ein.

Achten oder aktivieren Sie Cloudcode › Duet AI: Enable und Cloudcode › Duet AI › Inline-Vorschläge: Automatische Aktivierung

111b8d587330ec74.png

Klicken Sie in der Statusleiste unten auf Cloud Code – Sign In (Cloud Code – Anmelden) und folgen Sie dem Anmeldeworkflow.

Wenn Sie bereits angemeldet sind, wird in der Statusleiste Cloud Code – Kein Projekt angezeigt.

Klicken Sie auf „Cloud Code – No Projekt“ (Cloud Code – Kein Projekt). Daraufhin wird oben ein Drop-down-Menü für die Aktion angezeigt. Klicken Sie auf Google Cloud-Projekt auswählen.

3241a59811e3c84a.png

Beginnen Sie mit der Eingabe der PROJEKT-ID. Ihr Projekt sollte in der Liste angezeigt werden.

c5358fc837588fe.png

Wählen Sie Ihre PROJECT_ID aus der Projektliste aus.

In der unteren Statusleiste wird nun Ihre Projekt-ID angezeigt. Ist dies nicht der Fall, müssen Sie möglicherweise den Tab mit dem Cloud Shell-Editor aktualisieren.

Klicken Sie in der linken Menüleiste auf das Duet AI-Symbol d97fc4e7b594c3af.png. Daraufhin wird das Duet AI-Chatfenster angezeigt. Die Meldung „GCP-Projekt auswählen“ wird angezeigt. Klicken Sie auf das Projekt und wählen Sie es noch einmal aus.

Sie sehen jetzt das Duet AI-Chatfenster

781f888360229ca6.png

3. Infrastruktur einrichten

d3234d237f00fdbb.png

Sie benötigen die folgenden GCP-Ressourcen, um den neuen Versandservice in der GCP ausführen zu können:

  1. Eine Cloud SQL-Instanz mit einer Datenbank.
  2. Ein GKE-Cluster zum Ausführen des containerisierten Dienstes.
  3. Eine Artifact Registry zum Speichern des Docker-Images.
  4. Ein Cloud Source Repository für den Code.

Klonen Sie im Cloud Shell-Terminal das folgende Repository und führen Sie die folgenden Befehle aus, um die Infrastruktur in Ihrem GCP-Projekt einzurichten.

# 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. Python Flask-Dienst entwickeln

9745ba5c70782e76.png

Der Dienst, den wir entwickeln, besteht letztendlich aus den folgenden Dateien. Sie müssen diese Dateien nicht jetzt erstellen. Erstellen Sie sie einzeln, indem Sie der Anleitung unten folgen:

  1. package-service.yaml: Eine Open API-Spezifikation für den Paketdienst mit Daten wie Höhe, Breite und Gewicht sowie spezielle Hinweise zur Handhabung.
  2. data_model.py – Datenmodell für die Package-Service-API-Spezifikation Erstellt außerdem die Tabelle packages in der Datenbank „product_details“.
  3. connect_connector.py – Cloud SQL-Verbindung (definiert Engine, Sitzung und Basis-ORM)
  4. db_init.py: Generiert Beispieldaten in der Tabelle packages.
  5. main.py: Ein Python Flask-Dienst mit einem GET-Endpunkt, um Paketdetails aus den packages-Daten basierend auf der „product_id“ abzurufen.
  6. test.py – Einheitentest
  7. requirement.txt: Python-Anforderungen
  8. Dockerfile – Zum Containerisieren dieser Anwendung

Sollten während der Übungen Probleme auftreten, finden Sie die endgültigen Dateien als Referenz im ANHANG dieses Codelabs.

Im vorherigen Schritt haben Sie ein Cloud Source Repository erstellt. Klonen Sie das Repository. Sie erstellen die Anwendungsdateien im geklonten Repository-Ordner.

Führen Sie im Cloud Shell-Terminal den folgenden Befehl aus, um das Repository zu klonen.

cd ~
gcloud source repos clone shipping shipping
cd ~/shipping 

Öffnen Sie im linken Menü des Cloud Shell-Editors die Duet AI-Chatseitenleiste. Das Symbol sieht aus wie 8b135a000b259175.png. Sie können jetzt Duet-KI zur Codeunterstützung verwenden.

package-service.yaml

Wenn keine Dateien geöffnet sind, bitten Sie Duet, eine Open API-Spezifikation für den Versandservice zu generieren.

Aufgabe 1: Generieren Sie eine OpenAPI-YAML-Spezifikation für einen Dienst, der Versand- und Paketinformationen anhand einer numerischen Produkt-ID bereitstellt. Der Service sollte Informationen zu Höhe, Breite, Tiefe und Gewicht des Pakets sowie spezielle Hinweise zur Handhabung enthalten.

ba12626f491a1204.png

Oben rechts im Fenster mit dem generierten Code werden drei Optionen angezeigt.

Du kannst den Code entweder COPY 71194556d8061dae.pngund in eine Datei einfügen.

Sie können den Code mit ADD df645de8c65607a.png in die aktuell geöffnete Datei im Editor einfügen.

Alternativ können Sie den Code in einer neuen Datei mit OPEN a4c7ed6d845df343.png speichern.

Klicken Sie auf OPEN a4c7ed6d845df343.png den Code in einer neuen Datei.

Klicken Sie auf CTRL/CMD + s, um die Datei zu speichern, und speichern Sie sie im Anwendungsordner unter dem Dateinamen package-service.yaml. Klicken Sie auf "OK".

f6ebd5b836949366.png

Die letzte Datei befindet sich im Abschnitt „ANHANG“ dieses Codelabs. Ist dies nicht der Fall, nehmen Sie die entsprechenden Änderungen manuell vor.

Sie können auch verschiedene Prompts ausprobieren, um die Antworten von Duet AI zu sehen.

Setzen Sie das Duet AI-Chatprotokoll zurück, indem Sie oben in der Duet AI-Seitenleiste auf das Papierkorbsymbol f574ca2c1e114856.png klicken.

data_model.py

Als Nächstes erstellen Sie die Python-Datenmodelldatei für den Dienst, die auf der OpenAPI-Spezifikation basiert.

Geben Sie bei geöffneter Datei package-service.yaml den folgenden Prompt ein.

Aufgabe 1: Generieren Sie mit Python sqlalchemy ORM ein Datenmodell für diesen API-Dienst. Fügen Sie außerdem eine separate Funktion und einen Haupteinstiegspunkt hinzu, über den die Datenbanktabellen erstellt werden.

b873a6a28bd28ca1.png

Schauen wir uns die einzelnen Teile an, die generiert wurden. Duet AI ist nach wie vor ein Assistent. Sie können damit schnell Code erstellen, sollten aber trotzdem generierte Inhalte prüfen und verstehen, während Sie sie verwenden.

Zuerst gibt es eine Klasse mit dem Namen Package von Art Base, die das Datenmodell für die Datenbank packages so definiert:

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))

Als Nächstes benötigen Sie eine Funktion, die die Tabelle in der Datenbank wie die folgende erstellt:

def create_tables(engine):
    Base.metadata.create_all(engine)

Schließlich benötigen Sie eine Hauptfunktion, die die create_tables-Funktion ausführt, um die Tabelle tatsächlich in der Cloud SQL-Datenbank zu erstellen. Beispiel:

if __name__ == '__main__':
    from sqlalchemy import create_engine

    engine = create_engine('sqlite:///shipping.db')
    create_tables(engine)

    print('Tables created successfully.')

Die Funktion main erstellt eine Suchmaschine mithilfe einer lokalen sqlite-Datenbank. Sie müssen ihn ändern, um Cloud SQL verwenden zu können. Das tun Sie etwas später.

Verwenden Sie OPEN a4c7ed6d845df343.png den Code wie zuvor in einem neuen Dateiworkflow. Speichern Sie den Code in einer Datei namens data_model.py. Beachten Sie dabei den Unterstrich und nicht den Bindestrich.

Setzen Sie das Duet AI-Chatprotokoll zurück, indem Sie oben in der Duet AI-Seitenleiste auf das Papierkorbsymbol f574ca2c1e114856.png klicken.

connect-connector.py

Erstellen Sie den CloudSQL-Connector.

Öffnen Sie die Datei data_model.py und geben Sie die folgenden Aufforderungen ein.

Aufgabe 1: Generieren Sie mit der Cloud SQL-Python-Connector-Bibliothek eine Funktion, die einen Verbindungspool für eine Cloud SQL-Instanz von Postgres initialisiert.

ed05cb6ff85d34c5.png

Beachten Sie, dass in der Antwort nicht die cloud-sql-python-connector-Bibliothek verwendet wird. Sie können Prompts optimieren, um Duet einen Vorgeschmack zu geben, indem Sie demselben Chat-Thread Details hinzufügen.

Verwenden wir einen anderen Prompt.

Aufgabe 2: Muss die Cloud-SQL-Python-Connector-Bibliothek verwenden.

d09095b44dde35bf.png

Achte darauf, dass die cloud-sql-python-connector-Bibliothek verwendet wird.

Verwenden Sie OPEN a4c7ed6d845df343.png den Code wie zuvor in einem neuen Dateiworkflow. Speichern Sie den Code in einer Datei mit dem Namen connect_conector.py. Möglicherweise musst du die pg8000-Bibliothek manuell importieren (siehe Datei unten).

Löschen Sie den Duet AI-Chatverlauf und generieren Sie bei geöffneter Datei connect_connector.py den ORM DB engine, sessionmaker und base, der in der App verwendet werden soll.

Aufgabe 1: Engine, Sessionmaker-Klasse und Base ORM mit der Methode „connect_with_connector“ erstellen

6e4214b72ab13a63.png

Durch die Antwort werden möglicherweise engine, Session und Base an die Datei connect_connector.py angehängt.

Die letzte Datei befindet sich im Abschnitt „ANHANG“ dieses Codelabs. Ist dies nicht der Fall, nehmen Sie die entsprechenden Änderungen manuell vor.

Sie können auch verschiedene Prompts ausprobieren, um die mögliche Variante der Antworten von Duet AI zu sehen.

Setzen Sie das Duet AI-Chatprotokoll zurück, indem Sie oben in der Duet AI-Seitenleiste auf das Papierkorbsymbol f574ca2c1e114856.png klicken.

data_model.py wird aktualisiert

Sie müssen die Suchmaschine verwenden, die Sie im vorherigen Schritt erstellt haben (in der Datei connect_connector.py), um eine Tabelle in der Cloud SQL-Datenbank zu erstellen.

Löschen Sie das Duet AI-Chatprotokoll. Öffnen Sie die Datei data_model.py. Versuchen Sie es mit dem folgenden Prompt.

Aufgabe 1: Importieren und verwenden Sie die Engine aus „connect_connector.py“ in der Hauptfunktion

2e768c9b6c523b9a.png

Die Antwort sollte angezeigt werden, wenn engine aus connect_connector (für Cloud SQL) importiert wird. Die create_table verwendet diese Engine (anstelle der standardmäßigen lokalen sqlite-Datenbank).

Datei „data_model.py“ aktualisieren.

Die letzte Datei befindet sich im Abschnitt „ANHANG“ dieses Codelabs. Ist dies nicht der Fall, nehmen Sie die entsprechenden Änderungen manuell vor.

Sie können auch verschiedene Prompts ausprobieren, um sich die Antworten von Duet AI anzusehen.

Setzen Sie das Duet AI-Chatprotokoll zurück, indem Sie oben in der Duet AI-Seitenleiste auf das Papierkorbsymbol f574ca2c1e114856.png klicken.

requirements.txt

Erstellen Sie eine requirements.txt-Datei für die Anwendung.

Öffnen Sie sowohl die Datei connect_connector.py als auch die Datei data_model.py und geben Sie den folgenden Prompt ein.

Aufgabe 1: Eine pip-Anforderungsdatei für dieses Datenmodell und diesen Dienst generieren

Aufgabe 2: Mit den neuesten Versionen eine pip-Anforderungsdatei für dieses Datenmodell und diesen Dienst generieren

69fae373bc5c6a18.png

Prüfen Sie, ob die Namen und Versionen korrekt sind. In der Antwort oben sind beispielsweise der Name und die Version von google-cloud-sql-connecter falsch. Korrigieren Sie die Versionen manuell und erstellen Sie eine requirements.txt-Datei, die so aussieht:

cloud-sql-python-connector==1.2.4
sqlalchemy==1.4.36
pg8000==1.22.0

Führen Sie im Befehlsterminal folgenden Befehl aus:

pip3 install -r requirements.txt

Setzen Sie das Duet AI-Chatprotokoll zurück, indem Sie oben in der Duet AI-Seitenleiste auf das Papierkorbsymbol f574ca2c1e114856.png klicken.

Pakettabelle in Cloud SQL erstellen

Legen Sie die Umgebungsvariablen für den CloudSQL-Datenbank-Connector fest.

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

Führen Sie nun data_model.py aus.

python data_model.py

Die Ausgabe sieht in etwa so aus (überprüfen Sie den Code, um zu sehen, was tatsächlich erwartet wird):

Tables created successfully.

Stellen Sie eine Verbindung zur Cloud SQL-Instanz her und prüfen Sie, ob die Datenbank erstellt wurde.

gcloud sql connect ${INSTANCE_NAME} --user=evolution --database=product_details

Nachdem Sie das Passwort (auch evolution) eingegeben haben, rufen Sie die Tabellen ab.

product_details=> \dt

Die Ausgabe sieht in etwa so aus:

           List of relations
 Schema |   Name   | Type  |   Owner   
--------+----------+-------+-----------
 public | packages | table | evolution
(1 row)

Sie können sich auch das Datenmodell und die Tabellendetails ansehen.

product_details=> \d+ packages

Die Ausgabe sieht in etwa so aus:

                                                                        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

Geben Sie \q ein, um Cloud SQL zu beenden.

db_init.py

Als Nächstes fügen wir der Tabelle packages Beispieldaten hinzu.

Löschen Sie das Duet AI-Chatprotokoll. Öffnen Sie die Datei data_model.py und versuchen Sie es mit den folgenden Prompts.

Aufgabe 1: Funktion generieren, die 10 Zeilen mit Beispielpaketen erstellt und sie an die Tabelle „Packages“ übergibt

Aufgabe 2: Generieren Sie mithilfe der Sitzung von „connect_connector“ eine Funktion, die 10 Beispielpaketzeilen erstellt und an die Pakettabelle übergibt

34a9afc5f04ba5.png

Verwenden Sie OPEN a4c7ed6d845df343.png den Code wie zuvor in einem neuen Dateiworkflow. Speichern Sie den Code in einer Datei mit dem Namen db_init.py.

Die letzte Datei befindet sich im Abschnitt „ANHANG“ dieses Codelabs. Ist dies nicht der Fall, nehmen Sie die entsprechenden Änderungen manuell vor.

Sie können auch verschiedene Prompts ausprobieren, um sich die Antworten von Duet AI anzusehen.

Setzen Sie das Duet AI-Chatprotokoll zurück, indem Sie oben in der Duet AI-Seitenleiste auf das Papierkorbsymbol f574ca2c1e114856.png klicken.

Beispielpaketdaten erstellen

Führen Sie db_init.py über die Befehlszeile aus.

python db_init.py

Die Ausgabe sieht in etwa so aus:

Packages created successfully.

Stellen Sie wieder eine Verbindung zur Cloud SQL-Instanz her und prüfen Sie, ob die Beispieldaten der Tabelle „Packages“ hinzugefügt wurden.

Stellen Sie eine Verbindung zur Cloud SQL-Instanz her und prüfen Sie, ob die Datenbank erstellt wurde.

gcloud sql connect ${INSTANCE_NAME} --user=evolution --database=product_details

Nach der Eingabe des Passworts (auch evolution) können Sie alle Daten aus der Tabelle „packages“ abrufen.

product_details=> SELECT * FROM packages;

Die Ausgabe sieht in etwa so aus:

 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)

Geben Sie \q ein, um Cloud SQL zu beenden.

main.py

Wenn die Dateien data_model.py, package-service.yaml und connect_connector.py geöffnet sind, erstellen Sie eine main.py für die Anwendung.

Aufgabe 1: Mit der Python flask-Bibliothek eine Implementierung erstellen, die HTTP-REST-Endpunkte für diesen Dienst verwendet

Aufgabe 2: Verwenden Sie die Python flask-Bibliothek. Erstellen Sie eine Implementierung, die HTTP-REST-Endpunkte für diesen Dienst verwendet. und verwenden Sie SessionMaker aus „connect_conector.py“ für Paketdaten.

Aufgabe 3: Verwenden Sie die Python flask-Bibliothek. Erstellen Sie eine Implementierung, die HTTP-REST-Endpunkte für diesen Dienst verwendet. Importieren und verwenden Sie ein Paket aus „data_model.py“ und „SessionMaker“ aus „connect_conector.py“ für Paketdaten.

Aufgabe 4: Verwenden Sie die Python flask-Bibliothek. Erstellen Sie eine Implementierung, die HTTP-REST-Endpunkte für diesen Dienst verwendet. Import und Verwendung von Paketen aus data_model.py und SessionMaker aus connect_conector.py für Paketdaten. Host-IP 0.0.0.0 für app.run verwenden

6d794fc52a90e6ae.png

Aktualisieren Sie die Anforderungen für main.py.

Prompt: Anforderungsdatei für main.py erstellen

1cc0b318d2d4ca2f.png

Hängen Sie dies an requirements.txt-Datei an. Stellen Sie sicher, dass Sie Flask Version 3.0.0 verwenden.

Verwenden Sie OPEN a4c7ed6d845df343.png den Code wie zuvor in einem neuen Dateiworkflow. Speichern Sie den Code in einer Datei mit dem Namen main.py.

Die letzte Datei befindet sich im Abschnitt „ANHANG“ dieses Codelabs. Ist dies nicht der Fall, nehmen Sie die entsprechenden Änderungen manuell vor.

Setzen Sie das Duet AI-Chatprotokoll zurück, indem Sie oben in der Duet AI-Seitenleiste auf das Papierkorbsymbol f574ca2c1e114856.png klicken.

5. Anwendung testen und ausführen

Installieren Sie die Anforderungen.

pip3 install -r requirements.txt

Führen Sie main.py aus.

python main.py

Die Ausgabe sieht in etwa so aus:

 * 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

Testen Sie an einem zweiten Terminal den Endpunkt /packages/<product_id>.

curl localhost:5000/packages/1

Die Ausgabe sieht in etwa so aus:

{"depth":10.0,"height":10.0,"special_handling_instructions":"No special handling instructions.","weight":10.0,"width":10.0}

Sie können auch jede andere Produkt-ID in Ihren Beispieldaten testen.

Geben Sie CTRL_C ein, um den laufenden Docker-Container im Terminal zu beenden.

Einheitentests werden generiert

Generieren Sie bei geöffneter Datei main.py Einheitentests.

Aufgabe 1: Einheitentests generieren.

e861e5b63e1b2657.png

Verwenden Sie OPEN a4c7ed6d845df343.png den Code wie zuvor in einem neuen Dateiworkflow. Speichern Sie den Code in einer Datei mit dem Namen test.py.

In der Funktion test_get_package muss eine product_id definiert werden. Sie können sie manuell hinzufügen.

Die letzte Datei befindet sich im Abschnitt „ANHANG“ dieses Codelabs. Ist dies nicht der Fall, nehmen Sie die entsprechenden Änderungen manuell vor.

Setzen Sie das Duet AI-Chatprotokoll zurück, indem Sie oben in der Duet AI-Seitenleiste auf das Papierkorbsymbol f574ca2c1e114856.png klicken.

Einheitentests ausführen

Führen Sie den Einheitentest durch.

python test.py

Die Ausgabe sieht in etwa so aus:

.
----------------------------------------------------------------------
Ran 1 test in 1.061s

OK

Schließen Sie alle Dateien im Cloud Shell-Editor und löschen Sie das Chatprotokoll. Klicken Sie dazu in der oberen Statusleiste auf das Papierkorbsymbol 1ecccfe10d6c540.png.

Dockerfile

Erstellen Sie eine Dockerfile für diese Anwendung.

Öffne main.py und versuche es mit den folgenden Aufforderungen.

Aufgabe 1: Generieren Sie ein Dockerfile für diese Anwendung.

Aufgabe 2: Generieren Sie ein Dockerfile für diese Anwendung. Kopieren Sie alle Dateien in den Container.

9c473caea437a5c3.png

Außerdem musst du ENVARS für INSTANCE_CONNECTION_NAME, DB_USER, DB_PASS und DB_NAME festlegen. Sie können dies manuell tun. Das Dockerfile sollte so aussehen:

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"]

Verwenden Sie OPEN a4c7ed6d845df343.png den Code wie zuvor in einem neuen Dateiworkflow. Speichern Sie den Code in einer Datei namens Dockerfile.

Die letzte Datei befindet sich im Abschnitt „ANHANG“ dieses Codelabs. Ist dies nicht der Fall, nehmen Sie die entsprechenden Änderungen manuell vor.

Anwendung lokal ausführen

Versuchen Sie bei geöffnetem Dockerfile den folgenden Prompt.

Aufgabe 1: Wie führe ich einen Container mit diesem Dockerfile lokal aus

570fd5c296ca8c83.png

Folgen Sie der Anleitung.

# Build
docker build -t shipping .
# And run
docker run -p 5000:5000 -it shipping

Die Ausgabe sieht in etwa so aus:

 * 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

Greifen Sie in einem zweiten Terminalfenster auf den Container zu.

curl localhost:5000/packages/1

Die Ausgabe sieht in etwa so aus:

{"depth":10.0,"height":10.0,"special_handling_instructions":"No special handling instructions.","weight":10.0,"width":10.0}

Die Containeranwendung funktioniert.

Geben Sie CTRL_C ein, um den laufenden Docker-Container im Terminal zu beenden.

Container-Image in Artifact Registry erstellen

Erstellen Sie das Container-Image und übertragen Sie es per Push an 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

Der Anwendungscontainer befindet sich jetzt unter us-central1-docker.pkg.dev/${PROJECT_ID}/shipping/shipping und kann in GKE bereitgestellt werden.

6. Anwendung wird im GKE-Cluster bereitgestellt

Beim Erstellen der GCP-Ressourcen für diesen Workshop wurde ein GKE Autopilot-Cluster erstellt. Stellen Sie eine Verbindung zum GKE-Cluster her.

gcloud container clusters get-credentials gke1 \
    --region=us-central1

Kommentieren Sie das Kubernetes-Standarddienstkonto mit dem Google-Dienstkonto.

kubectl annotate serviceaccount default iam.gke.io/gcp-service-account=cloudsqlsa@${PROJECT_ID}.iam.gserviceaccount.com

Die Ausgabe sieht in etwa so aus:

serviceaccount/default annotated

Bereiten Sie die Datei k8s.yaml vor und wenden Sie sie an.

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

Die Ausgabe sieht in etwa so aus:

deployment.apps/shipping created
service/shipping created

Warten Sie, bis die Pods ausgeführt werden und dem Dienst eine IP-Adresse für den externen Load Balancer zugewiesen ist.

kubectl get pods
kubectl get service shipping

Die Ausgabe sieht in etwa so aus:

# 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

Warten Sie bei GKE Autopilot-Clustern einen Moment, bis die Ressourcen bereit sind.

Greifen Sie über die EXTERNAL-IP-Adresse auf den Dienst zu.

export EXTERNAL_IP=$(kubectl get svc shipping --output jsonpath='{.status.loadBalancer.ingress[0].ip}')
curl http://${EXTERNAL_IP}/packages/1

Die Ausgabe sieht in etwa so aus:

{"depth":10.0,"height":10.0,"special_handling_instructions":"No special handling instructions.","weight":10.0,"width":10.0}

7. Zusätzlicher Schritt: Fehlerbehebung bei der Bewerbung

Entfernen Sie die IAM-Rolle „Cloud SQL-Client“ aus dem Dienstkonto cloudsqlsa. Dies führt zu einem Fehler beim Herstellen einer Verbindung zur Cloud SQL-Datenbank.

gcloud projects remove-iam-policy-binding ${PROJECT_ID} \
    --member="serviceAccount:cloudsqlsa@${PROJECT_ID}.iam.gserviceaccount.com" \
    --role="roles/cloudsql.client"

Starten Sie den Versand-Pod neu.

kubectl rollout restart deployment shipping

Versuchen Sie nach dem Neustart des Pods noch einmal, auf den Dienst shipping zuzugreifen.

export EXTERNAL_IP=$(kubectl get svc shipping --output jsonpath='{.status.loadBalancer.ingress[0].ip}')
curl http://${EXTERNAL_IP}/packages/1 

Die Ausgabe sieht in etwa so aus:

...
<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>

Prüfen Sie die Logs unter Kubernetes Engine > Arbeitslasten

d225b1916c829167.png

Klicken Sie auf das Deployment shipping und dann auf den Tab Logs.

1d0459141483d6a7.png

Klicken Sie rechts in der Statusleiste auf das Symbol Im Log-Explorer ansehen df8b9d19a9fe4c73.png. Dadurch wird ein neues Fenster mit dem Log-Explorer geöffnet.

e86d1c265e176bc4.png

Klicken Sie auf einen der Traceback-Fehlereinträge und dann auf Diesen Logeintrag erklären.

d6af045cf03008bc.png

Lesen Sie die Erklärung des Fehlers.

Als Nächstes bitten wir Sie, den Fehler mithilfe von Duet AI zu beheben.

Versuchen Sie es mit dem folgenden Prompt.

Aufgabe 1: Hilfe bei der Fehlerbehebung

9288dd6045369167.png

Geben Sie die Fehlermeldung in die Eingabeaufforderung ein.

Aufgabe 2: Verboten: Das authentifizierte IAM-Hauptkonto ist anscheinend nicht berechtigt, API-Anfragen zu senden. Cloud SQL Admin API überprüfen in Ihrem GCP-Projekt und im Cloud SQL-Client aktiviert ist, Rolle wurde dem IAM-Hauptkonto gewährt

f1e64fbdc435d31c.png

Und dann.

Aufgabe 3: Wie weise ich mit gcloud einem Google-Dienstkonto die Rolle „Cloud SQL-Client“ zu?

bb8926b995a8875c.png

Weisen Sie dem cloudsqlsa die Rolle „Cloud SQL-Client“ zu.

gcloud projects add-iam-policy-binding ${PROJECT_ID} \
    --member="serviceAccount:cloudsqlsa@${PROJECT_ID}.iam.gserviceaccount.com" \
    --role="roles/cloudsql.client"

Warten Sie einen Moment und versuchen Sie dann noch einmal, auf die App zuzugreifen.

export EXTERNAL_IP=$(kubectl get svc shipping --output jsonpath='{.status.loadBalancer.ingress[0].ip}')
curl http://${EXTERNAL_IP}/packages/1

Die Ausgabe sieht in etwa so aus:

{"depth":10.0,"height":10.0,"special_handling_instructions":"No special handling instructions.","weight":10.0,"width":10.0}

Sie haben Duet AI in Cloud Logging, Log Explorer und Log Explainer verwendet, um das Problem zu beheben.

8. Fazit

Glückwunsch! Du hast dieses Codelab erfolgreich abgeschlossen.

In diesem Codelab haben Sie Folgendes gelernt:

  1. Aktivieren Sie Duet AI in Ihrem GCP-Projekt und konfigurieren Sie es für die Verwendung in einer IDE und in der Cloud Console.
  2. Verwenden Sie Duet-KI zum Generieren, Vervollständigen und Erklärungen von Code.
  3. Mit Duet-KI ein Anwendungsproblem erklären und beheben
  4. Duet AI-Funktionen wie IDE-Chat und Chat in mehreren Schritten, Chat- und Inline-Codegenerierung, intelligente Aktionen wie Codeerklärung und Rezitationsbestätigung.

9. Anhang

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"]