1. الأهداف
تهدف ورشة العمل هذه إلى توفير تعليم عملي بشأن Duet AI للمستخدمين والممارسين.
في هذا الدرس التطبيقي حول الترميز، ستتعرَّف على ما يلي:
- تفعيل Duet AI في مشروع Google Cloud Platform وإعداده للاستخدام في بيئة تطوير متكاملة (IDE) وCloud Console
- استخدام Duet AI لإنشاء الرموز البرمجية وإكمالها وشرحها
- يمكنك استخدام Duet AI لتوضيح مشكلة في التطبيق وحلّها.
- ميزات Duet AI، مثل المحادثة عبر بيئة تطوير متكاملة (IDE) والمحادثة المتعدّدة الأدوار والمحادثة وإنشاء الرموز المضمَّنة وإجراءات ذكية، مثل شرح الرموز البرمجية والإقرار بالتلاوات وغير ذلك
Narrative
إنّ أنشطة ورشة العمل هذه تتم في سياق سردي لشرح كيفية استخدام Duet AI for Developers بشكل أصيل في عمليات التطوير اليومية.
ينضم مطوِّر جديد إلى شركة تجارة إلكترونية. ويُكلف الفريق بإضافة خدمة جديدة إلى تطبيق التجارة الإلكترونية الحالي (تتألف من خدمات متعددة). توفّر الخدمة الجديدة معلومات إضافية (الأبعاد والوزن وما إلى ذلك) عن المنتجات في كتالوج المنتجات. تتيح هذه الخدمة توفير تكاليف شحن أفضل/أقل استنادًا إلى أبعاد المنتج وأوزانه.
بما أنّ المطوّر هو مستخدِم جديد في الشركة، سيستخدم Duet AI لإنشاء الرموز وشرحها ومستنداتها.
بعد ترميز الخدمة، سيستخدم مشرف النظام الأساسي Duet AI (الدردشة) للمساعدة في إنشاء العنصر (حاوية التخزين)، والموارد اللازمة لنشر العناصر في Google Cloud Platform (مثل Artifact Registry وأذونات "إدارة الهوية وإمكانية الوصول" ومستودع الرموز والبنية الأساسية للحوسبة، مثل GKE أو CloudRun وما إلى ذلك).
بعد نشر التطبيق على Google Cloud Platform، سيستخدم مشغّل التطبيق/SRE Duet AI (وعمليات Cloud Ops) للمساعدة في تحديد خطأ ما في الخدمة الجديدة وحلّها.
الشخصية
تتناول ورشة العمل الشخصية التالية:
- مطوِّر التطبيقات: يلزم معرفة بعض الخبرة في مجال البرمجة وتطوير البرامج.
هذا الشكل من ورشة عمل Duet AI مخصّص للمطوّرين فقط. لست بحاجة إلى معرفة موارد السحابة الإلكترونية في Google Cloud Platform. يمكن العثور على النصوص البرمجية لكيفية إنشاء موارد GCP المطلوبة لتشغيل هذا التطبيق هنا. يمكنك اتّباع التعليمات الواردة في هذا الدليل لنشر موارد GCP المطلوبة.
2. تحضير البيئة
جارٍ تفعيل Duet AI
يمكنك تفعيل Duet AI في مشروع على Google Cloud Platform إما من خلال واجهة برمجة التطبيقات (gcloud أو أدوات IaC مثل Terraform) أو من خلال واجهة مستخدم Cloud Console.
لتفعيل Duet AI في مشروع على Google Cloud، عليك تفعيل Cloud AI Companion API ومنح "المستخدم المصاحب" في Cloud AI ودورَي "إدارة الهوية وإمكانية الوصول" (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.
امنح "المستخدم المصاحب" للذكاء الاصطناعي في السحابة الإلكترونية ودور "إدارة الهوية وإمكانية الوصول" (IAM) لعارض استخدام الخدمة لحساب "المستخدم". تستند واجهة برمجة التطبيقات Cloud Companion API إلى الميزات المتوفّرة في كل من بيئة التطوير المتكاملة (IDE) ووحدة التحكّم التي سنستخدمها. يُستخدم إذن "عارِض استخدام الخدمة" كفحص سريع قبل تفعيل واجهة المستخدم في وحدة التحكّم (بحيث لا تظهر واجهة مستخدم Duet إلا في المشاريع التي تم فيها تفعيل واجهة برمجة التطبيقات).
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
لتفعيل واجهة برمجة التطبيقات، يُرجى الانتقال إلى صفحة Cloud AI Companion API في Google Cloud Console.
في أداة اختيار المشروع، اختَر مشروعًا.
انقر على تفعيل.
يتم تعديل الصفحة وعرض الحالة مفعّل. يتوفّر Duet AI الآن في مشروع Google Cloud المحدّد لجميع المستخدمين الذين لديهم أدوار "إدارة الهوية وإمكانية الوصول" المطلوبة.
لمنح أدوار "إدارة الهوية وإمكانية الوصول" المطلوبة لاستخدام Duet AI، انتقِل إلى صفحة IAM.
في العمود مدير الحساب، ابحث عن المستخدم الذي تريد تفعيل إذن الوصول إلى Duet AI له، ثم انقر على رمز القلم الرصاص ✏️ تعديل المدير في ذلك الصف.
في لوحة تعديل إذن الوصول، انقر على إضافة دور آخر.
في "اختيار دور"، اختَر مستخدم مصاحب في Cloud AI.
انقر على إضافة دور آخر واختَر مُشاهد استخدام الخدمة.
انقر على حفظ.
إعداد بيئة التطوير المتكاملة
يمكن للمطوّرين الاختيار من بين مجموعة متنوّعة من حِزم تطوير البرامج (IDE) التي تناسب احتياجاتهم على أفضل وجه. تتوفّر ميزة المساعدة في رمز Duet AI في العديد من بيئات IDE، مثل Visual Studio Code وJetBrains IDE (IntelliJ وPyCharm وGoLand وWebStorm وغيرها) وCloud Workstations وCloud Shell Editor.
في هذا الدرس التطبيقي، يمكنك استخدام Cloud Workstations أو محرِّر Cloud Shell.
تستخدم ورشة العمل هذه محرِّر Cloud Shell.
يُرجى العلم أنّ إعداد Cloud Workstations قد يستغرق مدة تتراوح بين 20 و30 دقيقة.
لاستخدامها على الفور، استخدِم محرِّر Cloud Shell.
افتح تطبيق Cloud Shell Editor من خلال النقر على رمز القلم الرصاص ✏️ في شريط القائمة العلوي في Cloud Shell.
يحتوي محرِّر Cloud Shell على واجهة مستخدم وتجربة مستخدم متشابهة جدًا مع VSCode.
انقر على CTRL (في نظام التشغيل Windows)/CMD (في نظام التشغيل Mac) + , (فاصلة) للدخول إلى جزء الإعدادات.
في شريط البحث، اكتب "duet ai".
تأكَّد من Cloudcode أو فعِّله › Duet AI: تفعيل وCloudcode › Duet AI › الاقتراحات المضمّنة: تفعيل تلقائي
في شريط الحالة في أسفل الصفحة، انقر على رمز السحابة الإلكترونية - تسجيل الدخول واتّبِع خطوات تسجيل الدخول.
إذا سبق أن سجّلت الدخول، سيعرض شريط الحالة Cloud Code - ليس هناك مشروع.
انقر فوق "Cloud Code" (رمز السحابة) - لن يظهر أي مشروع وستظهر لوحة الإجراءات المنسدلة في الأعلى. انقر على اختيار مشروع على Google Cloud.
ابدأ في كتابة معرّف المشروع وسيظهر مشروعك في القائمة.
حدد PROJECT_ID من قائمة المشروعات.
يتم تعديل شريط الحالة السفلي لعرض رقم تعريف مشروعك. وفي حال عدم حدوث ذلك، قد تحتاج إلى إعادة تحميل علامة التبويب "محرِّر Cloud Shell".
انقر على رمز Duet AI في شريط القوائم الأيمن، وستظهر نافذة المحادثة في Duet AI. إذا ظهرت رسالة تشير إلى اختيار مشروع Google Cloud Platform. انقر على المشروع وأعِد اختياره.
ستظهر الآن نافذة محادثة Duet AI.
3- إعداد البنية الأساسية
لاستخدام خدمة الشحن الجديدة في Google Cloud Platform، يجب أن تتوفّر لديك المَراجع التالية من Google Cloud Platform:
- مثيل Cloud SQL مع قاعدة بيانات.
- مجموعة GKE لتشغيل الخدمة المضمّنة في الحاوية.
- Artifact Registry لتخزين صورة Docker
- مستودع مصدر السحابة الإلكترونية للرمز البرمجي
في الوحدة الطرفية Cloud Shell، استنسِخ المستودع التالي وشغِّل الأوامر التالية لإعداد البنية الأساسية في مشروع Google Cloud Platform.
# 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
ستتألف الخدمة التي سننشئها في النهاية من الملفات التالية. لا تحتاج إلى إنشاء هذه الملفات الآن وسيتم إنشاؤها واحدًا تلو الآخر من خلال اتّباع التعليمات أدناه:
package-service.yaml
- مواصفات واجهة برمجة التطبيقات المفتوحة لخدمة الحزمة التي تتضمن بيانات مثل الطول والعرض والوزن وتعليمات المناولة الخاصة.data_model.py
- نموذج البيانات لمواصفات واجهة برمجة تطبيقات خدمة الحزمة. تنشئ أيضًا جدولpackages
في قاعدة بيانات product_details.connect_connector.py
: اتصال CloudSQL (يعرّف المحرّك والجلسة وقاعدة ORM الأساسية)db_init.py
: إنشاء عيّنات بيانات في جدولpackages
main.py
: خدمة Python Flask مع نقطة نهايةGET
لاسترداد تفاصيل الحزمة من بياناتpackages
استنادًا إلى product_id.test.py
- اختبار الوحدةrequirement.txt
- متطلبات PythonDockerfile
- لتضمين هذا التطبيق
إذا واجهت أي مشاكل ثابتة أثناء التمارين، يمكنك الاطّلاع على الملفات النهائية في ملحق هذا الدرس التطبيقي حول الترميز.
في الخطوة السابقة، أنشأت مستودع Cloud Source. استنساخ المستودع. ستنشئ ملفات التطبيق في مجلد المستودع المنسوخ.
في الوحدة الطرفية Cloud Shell، شغِّل الأمر التالي لانسخ المستودع.
cd ~ gcloud source repos clone shipping shipping cd ~/shipping
افتح الشريط الجانبي للمحادثة في Duet AI من القائمة اليمنى في "محرِّر Cloud Shell". يبدو الرمز مثل . يمكنك الآن استخدام Duet AI للحصول على مساعدة بشأن الرمز البرمجي.
package-service.yaml
بدون فتح أي ملفات، اطلب من Duet إنشاء إحدى مواصفات واجهة برمجة التطبيقات المفتوحة لخدمة الشحن.
المطالبة 1: إنشاء مواصفات yaml في OpenAPI لخدمة تقدم معلومات الشحن والحزمة باستخدام معرّف رقمي للمنتج. ويجب أن تتضمّن الخدمة معلومات عن ارتفاع الطرود وعرضها وعمقها ووزنها وأي تعليمات خاصة حول المناولة.
هناك ثلاثة خيارات مدرجة في أعلى يسار نافذة الرمز التي تم إنشاؤها.
يمكنك COPY
الرمز ولصقه في ملف.
يمكنك ADD
إضافة الرمز إلى الملف المفتوح حاليًا في "محرّر إعلانات Google".
أو يمكنك OPEN
الرمز في ملف جديد.
انقر على الرمز OPEN
في ملف جديد.
انقر على CTRL/CMD + s
لحفظ الملف وتخزين الملف في مجلد التطبيق باسم ملف باسم package-service.yaml
. انقر على "موافق".
الملف الأخير موجود في قسم APPENDIX من هذا الدرس التطبيقي حول الترميز. وإذا لم يحدث ذلك، يمكنك إجراء التغييرات المناسبة يدويًا.
يمكنك أيضًا تجربة طلبات مختلفة للاطّلاع على ردود Duet AI.
يمكنك إعادة ضبط سجلّ محادثات Duet AI من خلال النقر على رمز المهملات في أعلى الشريط الجانبي في Duet AI.
data_model.py
بعد ذلك، يمكنك إنشاء ملف نموذج البيانات بايثون للخدمة بناءً على مواصفات OpenAPI.
بعد فتح الملف package-service.yaml
، أدخِل الطلب التالي.
المطالبة 1: باستخدام ORM بلغة python sqlalchemy، يمكنك إنشاء نموذج بيانات لخدمة واجهة برمجة التطبيقات هذه. عليك أيضًا تضمين دالة منفصلة ونقطة إدخال رئيسية لإنشاء جداول قاعدة البيانات.
لنلقِ نظرة على كل جزء تم إنشاؤه. لا يزال Duet AI مساعدًا، ومع أنّه يمكنه المساعدة في كتابة الرموز البرمجية بسرعة، من المفترَض أن تستمرّ في مراجعة المحتوى الذي يتم إنشاؤه وفهمه خلال عملية الإنشاء.
أولاً، هناك فئة تُسمى Package
من النوع 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
في سير عمل جديد للملفات على النحو السابق. احفظ الرمز في ملف باسم
data_model.py
(يُرجى ملاحظة استخدام الشرطة السفلية في الاسم وليس شرطة).
يمكنك إعادة ضبط سجلّ محادثات Duet AI من خلال النقر على رمز المهملات في أعلى الشريط الجانبي في Duet AI.
connect-connector.py
أنشِئ موصِّل CloudSQL.
بعد فتح ملف data_model.py
، أدخِل الطلبات التالية.
الطلب 1: باستخدام مكتبة cloud-sql-python-connector، إنشاء دالة تهيئ مجموعة اتصالات لمثيل Cloud SQL من Postgres
يُرجى العِلم أنّ الردّ لا يستخدم مكتبة "cloud-sql-python-connector
". يمكنك تحسين الطلبات من خلال إضافة تذكير تلقائي إلى Duet AI، وذلك من خلال إضافة تفاصيل إلى سلسلة المحادثات نفسها.
لنستخدم طلبًا آخر.
المطالبة 2: يجب استخدام مكتبة cloud-sql-python-connector.
تأكّد من أنّه يستخدم مكتبة cloud-sql-python-connector
.
استخدام الرمز OPEN
في سير عمل جديد للملفات على النحو السابق. احفظ الرمز في ملف باسم
connect_conector.py
. قد تحتاج إلى استيراد مكتبة pg8000
يدويًا، ويُرجى الاطّلاع على الملف أدناه.
يمكنك محو سجلّ محادثات Duet AI، وفتح الملف connect_connector.py
، يمكنك إنشاء عمليات ORM DB engine
وsessionmaker
وbase
لاستخدامها في التطبيق.
المطالبة 1: إنشاء محرك وفئة صانع جلسات وقاعدة ORM باستخدام طريقة Connect_with_connector
قد يُلحق الرد engine
وSession
وBase
في ملف connect_connector.py
.
الملف الأخير موجود في قسم APPENDIX من هذا الدرس التطبيقي حول الترميز. وإذا لم يحدث ذلك، يمكنك إجراء التغييرات المناسبة يدويًا.
يمكنك أيضًا تجربة طلبات مختلفة للاطّلاع على الصيغة المحتملة لردود Duet AI.
يمكنك إعادة ضبط سجلّ محادثات Duet AI من خلال النقر على رمز المهملات في أعلى الشريط الجانبي في Duet AI.
جارٍ تحديث data_model.py
عليك استخدام المحرّك الذي أنشأته في الخطوة السابقة (في ملف connect_connector.py
) لإنشاء جدول في قاعدة بيانات CloudSQL.
محو سجلّ محادثات Duet AI افتح ملف data_model.py
. جرِّب الطلب التالي.
المطالبة 1: في الدالة الرئيسية، قم باستيراد واستخدام المحرك منconnect_connector.py
من المفترض أن يظهر لك الرد الذي يستورد engine
من connect_connector
(بالنسبة إلى CloudSQL). وتستخدم create_table
هذا المحرّك (بدلاً من قاعدة البيانات المحلية التلقائية sqlite
).
يجب تعديل ملف data_model.py
.
الملف الأخير موجود في قسم APPENDIX من هذا الدرس التطبيقي حول الترميز. وإذا لم يحدث ذلك، يمكنك إجراء التغييرات المناسبة يدويًا.
يمكنك أيضًا تجربة طلبات مختلفة للاطّلاع على ردود Duet AI المختلفة.
يمكنك إعادة ضبط سجلّ محادثات Duet AI من خلال النقر على رمز المهملات في أعلى الشريط الجانبي في Duet AI.
requirements.txt
أنشئ ملف requirements.txt
للتطبيق.
افتح كلاً من connect_connector.py
وملف data_model.py
وأدخِل الطلب التالي.
الطلب 1: إنشاء ملف متطلبات pip لنموذج البيانات والخدمة هذا
الطلب 2: إنشاء ملف متطلبات pip لنموذج البيانات هذا وهذه الخدمة باستخدام أحدث الإصدارات
تأكَّد من صحة الأسماء والنُسخ. على سبيل المثال، في الردّ أعلاه، اسم 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 من خلال النقر على رمز المهملات في أعلى الشريط الجانبي في 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
بعد إدخال كلمة المرور (التطوُّر أيضًا)، احصل على الجداول.
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
اكتب \q
للخروج من CloudSQL.
db_init.py
بعد ذلك، لنضيف بعض نماذج البيانات إلى جدول packages
.
محو سجلّ محادثات Duet AI بعد فتح ملف data_model.py
، جرِّب الطلبات التالية.
الطلب 1: إنشاء دالة تنشئ 10 نماذج لصفوف الحِزَم وتطبيقها في جدول الحِزم
المطالبة 2: باستخدام الجلسة منconnect_connector، إنشاء دالة تنشئ 10 صفوف لنماذج الحِزم وتطبيقها في جدول الحِزم
استخدام الرمز OPEN
في سير عمل جديد للملفات على النحو السابق. احفظ الرمز في ملف باسم
db_init.py
.
الملف الأخير موجود في قسم APPENDIX من هذا الدرس التطبيقي حول الترميز. وإذا لم يحدث ذلك، يمكنك إجراء التغييرات المناسبة يدويًا.
يمكنك أيضًا تجربة طلبات مختلفة للاطّلاع على ردود Duet AI المختلفة.
يمكنك إعادة ضبط سجلّ محادثات Duet AI من خلال النقر على رمز المهملات في أعلى الشريط الجانبي في 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)
اكتب \q
للخروج من CloudSQL.
main.py
أثناء فتح الملفات data_model.py
وpackage-service.yaml
وconnect_connector.py
، يمكنك إنشاء main.py
للتطبيق.
الطلب 1: استخدام مكتبة Python flask - إنشاء عملية تنفيذ تستخدم نقاط نهاية http في هذه الخدمة
المطالبة 2: باستخدام مكتبة بايثون الميزات - إنشاء تنفيذ يستخدم نقاط نهاية استراحة http لهذه الخدمة. استخدام أداة SessionMaker منconnect_conector.py إلى بيانات الحزم واستخدامها.
المطالبة 3: باستخدام مكتبة بايثون flask - إنشاء تنفيذ يستخدم نقاط نهاية استراحة http لهذه الخدمة. استخدام الحزمة من data_model.py وsessionMaker منconnect_conector.py إلى بيانات الحزم.
الطلب 4: باستخدام مكتبة بايثون flask - إنشاء تنفيذ يستخدم نقاط نهاية http في هذه الخدمة. استيراد واستخدام الحزمة من data_model.py وsessionMaker منconnect_conector.py إلى بيانات الحزم. استخدام عنوان IP المضيف 0.0.0.0 للتطبيق app.run
يُرجى تعديل متطلبات "main.py
".
طلب: إنشاء ملف متطلبات لنظام التشغيلMain.py
إلحاق هذا الإجراء بملف requirements.txt
. تأكد من استخدام الإصدار 3.0.0 من Flask.
استخدام الرمز OPEN
في سير عمل جديد للملفات على النحو السابق. احفظ الرمز في ملف باسم
main.py
.
الملف الأخير موجود في قسم APPENDIX من هذا الدرس التطبيقي حول الترميز. وإذا لم يحدث ذلك، يمكنك إجراء التغييرات المناسبة يدويًا.
يمكنك إعادة ضبط سجلّ محادثات Duet AI من خلال النقر على رمز المهملات في أعلى الشريط الجانبي في 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: إنشاء اختبارات الوحدات
استخدام الرمز OPEN
في سير عمل جديد للملفات على النحو السابق. احفظ الرمز في ملف باسم
test.py
.
في الدالة test_get_package
، يجب تحديد product_id
. يمكنك إضافته يدويًا.
الملف الأخير موجود في قسم APPENDIX من هذا الدرس التطبيقي حول الترميز. وإذا لم يحدث ذلك، يمكنك إجراء التغييرات المناسبة يدويًا.
يمكنك إعادة ضبط سجلّ محادثات Duet AI من خلال النقر على رمز المهملات في أعلى الشريط الجانبي في Duet AI.
جارٍ إجراء اختبارات الوحدة
أجرِ اختبار الوحدة.
python test.py
تشبه النتيجة ما يلي:
. ---------------------------------------------------------------------- Ran 1 test in 1.061s OK
أغلِق جميع الملفات في "محرِّر Cloud Shell" وامحُ سجلّ المحادثات من خلال النقر على رمز المهملات في شريط الحالة العلوي.
ملف شامل
إنشاء Dockerfile
لهذا التطبيق.
افتح main.py
وجرِّب الطلبات التالية.
الطلب 1: إنشاء ملف Dockerfile لهذا التطبيق
المطالبة 2: إنشاء ملف Dockerfile لهذا التطبيق. انسخ كل الملفات إلى الحاوية.
يجب أيضًا ضبط السمة ENVARS
لكل من INSTANCE_CONNECTION_NAME
وDB_USER
وDB_PASS
وDB_NAME
. يمكنك إجراء ذلك يدويًا. يجب أن يظهر الملف الشامل على النحو التالي:
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
في سير عمل جديد للملفات على النحو السابق. احفظ التعليمة البرمجية في ملف يسمى Dockerfile.
الملف الأخير موجود في قسم APPENDIX من هذا الدرس التطبيقي حول الترميز. وإذا لم يحدث ذلك، يمكنك إجراء التغييرات المناسبة يدويًا.
تشغيل التطبيق محليًا
مع فتح "Dockerfile
"، جرِّب الطلب التالي.
المطالبة 1: كيف أشغِّل حاوية على الجهاز باستخدام ملف Docker هذا
اتّبِع التعليمات.
# 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 Registry
أنشئ صورة الحاوية وانشرها إلى 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
تتوفّر حاوية التطبيق الآن على us-central1-docker.pkg.dev/${PROJECT_ID}/shipping/shipping
ويمكن نشرها على GKE.
6- نشر تطبيق في مجموعة GKE
تم إنشاء مجموعة GKE Autopilot عندما أنشأت موارد Google Cloud Platform لورشة العمل هذه. اتصِل بمجموعة أدوات 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
انتظِر إلى أن تعمل مجموعات الأجهزة اللوحية ويتم تخصيص عنوان 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 من حساب خدمة "cloudsqlsa
". يؤدي ذلك إلى حدوث خطأ أثناء الاتصال بقاعدة بيانات CloudSQL.
gcloud projects remove-iam-policy-binding ${PROJECT_ID} \ --member="serviceAccount:cloudsqlsa@${PROJECT_ID}.iam.gserviceaccount.com" \ --role="roles/cloudsql.client"
أعِد تشغيل مجموعة الشحن.
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 >. أعباء العمل
انقر على عملية نشر shipping
ثم على علامة التبويب السجلات.
انقر على رمز View in Log Explorer (مستكشف السجلّات) على يسار شريط الحالة. يؤدي ذلك إلى فتح نافذة مستكشف السجلّات جديدة.
انقر على أحد إدخالات الخطأ Traceback
، ثم انقر على شرح إدخال السجل هذا.
يمكنك قراءة شرح الخطأ.
بعد ذلك، لنطلب من Duet AI مساعدتك في تحديد الخطأ وحلّها.
جرِّب الطلب التالي.
المطالبة 1: مساعدتي في تحديد هذا الخطأ وحلّها
أدخِل رسالة الخطأ في الطلب.
الطلب 2: محظور: يبدو أن العنصر الرئيسي المُصدَّق عليه لإدارة الهوية وإمكانية الوصول غير مُصرَّح له بتقديم طلب من واجهة برمجة التطبيقات. إثبات صحة "واجهة برمجة تطبيقات المشرف في Cloud SQL" يتم تفعيلها ضمن مشروع Google Cloud Platform و"عميل Cloud SQL". منح الدور إلى المسؤول الرئيسي عن "إدارة الهوية وإمكانية الوصول"
وِبَعْدْ كِدَهْ.
الطلب 3: كيف يمكنني تعيين دور "عميل Cloud SQL" إلى حساب خدمة Google باستخدام gcloud؟
أسنِد دور "عميل Cloud SQL" إلى 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 AI بنجاح في تسجيل الدخول إلى السحابة الإلكترونية ومستكشف السجلّات وميزة شرح السجلّات لتحديد المشكلة وحلّها.
8. الخاتمة
تهانينا! لقد أكملت هذا الدرس التطبيقي حول الترميز بنجاح.
في هذا الدرس التطبيقي حول الترميز، تعلمت ما يلي:
- تفعيل Duet AI في مشروع Google Cloud Platform وإعداده للاستخدام في بيئة تطوير متكاملة (IDE) وCloud Console
- استخدام Duet AI لإنشاء الرموز البرمجية وإكمالها وشرحها
- يمكنك استخدام Duet AI لتوضيح مشكلة في التطبيق وحلّها.
- ميزات Duet AI، مثل المحادثة عبر بيئة تطوير متكاملة (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()
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
ملف شامل
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"]