Duet AI Technical Hands On Workshop Manual for Developers Codelab

1. اهداف

هدف از این کارگاه ارائه آموزش عملی هوش مصنوعی Duet به کاربران و تمرین‌کنندگان است.

در این کد لبه موارد زیر را یاد می گیرید:

  1. Duet AI را در پروژه GCP خود فعال کنید و آن را برای استفاده در یک IDE و Cloud Console پیکربندی کنید.
  2. از هوش مصنوعی Duet برای تولید کد، تکمیل و توضیح استفاده کنید.
  3. از هوش مصنوعی Duet برای توضیح و عیب یابی یک مشکل برنامه استفاده کنید.
  4. ویژگی‌های هوش مصنوعی Duet مانند چت IDE و چت چند نوبتی، چت در مقابل تولید کد درون خطی، اقدامات هوشمندانه مانند توضیح کد و تصدیق تلاوت و موارد دیگر.

روایت

برای نشان دادن اینکه چگونه هوش مصنوعی Duet برای توسعه دهندگان به طور واقعی در توسعه روزمره استفاده می شود، فعالیت های این کارگاه در یک زمینه روایت انجام می شود.

یک توسعه دهنده جدید به یک شرکت تجارت الکترونیک می پیوندد. آنها وظیفه دارند یک سرویس جدید به برنامه تجارت الکترونیک موجود (که از چندین سرویس تشکیل شده است) اضافه کنند. سرویس جدید اطلاعات اضافی (ابعاد، وزن و غیره) را در مورد محصولات موجود در کاتالوگ محصول ارائه می دهد. این سرویس هزینه های حمل و نقل بهتر/ارزان تری را بر اساس ابعاد و وزن محصول ممکن می سازد.

از آنجایی که توسعه‌دهنده در این شرکت جدید است، از هوش مصنوعی Duet برای تولید کد، توضیح و مستندسازی استفاده می‌کند.

پس از کدگذاری سرویس، یک سرپرست پلتفرم از Duet AI (چت) برای کمک به ایجاد مصنوع (محفظه docker) و منابع مورد نیاز برای استقرار مصنوع در GCP (به عنوان مثال Artifact Registry، مجوزهای IAM، مخزن کد، محاسبه استفاده می کند. زیرساخت مانند GKE یا CloudRun و غیره)

هنگامی که برنامه در GCP مستقر شد، یک اپراتور برنامه/SRE از Duet AI (و Cloud Ops) برای کمک به عیب یابی یک خطا در سرویس جدید استفاده می کند.

پرسونا

این کارگاه افراد زیر را پوشش می دهد:

  1. برنامه نویس - مقداری دانش برنامه نویسی و توسعه نرم افزار مورد نیاز است.

این نسخه از کارگاه هوش مصنوعی Duet فقط برای توسعه دهندگان است. هیچ دانشی از منابع ابری GCP لازم نیست. اسکریپت‌های نحوه ساخت منابع GCP مورد نیاز برای اجرای این برنامه را می‌توانید در اینجا پیدا کنید. می‌توانید دستورالعمل‌های این راهنما را برای استقرار منابع GCP مورد نیاز دنبال کنید.

2. آماده سازی محیط

فعال سازی Duet AI

می‌توانید هوش مصنوعی Duet را در یک پروژه GCP از طریق API (ابزارهای gcloud یا IaC مانند Terraform) یا از طریق رابط کاربری Cloud Console فعال کنید .

برای فعال کردن Duet AI در پروژه Google Cloud، Cloud AI Companion API را فعال می‌کنید و نقش‌های Cloud AI Companion User و سرویس Usage Viewer Identity and Access Management (IAM) را به کاربران اعطا می‌کنید.

از طریق gcloud

فعال کردن Cloud Shell:

PROJECT_ID ، USER خود را پیکربندی کنید و 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}

خروجی به صورت زیر است:

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

اعطای نقش‌های Cloud AI Companion User و سرویس Usage Viewer Identity and Access Management (IAM) به حساب USER. Cloud Companion API پشت ویژگی‌های IDE و کنسولی قرار دارد که ما از آنها استفاده خواهیم کرد. مجوز سرویس Usage Viewer به عنوان یک بررسی سریع قبل از فعال کردن رابط کاربری در کنسول استفاده می‌شود (بنابراین Duet UI فقط در پروژه‌هایی که API در آنها فعال است ظاهر می‌شود).

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

خروجی به صورت زیر است:

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

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

از طریق Cloud Console

برای فعال کردن API، به صفحه Cloud AI Companion API در کنسول Google Cloud بروید.

در انتخابگر پروژه، یک پروژه را انتخاب کنید.

روی Enable کلیک کنید.

صفحه به روز می شود و وضعیت فعال را نشان می دهد. هوش مصنوعی Duet اکنون در پروژه انتخابی Google Cloud برای همه کاربرانی که نقش های IAM مورد نیاز را دارند در دسترس است.

برای اعطای نقش های IAM که برای استفاده از Duet AI مورد نیاز هستند، به صفحه IAM بروید.

در ستون اصلی ، USER خود را که می‌خواهید دسترسی به هوش مصنوعی Duet را برای آن فعال کنید، پیدا کنید و سپس روی نماد مداد ✏️ ویرایش اصل در آن ردیف کلیک کنید.

در پنجره دسترسی ویرایش ، روی افزودن نقش دیگری کلیک کنید.

در انتخاب نقش، Cloud AI Companion User را انتخاب کنید.

روی افزودن نقش دیگری کلیک کنید و Viewer Usage را انتخاب کنید.

روی ذخیره کلیک کنید.

راه اندازی IDE

توسعه دهندگان می توانند از بین IDE های متنوعی انتخاب کنند که به بهترین وجه با نیازهای آنها مطابقت دارد. کمک کد Duet AI در چندین IDE مانند Visual Studio Code ، JetBrains IDE (IntelliJ، PyCharm، GoLand، WebStorm و موارد دیگر)، ایستگاه های کاری ابری ، Cloud Shell Editor در دسترس است.

در این آزمایشگاه می‌توانید از Cloud Workstations یا Cloud Shell Editor استفاده کنید.

این کارگاه از ویرایشگر پوسته ابری استفاده می کند.

توجه داشته باشید که راه اندازی ایستگاه های کاری Cloud ممکن است 20 تا 30 دقیقه طول بکشد.

برای استفاده فوری، از Cloud Shell Editor استفاده کنید.

با کلیک بر روی نماد مداد ✏️ در نوار منوی بالای Cloud Shell خود، Cloud Shell Editor را باز کنید.

Cloud Shell Editor دارای UI و UX بسیار شبیه به VSCode است.

d6a6565f83576063.png

روی CTRL (در ویندوز)/CMD (در مک) + , (کاما) کلیک کنید تا وارد قسمت تنظیمات شوید.

در نوار جستجو، "duet ai" را تایپ کنید.

اطمینان یا فعال کردن Cloudcode › Duet AI: فعال و Cloudcode › Duet AI › پیشنهادات درون خطی: فعال کردن خودکار

111b8d587330ec74.png

در نوار وضعیت پایین، روی Cloud Code - Sign In کلیک کنید و گردش کار ورود به سیستم را دنبال کنید.

اگر قبلاً وارد سیستم شده‌اید، نوار وضعیت Cloud Code - No project را نشان می‌دهد.

روی Cloud Code کلیک کنید - هیچ پروژه ای وجود ندارد و یک پنجره بازشوی عمل در بالا ظاهر می شود. روی Select a Google Cloud project کلیک کنید.

3241a59811e3c84a.png

شروع به تایپ ID PROJECT خود کنید و پروژه شما باید در لیست ظاهر شود.

c5358fc837588fe.png

PROJECT_ID خود را از لیست پروژه ها انتخاب کنید.

نوار وضعیت پایین برای نشان دادن شناسه پروژه شما به روز می شود. اگر اینطور نیست، ممکن است لازم باشد تب Cloud Shell Editor خود را بازخوانی کنید.

روی نماد Duet AI کلیک کنید d97fc4e7b594c3af.png در نوار منوی سمت چپ و پنجره چت Duet AI ظاهر می شود. اگر پیامی دریافت کردید که می گوید پروژه GCP را انتخاب کنید. پروژه را کلیک کرده و مجدداً انتخاب کنید.

اکنون پنجره چت Duet AI را می بینید

781f888360229ca6.png

3. راه اندازی زیرساخت

d3234d237f00fdbb.png

برای اجرای سرویس حمل و نقل جدید در GCP، به منابع GCP زیر نیاز دارید:

  1. یک نمونه Cloud SQL، با یک پایگاه داده.
  2. یک خوشه GKE برای اجرای سرویس کانتینری.
  3. یک رجیستری مصنوع برای ذخیره تصویر داکر.
  4. یک مخزن منبع ابری برای کد.

در ترمینال Cloud Shell، مخزن زیر را شبیه سازی کنید و دستورات زیر را برای راه اندازی زیرساخت در پروژه GCP خود اجرا کنید.

# Set your project
export PROJECT_ID=<INSERT_YOUR_PROJECT_ID>
gcloud config set core/project ${PROJECT_ID}

# Enable Cloudbuild and grant Cloudbuild SA owner role 
export PROJECT_NUMBER=$(gcloud projects describe ${PROJECT_ID} --format 'value(projectNumber)')
gcloud services enable cloudbuild.googleapis.com
gcloud projects add-iam-policy-binding ${PROJECT_ID} --member serviceAccount:${PROJECT_NUMBER}@cloudbuild.gserviceaccount.com --role roles/owner

# Clone the repo
git clone https://github.com/duetailabs/dev.git ~/duetaidev
cd ~/duetaidev

# Run Cloudbuild to create the necessary resources
gcloud builds submit --substitutions=_PROJECT_ID=${PROJECT_ID}

# To destroy all GCP resources, run the following
# gcloud builds submit --substitutions=_PROJECT_ID=${PROJECT_ID} --config=cloudbuild_destroy.yaml

4. توسعه یک سرویس python Flask

9745ba5c70782e76.png

سرویسی که ما ایجاد خواهیم کرد در نهایت شامل فایل های زیر خواهد بود. اکنون نیازی به ایجاد این فایل‌ها ندارید و این فایل‌ها را در یک زمان با پیروی از دستورالعمل‌های زیر ایجاد خواهید کرد:

  1. package-service.yaml - یک ویژگی Open API برای سرویس بسته که دارای داده‌هایی مانند ارتفاع، عرض، وزن و دستورالعمل‌های ویژه است.
  2. data_model.py - مدل داده برای مشخصات بسته سرویس API. همچنین جدول packages را در DB product_details ایجاد می کند.
  3. connect_connector.py - اتصال CloudSQL (موتور، Session و ORM پایه را تعریف می کند)
  4. db_init.py - داده های نمونه را در جدول packages ایجاد می کند.
  5. main.py - یک سرویس Python Flask با نقطه پایانی GET برای بازیابی جزئیات بسته از داده های packages بر اساس product_id.
  6. test.py - تست واحد
  7. requirement.txt - الزامات پایتون
  8. Dockerfile - برای کانتینری کردن این برنامه

اگر در طول تمرینات به مشکل چسبناکی برخورد کردید، فایل های نهایی همگی برای مرجع در ضمیمه این کد لبه قرار می گیرند.

در مرحله قبل، یک مخزن Cloud Source ایجاد کردید. مخزن را شبیه سازی کنید. فایل های برنامه را در پوشه مخزن کلون شده می سازید.

در ترمینال Cloud Shell، دستور زیر را برای کلون کردن مخزن اجرا کنید.

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

نوار کناری چت Duet AI را از منوی سمت چپ Cloud Shell Editor باز کنید. نماد به نظر می رسد 8b135a000b259175.png . اکنون می توانید از هوش مصنوعی Duet برای کمک به کد استفاده کنید.

package-service.yaml

بدون باز کردن هیچ فایلی، از Duet بخواهید که مشخصات Open API را برای سرویس حمل و نقل ایجاد کند.

درخواست 1: برای سرویسی که اطلاعات حمل و نقل و بسته را با یک شناسه عددی محصول ارائه می‌کند، مشخصات Yaml OpenAPI ایجاد کنید. این سرویس باید شامل اطلاعاتی در مورد ارتفاع، عرض، عمق، وزن بسته‌ها و هر دستورالعمل خاص حمل و نقل باشد.

ba12626f491a1204.png

سه گزینه در سمت راست بالای پنجره کد تولید شده وجود دارد.

می توانید COPY 71194556d8061dae.png کد را وارد کنید و آن را در یک فایل PEST کنید.

می توانید ADD df645de8c65607a.png کد فایل فعلی باز شده در ویرایشگر.

یا می توانید OPEN a4c7ed6d845df343.png کد در یک فایل جدید

OPEN کلیک کنید a4c7ed6d845df343.png کد در یک فایل جدید

برای ذخیره فایل روی CTRL/CMD + s کلیک کنید و فایل را در پوشه برنامه با نام فایل به نام package-service.yaml ذخیره کنید. روی OK کلیک کنید.

f6ebd5b836949366.png

فایل نهایی در قسمت APPENDIX این کد لبه است. اگر اینطور نیست، به صورت دستی تغییرات مناسب را انجام دهید.

همچنین می‌توانید برای مشاهده پاسخ‌های Duet AI، دستورهای مختلفی را امتحان کنید.

با کلیک بر روی نماد سطل زباله، سابقه چت Duet AI را بازنشانی کنید f574ca2c1e114856.png در بالای نوار کناری Duet AI.

data_model.py

در مرحله بعد، فایل پایتون مدل داده را برای سرویس بر اساس مشخصات OpenAPI ایجاد می کنید.

با باز کردن فایل package-service.yaml ، دستور زیر را وارد کنید.

درخواست 1: با استفاده از python sqlalchemy ORM، یک مدل داده برای این سرویس API ایجاد کنید. همچنین شامل یک تابع مجزا و یک ورودی اصلی که جداول پایگاه داده را ایجاد می کند.

b873a6a28bd28ca1.png

بیایید به هر بخشی که تولید شده است نگاه کنیم. هوش مصنوعی Duet هنوز یک دستیار است، و در حالی که می تواند به سرعت کدنویسی کمک کند، همچنان باید محتوای تولید شده را مرور کنید و آن را در حین حرکت درک کنید.

ابتدا یک کلاس به نام Package of kind Base وجود دارد که مدل داده را برای پایگاه داده packages مانند زیر تعریف می کند:

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

در مرحله بعد، به تابعی نیاز دارید که جدول را در پایگاه داده مانند زیر ایجاد کند:

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

در نهایت، شما به یک تابع اصلی نیاز دارید که تابع create_tables را اجرا کند تا در واقع جدول را در پایگاه داده CloudSQL بسازد، مانند زیر:

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

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

    print('Tables created successfully.')

توجه داشته باشید که عملکرد main ایجاد یک موتور با استفاده از پایگاه داده محلی sqlite است. برای استفاده از CloudSQL، باید آن را تغییر دهید. شما این کار را کمی بعد انجام دهید.

با استفاده از OPEN a4c7ed6d845df343.png کد در یک گردش کار فایل جدید مانند قبل. کد را در فایلی به نام data_model.py ذخیره کنید (به خط زیر در نام توجه کنید نه خط تیره).

با کلیک بر روی نماد سطل زباله، سابقه چت Duet AI را بازنشانی کنید f574ca2c1e114856.png در بالای نوار کناری Duet AI.

connect-connector.py

کانکتور CloudSQL را ایجاد کنید.

با باز بودن فایل data_model.py ، دستورات زیر را وارد کنید.

درخواست 1: با استفاده از کتابخانه cloud-sql-python-connector، تابعی را ایجاد کنید که یک مخزن اتصال را برای یک نمونه Cloud SQL از Postgres راه اندازی می کند.

ed05cb6ff85d34c5.png

توجه داشته باشید که پاسخ از کتابخانه cloud-sql-python-connector استفاده نمی کند. می‌توانید با افزودن ویژگی‌های خاص به همان موضوع چت، درخواست‌ها را اصلاح کنید تا کمی تند به Duet بدهید.

بیایید از یک دستور دیگر استفاده کنیم.

درخواست 2: باید از کتابخانه cloud-sql-python-connector استفاده کنید.

d09095b44dde35bf.png

مطمئن شوید که از کتابخانه cloud-sql-python-connector استفاده می کند.

با استفاده از OPEN a4c7ed6d845df343.png کد در یک گردش کار فایل جدید مانند قبل. کد را در فایلی به نام connect_conector.py ذخیره کنید. ممکن است لازم باشد کتابخانه pg8000 را به صورت دستی وارد کنید، لطفاً فایل زیر را ببینید.

تاریخچه چت Duet AI را پاک کنید و با باز کردن فایل connect_connector.py ، DB engine ، sessionmaker و ORM base را برای استفاده در برنامه ایجاد کنید.

درخواست 1: با استفاده از روش connect_with_connector یک موتور، کلاس sessionmaker و Base ORM ایجاد کنید.

6e4214b72ab13a63.png

پاسخ ممکن است engine ، Session و Base به فایل connect_connector.py اضافه کند.

فایل نهایی در قسمت APPENDIX این کد لبه است. اگر اینطور نیست، به صورت دستی تغییرات مناسب را انجام دهید.

همچنین می‌توانید اعلان‌های مختلفی را امتحان کنید تا تغییرات احتمالی پاسخ‌های Duet AI را ببینید.

با کلیک بر روی نماد سطل زباله، سابقه چت Duet AI را بازنشانی کنید f574ca2c1e114856.png در بالای نوار کناری Duet AI.

در حال به روز رسانی data_model.py

برای ایجاد جدول در پایگاه داده CloudSQL باید از موتوری که در مرحله قبل ایجاد کردید (در فایل connect_connector.py ) استفاده کنید.

تاریخچه چت Duet AI را پاک کنید. فایل data_model.py را باز کنید. دستور زیر را امتحان کنید.

درخواست 1: در تابع main، موتور را از connect_connector.py وارد کرده و از آن استفاده کنید

2e768c9b6c523b9a.png

باید engine واردکننده پاسخ را از connect_connector (برای CloudSQL) ببینید. create_table از آن موتور استفاده می کند (به جای DB محلی پیش فرض sqlite ).

فایل data_model.py را به روز کنید.

فایل نهایی در قسمت APPENDIX این کد لبه است. اگر اینطور نیست، به صورت دستی تغییرات مناسب را انجام دهید.

همچنین می‌توانید اعلان‌های مختلفی را برای مشاهده پاسخ‌های مختلف Duet AI امتحان کنید.

با کلیک بر روی نماد سطل زباله، سابقه چت Duet AI را بازنشانی کنید f574ca2c1e114856.png در بالای نوار کناری Duet AI.

الزامات. txt

یک فایل requirements.txt برای برنامه ایجاد کنید.

هر دو فایل connect_connector.py و data_model.py را باز کنید و دستور زیر را وارد کنید.

درخواست 1: یک فایل مورد نیاز پیپ برای این مدل داده و سرویس ایجاد کنید

درخواست 2: با استفاده از آخرین نسخه، یک فایل مورد نیاز پیپ برای این مدل داده و سرویس ایجاد کنید

69fae373bc5c6a18.png

بررسی کنید که نام ها و نسخه ها صحیح باشند. به عنوان مثال، در پاسخ بالا، نام و نسخه google-cloud-sql-connecter هر دو نادرست است. نسخه ها را به صورت دستی اصلاح کنید و یک فایل requirements.txt ایجاد کنید که به شکل زیر است:

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

در ترمینال فرمان موارد زیر را اجرا کنید:

pip3 install -r requirements.txt

با کلیک بر روی نماد سطل زباله، سابقه چت Duet AI را بازنشانی کنید f574ca2c1e114856.png در بالای نوار کناری Duet AI.

ایجاد جدول بسته ها در CloudSQL

متغیرهای محیطی را برای رابط پایگاه داده CloudSQL تنظیم کنید.

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

اکنون data_model.py را اجرا کنید.

python data_model.py

خروجی مشابه زیر است (کد را بررسی کنید تا ببینید واقعاً چه چیزی انتظار می رود):

Tables created successfully.

به نمونه CloudSQL متصل شوید و بررسی کنید پایگاه داده ایجاد شده است.

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

پس از وارد کردن رمز عبور (همچنین evolution )، جداول را دریافت کنید.

product_details=> \dt

خروجی مشابه موارد زیر است:

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

همچنین می توانید مدل داده و جزئیات جدول را بررسی کنید.

product_details=> \d+ packages

خروجی مشابه زیر است:

                                                                        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 \q را تایپ کنید.

db_init.py

در مرحله بعد، اجازه دهید برخی از داده های نمونه را به جدول packages اضافه کنیم.

تاریخچه چت Duet AI را پاک کنید. با باز بودن فایل data_model.py ، دستورات زیر را امتحان کنید.

درخواست 1: تابعی را ایجاد کنید که 10 ردیف بسته نمونه ایجاد می کند و آنها را به جدول بسته ها متعهد می کند.

درخواست 2: با استفاده از جلسه از connect_connector، تابعی را ایجاد کنید که 10 ردیف بسته نمونه ایجاد می کند و آنها را به جدول بسته ها متعهد می کند.

34a9afc5f04ba5.png

با استفاده از OPEN a4c7ed6d845df343.png کد در یک گردش کار فایل جدید مانند قبل. کد را در فایلی به نام db_init.py ذخیره کنید.

فایل نهایی در قسمت APPENDIX این کد لبه است. اگر اینطور نیست، به صورت دستی تغییرات مناسب را انجام دهید.

همچنین می‌توانید اعلان‌های مختلفی را برای مشاهده پاسخ‌های مختلف Duet AI امتحان کنید.

با کلیک بر روی نماد سطل زباله، سابقه چت Duet AI را بازنشانی کنید f574ca2c1e114856.png در بالای نوار کناری Duet AI.

ایجاد داده های بسته های نمونه

db_init.py از خط فرمان اجرا کنید.

python db_init.py

خروجی مشابه موارد زیر است:

Packages created successfully.

دوباره به نمونه CloudSQL متصل شوید و بررسی کنید که داده های نمونه به جدول بسته ها اضافه شده است.

به نمونه CloudSQL متصل شوید و بررسی کنید پایگاه داده ایجاد شده است.

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

پس از وارد کردن رمز عبور (همچنین تکامل )، تمام داده ها را از جدول بسته ها دریافت کنید.

product_details=> SELECT * FROM packages;

خروجی مشابه موارد زیر است:

 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 \q را تایپ کنید.

main.py

با باز کردن فایل‌های data_model.py ، package-service.yaml ، و connect_connector.py ، یک main.py برای برنامه ایجاد کنید.

درخواست 1: با استفاده از کتابخانه فلاسک پایتون - پیاده سازی ایجاد کنید که از نقاط پایانی http rest برای این سرویس استفاده کند.

درخواست 2: با استفاده از کتابخانه python flask - پیاده سازی ایجاد کنید که از نقاط پایانی http rest برای این سرویس استفاده کند. SessionMaker را از connect_conector.py به برای داده های بسته ها وارد کرده و استفاده کنید.

درخواست 3: با استفاده از کتابخانه python flask - پیاده سازی ایجاد کنید که از نقاط پایانی http rest برای این سرویس استفاده کند. Package را از data_model.py و SessionMaker را از connect_conector.py به داده های بسته ها وارد کرده و استفاده کنید.

درخواست 4: با استفاده از کتابخانه python flask - پیاده سازی ایجاد کنید که از نقاط پایانی http rest برای این سرویس استفاده کند. Package را از data_model.py و SessionMaker را از connect_conector.py به داده های بسته ها وارد کرده و استفاده کنید. برای app.run از IP میزبان 0.0.0.0 استفاده کنید

6d794fc52a90e6ae.png

الزامات main.py را به روز کنید.

Prompt: فایل مورد نیاز را برای main.py ایجاد کنید

1cc0b318d2d4ca2f.png

این را به فایل requirements.txt اضافه کنید. حتما از Flask نسخه 3.0.0 استفاده کنید.

با استفاده از OPEN a4c7ed6d845df343.png کد در یک گردش کار فایل جدید مانند قبل. کد را در فایلی به نام main.py ذخیره کنید.

فایل نهایی در قسمت APPENDIX این کد لبه است. اگر اینطور نیست، به صورت دستی تغییرات مناسب را انجام دهید.

با کلیک بر روی نماد سطل زباله، سابقه چت Duet AI را بازنشانی کنید f574ca2c1e114856.png در بالای نوار کناری Duet AI.

5. تست و اجرای برنامه

الزامات را نصب کنید.

pip3 install -r requirements.txt

main.py اجرا کنید.

python main.py

خروجی مشابه موارد زیر است:

 * 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

از ترمینال دوم، نقطه پایانی /packages/<product_id> را آزمایش کنید.

curl localhost:5000/packages/1

خروجی مشابه موارد زیر است:

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

همچنین می توانید هر شناسه محصول دیگری را در داده های نمونه خود آزمایش کنید.

CTRL_C وارد کنید تا از کانتینر docker در حال اجرا در ترمینال خارج شوید.

تست های واحد تولیدی

با باز بودن فایل main.py ، تست های واحد تولید کنید.

درخواست 1: تست های واحد تولید کنید.

e861e5b63e1b2657.png

با استفاده از OPEN a4c7ed6d845df343.png کد در یک گردش کار فایل جدید مانند قبل. کد را در فایلی به نام test.py ذخیره کنید.

در تابع test_get_package باید یک product_id تعریف شود. می توانید به صورت دستی آن را اضافه کنید.

فایل نهایی در قسمت APPENDIX این کد لبه است. اگر اینطور نیست، به صورت دستی تغییرات مناسب را انجام دهید.

با کلیک بر روی نماد سطل زباله، سابقه چت Duet AI را بازنشانی کنید f574ca2c1e114856.png در بالای نوار کناری Duet AI.

در حال اجرا تست های واحد

تست واحد را اجرا کنید.

python test.py

خروجی مشابه موارد زیر است:

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

OK

همه فایل‌ها را در Cloud Shell Editor ببندید و با کلیک بر روی نماد سطل زباله، تاریخچه چت را پاک کنید 1ecccfe10d6c540.png در نوار وضعیت بالا

Dockerfile

یک Dockerfile برای این برنامه ایجاد کنید.

main.py را باز کنید و دستورات زیر را امتحان کنید.

درخواست 1: یک Dockerfile برای این برنامه ایجاد کنید.

درخواست 2: یک Dockerfile برای این برنامه ایجاد کنید. همه فایل ها را در کانتینر کپی کنید.

9c473caea437a5c3.png

همچنین باید ENVARS برای INSTANCE_CONNECTION_NAME ، DB_USER ، DB_PASS و DB_NAME تنظیم کنید. شما می توانید این کار را به صورت دستی انجام دهید. 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"]

با استفاده از OPEN a4c7ed6d845df343.png کد در یک گردش کار فایل جدید مانند قبل. کد را در فایلی به نام Dockerfile ذخیره کنید.

فایل نهایی در قسمت APPENDIX این کد لبه است. اگر اینطور نیست، به صورت دستی تغییرات مناسب را انجام دهید.

به صورت محلی برنامه را اجرا می کند

با باز بودن Dockerfile ، دستور زیر را امتحان کنید.

درخواست 1: چگونه می توانم با استفاده از این Dockerfile یک کانتینر را به صورت محلی اجرا کنم

570fd5c296ca8c83.png

دستورالعمل ها را دنبال کنید.

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

خروجی مشابه موارد زیر است:

 * 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

از پنجره ترمینال دوم، به ظرف دسترسی پیدا کنید.

curl localhost:5000/packages/1

خروجی مشابه موارد زیر است:

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

برنامه کانتینری در حال کار است.

CTRL_C وارد کنید تا از کانتینر docker در حال اجرا در ترمینال خارج شوید.

ساخت تصویر کانتینر در رجیستری مصنوع

تصویر ظرف را بسازید و به رجیستری Artifact فشار دهید.

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

ظرف برنامه اکنون در us-central1-docker.pkg.dev/${PROJECT_ID}/shipping/shipping قرار دارد که می‌تواند در GKE مستقر شود.

6. استقرار برنامه در خوشه GKE

هنگامی که شما منابع GCP را برای این کارگاه ساختید، یک خوشه خودکار GKE ایجاد شد. به خوشه GKE متصل شوید.

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

حساب سرویس پیش فرض Kubernetes را با حساب سرویس Google حاشیه نویسی کنید.

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

خروجی مشابه موارد زیر است:

serviceaccount/default annotated

فایل 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

خروجی مشابه موارد زیر است:

deployment.apps/shipping created
service/shipping created

صبر کنید تا Pods اجرا شود و سرویس یک آدرس IP خارجی متعادل کننده بار اختصاص داده شود.

kubectl get pods
kubectl get service shipping

خروجی مشابه موارد زیر است:

# 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، چند لحظه صبر کنید تا منابع آماده شوند.

از طریق آدرس EXTERNAL-IP به سرویس دسترسی پیدا کنید.

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

خروجی مشابه زیر است:

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

7. اعتبار اضافی: عیب یابی برنامه

نقش CloudSQL Client IAM را از حساب سرویس cloudsqlsa حذف کنید. این باعث ایجاد خطا در اتصال به پایگاه داده CloudSQL می شود.

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

Pod حمل و نقل را مجدداً راه اندازی کنید.

kubectl rollout restart deployment shipping

پس از راه اندازی مجدد پاد، دوباره سعی کنید به سرویس shipping دسترسی پیدا کنید.

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

خروجی مشابه موارد زیر است:

...
<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 > Workloads، گزارش‌ها را بررسی کنید

d225b1916c829167.png

روی استقرار shipping و سپس برگه Logs کلیک کنید.

1d0459141483d6a7.png

روی View in Log Explorer کلیک کنید df8b9d19a9fe4c73.png نماد سمت راست نوار وضعیت با این کار یک پنجره Log Explorer جدید باز می شود.

e86d1c265e176bc4.png

روی یکی از ورودی های خطای Traceback کلیک کنید و سپس روی توضیح این ورود ورود کلیک کنید.

d6af045cf03008bc.png

می توانید توضیح خطا را بخوانید.

در مرحله بعد، بیایید هوش مصنوعی Duet را برای کمک به عیب یابی خطا دریافت کنیم.

دستور زیر را امتحان کنید.

درخواست 1: به من کمک کنید این خطا را عیب یابی کنم

9288dd6045369167.png

پیام خطا را در اعلان وارد کنید.

درخواست 2: ممنوع: به نظر نمی رسد که اصل IAM تأیید شده مجاز به درخواست API باشد. بررسی کنید که «Cloud SQL Admin API» در پروژه GCP شما فعال است و نقش «Cloud SQL Client» به اصلی IAM اعطا شده است.

f1e64fbdc435d31c.png

و سپس.

درخواست 3: چگونه می توانم نقش Cloud SQL Client را با استفاده از gcloud به حساب سرویس Google اختصاص دهم؟

bb8926b995a8875c.png

نقش Cloud SQL Client را به cloudsqlsa اختصاص دهید.

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

چند لحظه صبر کنید و دوباره سعی کنید به برنامه دسترسی داشته باشید.

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

خروجی مشابه موارد زیر است:

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

شما با موفقیت از هوش مصنوعی Duet در Cloud Logging ، Log Explorer و ویژگی Log Explainer برای عیب یابی استفاده کرده اید.

8. نتیجه گیری

تبریک می گویم! شما با موفقیت این کد را تکمیل کردید.

در این کد لبه موارد زیر را یاد گرفتید:

  1. Duet AI را در پروژه GCP خود فعال کنید و آن را برای استفاده در یک IDE و Cloud Console پیکربندی کنید.
  2. از هوش مصنوعی Duet برای تولید کد، تکمیل و توضیح استفاده کنید.
  3. از هوش مصنوعی Duet برای توضیح و عیب یابی یک مشکل برنامه استفاده کنید.
  4. ویژگی‌های هوش مصنوعی Duet مانند چت IDE و چت چند نوبتی، چت در مقابل تولید کد درون خطی، اقدامات هوشمندانه مانند توضیح کد و تصدیق تلاوت و موارد دیگر.

9. ضمیمه

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

الزامات. 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"]