Geliştiriciler için Duet AI Teknik Uygulamalı Atölye Kılavuzu

1. Hedefler

Bu atölyenin amacı, kullanıcılara ve uygulayıcılara Duet AI eğitimi sunmaktır.

Bu codelab'de şunları öğreneceksiniz:

  1. GCP projenizde Duet AI'ı etkinleştirip IDE ve Cloud Console'da kullanmak üzere yapılandırın.
  2. Kod oluşturma, tamamlama ve açıklama için Duet AI'ı kullanın.
  3. Uygulamalardaki bir sorunu açıklamak ve gidermek için Duet AI'ı kullanın.
  4. IDE sohbet ve çok dönüşlü sohbet, sohbet ya da satır içi kod oluşturma gibi Duet AI özellikleri, kod açıklaması ve hatırlatma onayı gibi akıllı işlemler ve daha fazlası.

Anlatım

Geliştiriciler için Duet AI'ın günlük gelişimde özgün bir şekilde nasıl kullanıldığını göstermek amacıyla bu atölyenin etkinlikleri, anlatı bağlamında gerçekleştiriliyor.

Bir e-ticaret şirketine yeni bir geliştirici katılıyor. Ekip, mevcut e-ticaret uygulamasına (birden fazla hizmetten oluşan) yeni bir hizmet eklemekle görevlendirilir. Bu yeni hizmet, ürün kataloğundaki ürünler hakkında ek bilgiler (boyutlar, ağırlık vb.) sağlar. Bu hizmet, ürün boyutlarına ve ağırlıklarına göre daha iyi/daha ucuz kargo maliyetlerine olanak tanır.

Geliştirici şirkette yeni olduğundan kod oluşturma, açıklama ve belgeleme işlemleri için Duet AI'ı kullanacaklar.

Hizmet kodlandıktan sonra platform yöneticileri yapıyı (docker container'ı) oluşturmak için Duet AI'ı (chat) ve yapıyı GCP'ye dağıtmak için gereken kaynakları (ör.Artifact Registry, IAM izinleri, kod deposu, bilgi işlem altyapısı (ör. GKE veya CloudRun)) kullanır.

Uygulama GCP'ye dağıtıldıktan sonra bir uygulama operatörü/SRE, yeni hizmetteki bir hatanın giderilmesine yardımcı olmak için Duet AI'ı (ve Cloud Ops'u) kullanır.

Karakter

Atölyede aşağıdaki karakter ele alınır:

  1. Uygulama Geliştirici: Biraz programlama ve yazılım geliştirme bilgisi gerekir.

Duet AI atölyesinin bu varyasyonu yalnızca geliştiricilere yöneliktir. GCP bulut kaynakları hakkında bilgi sahibi olmanız gerekmez. Bu uygulamayı çalıştırmak için gerekli GCP kaynaklarını derlemeye yönelik komut dosyalarını burada bulabilirsiniz. Gerekli GCP kaynaklarını dağıtmak için bu kılavuzdaki talimatları uygulayabilirsiniz.

2. Ortamı hazırlama

Duet AI etkinleştiriliyor

GCP projesinde Duet AI'ı etkinleştirmek için API'yi (gcloud veya Terraform gibi IaC araçları) ya da Cloud Console kullanıcı arayüzünü kullanabilirsiniz.

Bir Google Cloud projesinde Duet AI'ı etkinleştirmek için Cloud AI Companion API'yi etkinleştirip kullanıcılara Cloud AI Companion User ve Hizmet Kullanımı Görüntüleyici Kimlik ve Erişim Yönetimi (IAM) rollerini verirsiniz.

gcloud aracılığıyla

Cloud Shell'i etkinleştirin:

PROJECT_ID ve USER yapılandırın ve Cloud AI Companion API'yi etkinleştirin.

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}

Çıkış şuna benzer:

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

Cloud AI Tamamlayıcı Kullanıcısı ve Hizmet Kullanımı Görüntüleyicisi Kimlik ve Erişim Yönetimi (IAM) rollerini USER hesabına verin. Cloud Companion API, hem IDE'deki hem de konsoldaki özelliklerin arkasındadır. Hizmet Kullanım Görüntüleyici izni, konsolda kullanıcı arayüzü etkinleştirilmeden önce hızlı bir kontrol olarak kullanılır. Böylece Duet kullanıcı arayüzü yalnızca API'nin etkinleştirildiği projelerde gösterilir.

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

Çıkış şuna benzer:

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

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

Cloud Console aracılığıyla

API'yi etkinleştirmek için Google Cloud Console'daki Cloud AI Companion API sayfasına gidin.

Proje seçicide bir proje seçin.

Etkinleştir'i tıklayın.

Sayfa güncellenir ve Etkin durumu gösterilir. Duet AI, seçilen Google Cloud projesinde artık gerekli IAM rollerine sahip olan tüm kullanıcılar tarafından kullanılabilir.

Duet AI'ı kullanmak için gereken IAM rollerini vermek üzere IAM sayfasına gidin.

Ana hesap sütununda Duet AI'a erişimi etkinleştirmek istediğiniz KULLANICI'yı bulun ve ardından kalem simgesini ✏️ bu satırdaki Ana hesabı düzenle'yi tıklayın.

Düzenleme erişim bölmesinde Başka bir rol ekle'yi tıklayın.

Rol seçin bölümünde Cloud AI Companion User'ı (Cloud AI Tamamlayıcı Kullanıcısı) seçin.

Başka bir rol ekle'yi tıklayın ve Hizmet Kullanımı Görüntüleyici'yi seçin.

Kaydet'i tıklayın.

IDE'yi ayarlama

Geliştiriciler ihtiyaçlarına en uygun IDE'ler arasından seçim yapabilirler. Duet AI kod yardımı; Visual Studio Code, JetBrains IDE'ler (IntelliJ, PyCharm, GoLand, WebStorm ve diğerleri), Cloud Workstations ve Cloud Shell Düzenleyici gibi birden fazla IDE'de kullanılabilir.

Bu laboratuvarda Cloud Workstations'ı veya Cloud Shell Düzenleyici'yi kullanabilirsiniz.

Bu atölyede Cloud Shell Düzenleyici kullanılır.

Cloud Workstations'ın kurulumunun 20-30 dakika sürebileceğini unutmayın.

Hemen kullanmak için Cloud Shell Düzenleyici'yi kullanın.

Cloud Shell'inizin üst menü çubuğundaki kalem simgesini ✏️ tıklayarak Cloud Shell Düzenleyici'yi açın.

Cloud Shell Düzenleyici'nin, VSCode'a çok benzer bir kullanıcı arayüzü ve kullanıcı deneyimi vardır.

d6a6565f83576063.png

Ayarlar bölmesine girmek için CTRL (Windows'da)/CMD (Mac'te) + , (virgül) tuşlarına basın.

Arama çubuğuna "duet ai" yazın.

Cloudcode › Duet AI: Etkinleştir ve Cloudcode › Duet AI › Satır içi Öneriler: Otomatik'i etkinleştir seçeneğini etkinleştirin veya etkinleştirin

111b8d587330ec74.png

Alttaki Durum Çubuğu'ndan Cloud Code - Oturum Aç'ı tıklayın ve oturum açma iş akışını uygulayın.

Zaten oturum açtıysanız durum çubuğunda Cloud Code - Proje yok ifadesi gösterilir.

Cloud Code'u tıklayın - Proje yok ve en üstte bir işlem açılır bölmesi görünür. Select a Google Cloud project'i (Google Cloud projesi seç) tıklayın.

3241a59811e3c84a.png

PROJE KİMLİĞİnizi yazmaya başladığınızda projeniz listede görünecektir.

c5358fc837588fe.png

Proje listesinden PROJECT_ID'nizi seçin.

Alttaki durum çubuğu, proje kimliğinizi gösterecek şekilde güncellenir. Açılmazsa Cloud Shell Düzenleyici sekmenizi yenilemeniz gerekebilir.

Soldaki menü çubuğunda Duet AI simgesini d97fc4e7b594c3af.png tıkladığınızda Duet AI sohbet penceresi açılır. "GCP Projesini Seçin" mesajını alırsanız Projeyi tıklayıp yeniden seçin.

Duet AI sohbet penceresini artık görüyorsunuz

781f888360229ca6.png

3. Altyapı kurulumu

d3234d237f00fdbb.png

GCP'de yeni kargo hizmetini çalıştırmak için aşağıdaki GCP kaynaklarına ihtiyacınız vardır:

  1. Veritabanı bulunan bir Cloud SQL örneği.
  2. Container mimarisine alınmış hizmeti çalıştırmak için bir GKE kümesi.
  3. Docker görüntüsünü depolamak için bir Artifact Registry.
  4. Kod için Cloud Kaynak Deposu.

Cloud Shell terminalinde aşağıdaki depoyu klonlayın ve GCP projenizdeki altyapıyı kurmak için aşağıdaki komutları çalıştırın.

# 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 hizmeti geliştirme

9745ba5c70782e76.png

Oluşturacağımız hizmet sonuçta aşağıdaki dosyalardan oluşacak. Bu dosyaları şimdi oluşturmanız gerekmez. Aşağıdaki talimatları uygulayarak tek seferde bu dosyaları oluşturacaksınız:

  1. package-service.yaml: Paket hizmeti için yükseklik, genişlik, ağırlık ve özel sevkiyata hazırlık talimatları gibi verilerin bulunduğu bir Open API spesifikasyonu.
  2. data_model.py - Paket hizmeti API spesifikasyonu için veri modeli. Ayrıca product_details veritabanında packages tablosunu oluşturur.
  3. connect_connector.py - CloudSQL bağlantısı (arama motoru, oturum ve temel ORM'yi tanımlar)
  4. db_init.py: packages tablosunda örnek veriler oluşturur.
  5. main.py - Product_id değerine göre packages verilerinden paket ayrıntılarını almak için GET uç noktasına sahip bir Python Flask hizmeti.
  6. test.py - Ünite testi
  7. requirement.txt - Python gereksinimleri
  8. Dockerfile - Bu uygulamayı container mimarisine almak için

Alıştırmalar sırasında yapışkan problemlerle karşılaşırsanız son dosyaların tamamı referans olması için bu codelab'in EK bölümünde yer almaktadır.

Önceki adımda bir Cloud Source Repositories oluşturdunuz. Depoyu klonlayın. Uygulama dosyalarını klonlanan depo klasöründe derleyeceksiniz.

Cloud Shell terminalinde aşağıdaki komutu çalıştırarak depoyu klonlayın.

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

Cloud Shell Düzenleyici'nin sol menüsünden Duet AI sohbet kenar çubuğunu açın. Simge 8b135a000b259175.png şeklinde görünür. Artık kod yardımı için Duet AI'ı kullanabilirsiniz.

package-service.yaml

Herhangi bir dosya açık olmadan Duet'ten, kargo hizmeti için bir Open API spesifikasyonu oluşturmasını isteyin.

İstem 1: Sayısal ürün kimliği sağlanan gönderim ve paket bilgilerini sağlayan bir hizmet için OpenAPI yaml spesifikasyonu oluşturun. Hizmet; paketlerin yüksekliği, genişliği, derinliği, ağırlığı ve özel sevkiyata hazırlık talimatlarıyla ilgili bilgileri içermelidir.

ba12626f491a1204.png

Oluşturulan kod penceresinin sağ üst köşesinde üç seçenek listelenmiştir.

Kodu COPY 71194556d8061dae.pngve bir dosyaya yapıştırabilirsiniz.

Kodu, Editor'da açık olan dosyaya ADD df645de8c65607a.png ekleyebilirsiniz.

Alternatif olarak, kodu yeni bir dosyada OPEN a4c7ed6d845df343.png.

Yeni bir dosyadaki kodu OPEN a4c7ed6d845df343.png tıklayın.

Dosyayı kaydetmek için CTRL/CMD + s öğesini tıklayın ve dosyayı package-service.yaml adlı dosya adıyla uygulama klasöründe depolayın. Tamam'ı tıklayın.

f6ebd5b836949366.png

Nihai dosya, bu codelab'in EK bölümündedir. Böyle bir uyarı görüntülenmiyorsa gerekli değişiklikleri manuel olarak yapın.

Duet AI'ın yanıtlarını görmek için çeşitli istemleri de deneyebilirsiniz.

Duet AI kenar çubuğunun üst kısmındaki çöp kutusu simgesini f574ca2c1e114856.png tıklayarak Duet AI sohbet geçmişini sıfırlayın.

data_model.py

Daha sonra, OpenAPI spesifikasyonuna göre hizmet için veri modeli python dosyasını oluşturun.

package-service.yaml dosyası açıkken aşağıdaki istemi girin.

İstem 1: python sqlalchemy ORM'yi kullanarak bu API hizmeti için bir veri modeli oluşturun. Ayrıca, veritabanı tablolarını oluşturan ayrı bir işlev ve ana giriş noktası ekleyin.

b873a6a28bd28ca1.png

Oluşturulan her bir bölümü inceleyelim. Duet AI, hâlâ asistanınızdır ve hızlıca kod yazmanıza yardımcı olsa da oluşturulan içerikleri inceleyip anladığınızdan emin olmalısınız.

İlk olarak, packages veritabanının veri modelini aşağıdaki gibi tanımlayan Package türBase adında bir Sınıf bulunur:

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

Ardından, veritabanında tabloyu oluşturan aşağıdaki gibi bir işleve ihtiyacınız vardır:

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

Son olarak, tabloyu CloudSQL veritabanında oluşturmak için create_tables işlevini çalıştıran aşağıdaki gibi bir ana işleve ihtiyacınız vardır:

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

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

    print('Tables created successfully.')

main işlevinin, yerel sqlite veritabanı kullanarak bir motor oluşturduğunu unutmayın. CloudSQL'i kullanmak için bunu değiştirmeniz gerekir. Bunu biraz sonra yaparsınız.

Kod, önceki gibi yeni bir dosya iş akışında OPEN a4c7ed6d845df343.png kullanıldığında. Kodu data_model.py adlı bir dosyaya kaydedin (kısa çizgiye değil, addaki alt çizgiye dikkat edin).

Duet AI kenar çubuğunun üst kısmındaki çöp kutusu simgesini f574ca2c1e114856.png tıklayarak Duet AI sohbet geçmişini sıfırlayın.

connect-connector.py

CloudSQL bağlayıcısını oluşturun.

data_model.py dosyası açıkken aşağıdaki istemleri girin.

İstem 1: Cloud-sql-python-connector kitaplığını kullanarak Postgres Cloud SQL örneği için bağlantı havuzu başlatan bir işlev oluşturun.

ed05cb6ff85d34c5.png

Yanıtın cloud-sql-python-connector kitaplığını kullanmadığını unutmayın. Aynı sohbet ileti dizisine ayrıntılı bilgiler ekleyerek Duet'e biraz otomatik hatırlatmalar yapmak için istemleri hassaslaştırabilirsiniz.

Başka bir istem kullanalım.

2. İstem: cloud-sql-python-connector kitaplığı kullanılmalıdır.

d09095b44dde35bf.png

cloud-sql-python-connector kitaplığını kullandığından emin olun.

Kod, önceki gibi yeni bir dosya iş akışında OPEN a4c7ed6d845df343.png kullanıldığında. Kodu connect_conector.py adlı bir dosyaya kaydedin. pg8000 kitaplığını manuel olarak içe aktarmanız gerekebilir. Lütfen aşağıdaki dosyaya bakın.

Duet AI sohbet geçmişini temizleyin ve connect_connector.py dosyası açıkken uygulamada kullanılacak DB engine, sessionmaker ve base ORM'sini oluşturun.

İstem 1: connect_with_connector yöntemini kullanarak bir motor, sessionmaker sınıfı ve Base ORM oluşturma

6e4214b72ab13a63.png

Yanıtta engine, Session ve Base özellikleri connect_connector.py dosyasına eklenebilir.

Nihai dosya, bu codelab'in EK bölümündedir. Böyle bir uyarı görüntülenmiyorsa gerekli değişiklikleri manuel olarak yapın.

Duet AI'ın yanıtlarının olası varyasyonlarını görmek için çeşitli istemleri de deneyebilirsiniz.

Duet AI kenar çubuğunun üst kısmındaki çöp kutusu simgesini f574ca2c1e114856.png tıklayarak Duet AI sohbet geçmişini sıfırlayın.

data_model.py güncelleniyor

CloudSQL veritabanında tablo oluşturmak için önceki adımda oluşturduğunuz motoru (connect_connector.py dosyasında) kullanmanız gerekir.

Duet AI sohbet geçmişini temizleyin. data_model.py dosyasını açın. Aşağıdaki istemi deneyin.

İstem 1: Ana işlevde, connect_connector.py'den motoru içe aktarıp kullanın

2e768c9b6c523b9a.png

connect_connector hizmetinden (CloudSQL için) engine içe aktarılmış yanıt göreceksiniz. create_table bu motoru kullanır (varsayılan sqlite yerel veritabanı yerine).

data_model.py dosyasını güncelleyin.

Nihai dosya, bu codelab'in EK bölümündedir. Böyle bir uyarı görüntülenmiyorsa gerekli değişiklikleri manuel olarak yapın.

Duet AI'ın çeşitli yanıtlarını görmek için çeşitli istemleri de deneyebilirsiniz.

Duet AI kenar çubuğunun üst kısmındaki çöp kutusu simgesini f574ca2c1e114856.png tıklayarak Duet AI sohbet geçmişini sıfırlayın.

requirements.txt

Uygulama için bir requirements.txt dosyası oluşturun.

Hem connect_connector.py hem de data_model.py dosyasını açın ve aşağıdaki istemi girin.

1. İstem: Bu veri modeli ve hizmeti için pip gereksinimleri dosyası oluşturun

2. İstem: En son sürümleri kullanarak bu veri modeli ve hizmet için bir pip gereksinimleri dosyası oluşturun

69fae373bc5c6a18.png

Adların ve sürümlerin doğru olduğundan emin olun. Örneğin, yukarıdaki yanıtta google-cloud-sql-connecter adı da sürümü de yanlış. Sürümleri manuel olarak düzeltin ve şuna benzer bir requirements.txt dosyası oluşturun:

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

Komut terminalinde aşağıdaki komutu çalıştırın:

pip3 install -r requirements.txt

Duet AI kenar çubuğunun üst kısmındaki çöp kutusu simgesini f574ca2c1e114856.png tıklayarak Duet AI sohbet geçmişini sıfırlayın.

CloudSQL'de paket tablosu oluşturma

CloudSQL veritabanı bağlayıcısı için ortam değişkenlerini ayarlayın.

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

Şimdi data_model.py'yi çalıştırın.

python data_model.py

Çıkış şuna benzerdir (Aslında ne beklendiğini görmek için kodu kontrol edin):

Tables created successfully.

CloudSQL örneğine bağlanın ve veritabanının oluşturulup oluşturulmadığını kontrol edin.

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

Şifreyi (ayrıca evolution olarak) girdikten sonra tabloları alın.

product_details=> \dt

Çıkış şuna benzer:

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

Veri modelini ve tablo ayrıntılarını da kontrol edebilirsiniz.

product_details=> \d+ packages

Çıkış şuna benzer:

                                                                        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

CloudSQL'den çıkmak için \q yazın.

db_init.py

Şimdi packages tablosuna bazı örnek veriler ekleyelim.

Duet AI sohbet geçmişini temizleyin. data_model.py dosyası açıkken aşağıdaki istemleri deneyin.

İstem 1: 10 örnek paket satırı oluşturan ve bunları paketler tablosuna kaydeden bir işlev oluşturma

İstem 2: connect_connector'daki oturumu kullanarak 10 örnek paket satırı oluşturan ve bunları paketler tablosuna aktaran bir işlev oluşturun

34a9afc5f04ba5.png

Kod, önceki gibi yeni bir dosya iş akışında OPEN a4c7ed6d845df343.png kullanıldığında. Kodu db_init.py adlı bir dosyaya kaydedin.

Nihai dosya, bu codelab'in EK bölümündedir. Böyle bir uyarı görüntülenmiyorsa gerekli değişiklikleri manuel olarak yapın.

Duet AI'ın çeşitli yanıtlarını görmek için çeşitli istemleri de deneyebilirsiniz.

Duet AI kenar çubuğunun üst kısmındaki çöp kutusu simgesini f574ca2c1e114856.png tıklayarak Duet AI sohbet geçmişini sıfırlayın.

Örnek paket verileri oluşturma

Komut satırından db_init.py komutunu çalıştırın.

python db_init.py

Çıkış şuna benzer:

Packages created successfully.

CloudSQL örneğine tekrar bağlanın ve örnek verilerin paketler tablosuna eklendiğini doğrulayın.

CloudSQL örneğine bağlanın ve veritabanının oluşturulup oluşturulmadığını kontrol edin.

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

Şifreyi (ayrıca evolution'ı) girdikten sonra paketler tablosundaki tüm verileri alın.

product_details=> SELECT * FROM packages;

Çıkış şuna benzer:

 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)

CloudSQL'den çıkmak için \q yazın.

main.py

data_model.py, package-service.yaml ve connect_connector.py dosyaları açıkken uygulama için bir main.py oluşturun.

İstem 1: Python deney tüpü kitaplığını kullanma - bu hizmet için http dinlenme uç noktalarını kullanan bir uygulama oluşturma

2. İstem: Python deney tüpü kitaplığını kullanma - bu hizmet için http dinlenme uç noktalarını kullanan bir uygulama oluşturun. paket verileri için connect_conector.py adresinden SessionMaker'ı içe aktarıp kullanın.

İstem 3: Python deney tüpü kitaplığını kullanma - bu hizmet için http dinlenme uç noktalarını kullanan bir uygulama oluşturun. paket verileri için data_model.py'den Paket'i, connect_conector.py adresinden SessionMaker'ı kullanarak Paket'i içe aktarıp kullanın.

4. İstem: Python deney tüpü kitaplığını kullanma - bu hizmet için http dinlenme uç noktalarını kullanan bir uygulama oluşturun. paket verileri için data_model.py'den Paket'i, connect_conector.py adresinden SessionMaker'ı kullanarak Paket'i içe aktarıp kullanın. app.run için ana makine IP'si 0.0.0.0 kullanılır

6d794fc52a90e6ae.png

main.py ile ilgili gereksinimleri güncelleyin.

İstem: Main.py için gereksinimler dosyası oluştur

1cc0b318d2d4ca2f.png

Bunu requirements.txt dosyasına ekleyin. Flask 3.0.0 sürümünü kullandığınızdan emin olun.

Kod, önceki gibi yeni bir dosya iş akışında OPEN a4c7ed6d845df343.png kullanıldığında. Kodu main.py adlı bir dosyaya kaydedin.

Nihai dosya, bu codelab'in EK bölümündedir. Böyle bir uyarı görüntülenmiyorsa gerekli değişiklikleri manuel olarak yapın.

Duet AI kenar çubuğunun üst kısmındaki çöp kutusu simgesini f574ca2c1e114856.png tıklayarak Duet AI sohbet geçmişini sıfırlayın.

5. Uygulamayı test etme ve çalıştırma

Gereksinimleri yükleyin.

pip3 install -r requirements.txt

main.py çalıştır.

python main.py

Çıkış şuna benzer:

 * 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

İkinci bir terminalden /packages/<product_id> uç noktasını test edin.

curl localhost:5000/packages/1

Çıkış şuna benzer:

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

Örnek verilerinizdeki diğer tüm ürün kimliklerini de test edebilirsiniz.

Terminalde çalışan Docker container'ından çıkmak için CTRL_C komutunu girin.

Birim testleri oluşturma

main.py dosyası açıkken birim testleri oluşturun.

İstem 1: Birim testleri oluşturma.

e861e5b63e1b2657.png

Kod, önceki gibi yeni bir dosya iş akışında OPEN a4c7ed6d845df343.png kullanıldığında. Kodu test.py adlı bir dosyaya kaydedin.

test_get_package işlevinde product_id tanımlanmalıdır. Manuel olarak ekleyebilirsiniz.

Nihai dosya, bu codelab'in EK bölümündedir. Böyle bir uyarı görüntülenmiyorsa gerekli değişiklikleri manuel olarak yapın.

Duet AI kenar çubuğunun üst kısmındaki çöp kutusu simgesini f574ca2c1e114856.png tıklayarak Duet AI sohbet geçmişini sıfırlayın.

Birim testlerini çalıştırma

Birim testini çalıştırın.

python test.py

Çıkış şuna benzer:

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

OK

Cloud Shell Düzenleyici'deki tüm dosyaları kapatın ve üst durum çubuğunda yer alan çöp kutusu simgesini 1ecccfe10d6c540.png tıklayarak sohbet geçmişini temizleyin.

Dockerfile

Bu uygulama için bir Dockerfile oluşturun.

main.py uygulamasını açıp aşağıdaki istemleri deneyin.

İstem 1: Bu uygulama için bir Dockerfile oluşturun.

İstem 2: Bu uygulama için Dockerfile oluşturun. Tüm dosyaları kapsayıcıya kopyalayın.

9c473caea437a5c3.png

INSTANCE_CONNECTION_NAME, DB_USER, DB_PASS ve DB_NAME için ENVARS değerini de ayarlamanız gerekir. Bunu manuel olarak yapabilirsiniz. Dockerfile'ınız aşağıdaki gibi görünmelidir:

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

Kod, önceki gibi yeni bir dosya iş akışında OPEN a4c7ed6d845df343.png kullanıldığında. Kodu Dockerfile adlı bir dosyaya kaydedin.

Nihai dosya, bu codelab'in EK bölümündedir. Böyle bir uyarı görüntülenmiyorsa gerekli değişiklikleri manuel olarak yapın.

Uygulamayı yerel olarak çalıştırma

Dockerfile açıkken aşağıdaki istemi deneyin.

1. İstem: Bu Dockerfile'ı kullanarak container'ı yerel olarak nasıl çalıştırırım?

570fd5c296ca8c83.png

Talimatları uygulayın.

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

Çıkış şuna benzer:

 * 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

İkinci bir terminal penceresinden kapsayıcıya erişin.

curl localhost:5000/packages/1

Çıkış şuna benzer:

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

Container mimarisine alınmış uygulama çalışıyor.

Terminalde çalışan Docker container'ından çıkmak için CTRL_C komutunu girin.

Artifact Registry'de container görüntüsü derleme

Container görüntüsünü derleyin ve Artifact Registry'ye aktarın.

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

Uygulama container'ı artık us-central1-docker.pkg.dev/${PROJECT_ID}/shipping/shipping konumunda bulunan ve GKE'ye dağıtılabilir.

6. Uygulama GKE kümesine dağıtılıyor

Bu atölyede GCP kaynaklarını derlediğinizde bir GKE Autopilot kümesi oluşturuldu. GKE kümesine bağlanın.

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

Varsayılan Kubernetes hizmet hesabına Google hizmet hesabıyla ek açıklama ekleyin.

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

Çıkış şuna benzer:

serviceaccount/default annotated

k8s.yaml dosyasını hazırlayın ve uygulayın.

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

Çıkış şuna benzer:

deployment.apps/shipping created
service/shipping created

Kapsüller çalışana ve Hizmete harici yük dengeleyici IP adresi atanana kadar bekleyin.

kubectl get pods
kubectl get service shipping

Çıkış şuna benzer:

# 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

GKE Autopilot kümeleri için kaynaklar hazır olana kadar birkaç dakika bekleyin.

Hizmete EXTERNAL-IP adresi üzerinden erişin.

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

Çıkış şuna benzer:

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

7. Ek Kredi: Başvuruyla ilgili sorunları giderme

cloudsqlsa hizmet hesabından CloudSQL İstemci IAM rolünü kaldırın. Bu durum, CloudSQL veritabanına bağlanırken hata oluşmasına neden olur.

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

Kargo kapsülünü yeniden başlatın.

kubectl rollout restart deployment shipping

Kapsül yeniden başlatıldıktan sonra shipping hizmetine erişmeyi tekrar deneyin.

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

Çıkış şuna benzer:

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

Kubernetes Engine > İş Yükleri

d225b1916c829167.png

shipping dağıtımını ve ardından Günlükler sekmesini tıklayın.

1d0459141483d6a7.png

Durum çubuğunun sağ tarafındaki Günlük Gezgini'nde Görüntüle df8b9d19a9fe4c73.pngsimgesini tıklayın. Yeni bir Günlük Gezgini penceresi açılır.

e86d1c265e176bc4.png

Traceback hata girişlerinden birini ve ardından Bu Günlük Girişini Açıkla'yı tıklayın.

d6af045cf03008bc.png

Hatanın açıklamasını okuyabilirsiniz.

Şimdi de Duet AI'ı kullanarak hatayı giderelim.

Aşağıdaki istemi deneyin.

1. İstem: Bu hatayı gidermeme yardımcı olun

9288dd6045369167.png

İsteme hata mesajını girin.

2. İstem: Yasak: Kimliği doğrulanmış IAM ana hesabının API isteği yapma yetkisi yok. "Cloud SQL Admin API" doğrulama GCP projenizde ve "Cloud SQL İstemcinizde" etkinleştirildiğinde IAM ana hesabına rolü verildi

f1e64fbdc435d31c.png

Sonra.

İstem 3: gcloud kullanarak bir Google hizmet hesabına Cloud SQL İstemcisi rolünü nasıl atayabilirim?

bb8926b995a8875c.png

cloudsqlsa öğesine Cloud SQL İstemcisi rolünü atayın.

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

Birkaç dakika bekleyin ve uygulamaya erişmeyi tekrar deneyin.

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

Çıkış şuna benzer:

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

Sorunu gidermek için Cloud Logging, Log Explorer ve Log Explainer özelliğinde Duet AI'ı başarıyla kullandınız.

8. Sonuç

Tebrikler! Bu codelab'i başarıyla tamamladınız.

Bu codelab'de şunları öğrendiniz:

  1. GCP projenizde Duet AI'ı etkinleştirip IDE ve Cloud Console'da kullanmak üzere yapılandırın.
  2. Kod oluşturma, tamamlama ve açıklama için Duet AI'ı kullanın.
  3. Uygulamalardaki bir sorunu açıklamak ve gidermek için Duet AI'ı kullanın.
  4. IDE sohbet ve çok dönüşlü sohbet, sohbet ya da satır içi kod oluşturma gibi Duet AI özellikleri, kod açıklaması ve hatırlatma onayı gibi akıllı işlemler ve daha fazlası.

9. Ek

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