1. วัตถุประสงค์
เวิร์กช็อปนี้มีจุดประสงค์เพื่อมอบการศึกษาเกี่ยวกับ Duet AI ในทางปฏิบัติแก่ผู้ใช้และผู้ประกอบวิชาชีพ
ในโค้ดแล็บนี้ คุณจะได้เรียนรู้สิ่งต่อไปนี้
- เปิดใช้งาน Duet AI ในโปรเจ็กต์ GCP และกำหนดค่าให้ใช้ใน IDE และ Cloud Console
- ใช้ Duet AI เพื่อสร้าง เติมให้สมบูรณ์ และอธิบายโค้ด
- ใช้ Duet AI เพื่ออธิบายและแก้ปัญหาแอปพลิเคชัน
- ฟีเจอร์ Duet AI เช่น แชท IDE และแชทแบบหลายรอบ แชทเทียบกับการสร้างโค้ดในบรรทัด การดำเนินการอัจฉริยะ เช่น คำอธิบายโค้ดและการรับทราบการท่องจำ และอื่นๆ
การบรรยาย
กิจกรรมในเวิร์กช็อปนี้จะเกิดขึ้นในบริบทที่เป็นเรื่องราวเพื่อแสดงให้เห็นว่า Duet AI สำหรับนักพัฒนาซอฟต์แวร์ถูกนำมาใช้ในการพัฒนาในแต่ละวันอย่างไร
นักพัฒนาแอปคนใหม่เข้าร่วมบริษัทอีคอมเมิร์ซ โดยมีหน้าที่เพิ่มบริการใหม่ลงในแอปพลิเคชันอีคอมเมิร์ซที่มีอยู่ (ซึ่งประกอบด้วยหลายบริการ) บริการใหม่นี้จะให้ข้อมูลเพิ่มเติม (ขนาด น้ำหนัก ฯลฯ) เกี่ยวกับผลิตภัณฑ์ในแคตตาล็อกผลิตภัณฑ์ บริการนี้จะช่วยให้คุณทราบค่าจัดส่งที่ถูกลง/ดีขึ้นตามขนาดและน้ำหนักของผลิตภัณฑ์
เนื่องจากนักพัฒนาซอฟต์แวร์เพิ่งเข้ามาทำงานในบริษัท จึงจะใช้ Duet AI เพื่อสร้าง อธิบาย และจัดทำเอกสารโค้ด
หลังจากเขียนโค้ดบริการแล้ว ผู้ดูแลระบบแพลตฟอร์มจะใช้ Duet AI (แชท) เพื่อช่วยสร้างอาร์ติแฟกต์ (คอนเทนเนอร์ Docker) และทรัพยากรที่จำเป็นในการติดตั้งใช้งานอาร์ติแฟกต์ใน GCP (เช่น Artifact Registry, สิทธิ์ IAM, ที่เก็บโค้ด, โครงสร้างพื้นฐานด้านการประมวลผล เช่น GKE หรือ Cloud Run เป็นต้น)
เมื่อแอปพลิเคชันได้รับการติดตั้งใช้งานใน GCP แล้ว ผู้ปฏิบัติงานแอปพลิเคชัน/SRE จะใช้ Duet AI (และ Cloud Ops) เพื่อช่วยแก้ปัญหาข้อผิดพลาดในบริการใหม่
ลักษณะตัวตน
เวิร์กช็อปนี้ครอบคลุมลักษณะตัวตนต่อไปนี้
- นักพัฒนาแอปพลิเคชัน - ต้องมีความรู้ด้านการเขียนโปรแกรมและการพัฒนาซอฟต์แวร์
การอบรมเชิงปฏิบัติการ Duet AI รูปแบบนี้มีไว้สำหรับนักพัฒนาแอปเท่านั้น ไม่จำเป็นต้องมีความรู้เกี่ยวกับทรัพยากรระบบคลาวด์ของ GCP ดูสคริปต์สำหรับวิธีสร้างทรัพยากร GCP ที่จำเป็นในการเรียกใช้แอปพลิเคชันนี้ได้ที่นี่ คุณสามารถทำตามวิธีการในคู่มือนี้เพื่อติดตั้งใช้งานทรัพยากร GCP ที่จำเป็น
2. การเตรียมสภาพแวดล้อม
การเปิดใช้งาน Duet AI
คุณเปิดใช้งาน Duet AI ในโปรเจ็กต์ GCP ได้ทั้งผ่าน API (gcloud หรือเครื่องมือ IaC เช่น Terraform) หรือผ่าน UI ของ Cloud Console
หากต้องการเปิดใช้งาน Duet AI ในโปรเจ็กต์ Google Cloud ให้เปิดใช้ Cloud AI Companion API และให้บทบาท Identity and Access Management (IAM) ของผู้ใช้ Cloud AI Companion และผู้มีสิทธิ์ดูการใช้งานบริการแก่ผู้ใช้
ผ่าน 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 และผู้ดูการใช้งานบริการ Identity and Access Management (IAM) ให้กับบัญชีผู้ใช้ Cloud Companion API อยู่เบื้องหลังฟีเจอร์ทั้งใน IDE และคอนโซลที่เราจะใช้ สิทธิ์ผู้ดูการใช้งานบริการใช้เพื่อตรวจสอบอย่างรวดเร็วก่อนเปิดใช้ UI ในคอนโซล (เพื่อให้ UI ของ Duet ปรากฏเฉพาะในโปรเจ็กต์ที่เปิดใช้ 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
เลือกโปรเจ็กต์ในเครื่องมือเลือกโปรเจ็กต์
คลิกเปิดใช้
หน้าเว็บจะอัปเดตและแสดงสถานะเป็นเปิดใช้ ตอนนี้ Duet AI พร้อมให้บริการในโปรเจ็กต์ Google Cloud ที่เลือกสำหรับผู้ใช้ทุกคนที่มีบทบาท IAM ที่จำเป็นแล้ว
หากต้องการให้บทบาท IAM ที่จำเป็นต่อการใช้ Duet AI ให้ไปที่หน้า IAM
ในคอลัมน์หลัก ให้ค้นหาผู้ใช้ที่คุณต้องการเปิดใช้สิทธิ์เข้าถึง Duet AI แล้วคลิกไอคอนดินสอ ✏️ แก้ไขหลักในแถวนั้น
ในแผงการเข้าถึงแก้ไข ให้คลิกเพิ่มเพิ่มบทบาทอื่น
ในส่วนเลือกบทบาท ให้เลือกผู้ใช้ Cloud AI Companion
คลิกเพิ่มบทบาทอื่น แล้วเลือกผู้ดูการใช้งานบริการ
คลิกบันทึก
การตั้งค่า IDE
นักพัฒนาแอปสามารถเลือก IDE ที่เหมาะกับความต้องการของตนมากที่สุดได้จากหลากหลายตัวเลือก ความช่วยเหลือด้านโค้ดของ Duet AI พร้อมให้บริการใน IDE หลายรายการ เช่น Visual Studio Code, IDE ของ JetBrains (IntelliJ, PyCharm, GoLand, WebStorm และอื่นๆ), Cloud Workstations, Cloud Shell Editor
ในแล็บนี้ คุณจะใช้ Cloud Workstations หรือ Cloud Shell Editor ก็ได้
เวิร์กช็อปนี้ใช้ Cloud Shell Editor
โปรดทราบว่า Cloud Workstations อาจใช้เวลา 20-30 นาทีในการตั้งค่า
หากต้องการใช้ทันที ให้ใช้โปรแกรมแก้ไข Cloud Shell
เปิด Cloud Shell Editor โดยคลิกไอคอนดินสอ ✏️ ในแถบเมนูด้านบนของ Cloud Shell
Cloud Shell Editor มี UI และ UX ที่คล้ายกับ VSCode มาก

คลิก CTRL (ใน Windows)/CMD (ใน Mac) + , (คอมมา) เพื่อเข้าสู่แผงการตั้งค่า
พิมพ์ "Duet AI" ในแถบค้นหา
ตรวจสอบหรือเปิดใช้ Cloudcode › Duet AI: เปิดใช้ และ Cloudcode › Duet AI › คำแนะนำในบรรทัด: เปิดใช้ Auto

คลิก Cloud Code - Sign In ในแถบสถานะด้านล่าง แล้วทำตามเวิร์กโฟลว์การลงชื่อเข้าใช้
หากคุณลงชื่อเข้าใช้อยู่แล้ว แถบสถานะจะแสดง Cloud Code - ไม่มีโปรเจ็กต์
คลิก Cloud Code - ไม่มีโปรเจ็กต์ แล้วแผงแบบเลื่อนลงของการดำเนินการจะปรากฏที่ด้านบน คลิกเลือกโปรเจ็กต์ Google Cloud

เริ่มพิมพ์รหัสโปรเจ็กต์ แล้วโปรเจ็กต์ควรจะปรากฏในรายการ

เลือก PROJECT_ID จากรายการโปรเจ็กต์
แถบสถานะด้านล่างจะอัปเดตเพื่อแสดงรหัสโปรเจ็กต์ หากไม่ปรากฏ คุณอาจต้องรีเฟรชแท็บ Cloud Shell Editor
คลิกไอคอน Duet AI
ในแถบเมนูด้านซ้าย แล้วหน้าต่างแชทของ Duet AI จะปรากฏขึ้น หากคุณได้รับข้อความที่ระบุว่า "เลือกโปรเจ็กต์ GCP" คลิกและเลือกโปรเจ็กต์อีกครั้ง
ตอนนี้คุณจะเห็นหน้าต่างแชทของ Duet AI

3. การตั้งค่าโครงสร้างพื้นฐาน

หากต้องการเรียกใช้บริการจัดส่งใหม่ใน GCP คุณต้องมีทรัพยากร GCP ต่อไปนี้
- อินสแตนซ์ Cloud SQL ที่มีฐานข้อมูล
- คลัสเตอร์ GKE เพื่อเรียกใช้บริการที่ทำงานในคอนเทนเนอร์
- Artifact Registry สำหรับจัดเก็บอิมเมจ Docker
- ที่เก็บของ Cloud Source สำหรับโค้ด
ในเทอร์มินัล 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. การพัฒนาบริการ Flask ของ Python

บริการที่เราจะสร้างประกอบด้วยไฟล์ต่อไปนี้ คุณไม่จำเป็นต้องสร้างไฟล์เหล่านี้ในตอนนี้ และจะสร้างไฟล์เหล่านี้ทีละไฟล์ตามวิธีการด้านล่าง
package-service.yaml- ข้อกำหนดของ Open API สำหรับบริการแพ็กเกจที่มีข้อมูล เช่น ความสูง ความกว้าง น้ำหนัก และวิธีการจัดการพิเศษdata_model.py- รูปแบบข้อมูลสำหรับข้อกำหนด API ของบริการแพ็กเกจ และสร้างตารางpackagesในฐานข้อมูล product_details ด้วยconnect_connector.py- การเชื่อมต่อ CloudSQL (กำหนดเครื่องมือ, เซสชัน และ ORM พื้นฐาน)db_init.py- สร้างข้อมูลตัวอย่างลงในตารางpackagesmain.py- บริการ Python Flask ที่มีปลายทางGETเพื่อดึงรายละเอียดแพ็กเกจจากข้อมูลpackagesตาม product_idtest.py- การทดสอบหน่วยrequirement.txt- ข้อกำหนดของ PythonDockerfile- หากต้องการสร้างคอนเทนเนอร์สำหรับแอปพลิเคชันนี้
หากพบปัญหาที่แก้ไขไม่ได้ในระหว่างแบบฝึกหัด ไฟล์สุดท้ายทั้งหมดจะอยู่ในภาคผนวกของ Codelab นี้เพื่อใช้อ้างอิง
ในขั้นตอนก่อนหน้า คุณได้สร้าง Cloud Source Repositories โคลนที่เก็บ คุณจะสร้างไฟล์แอปพลิเคชันในโฟลเดอร์ที่เก็บที่โคลน
ในเทอร์มินัล Cloud Shell ให้เรียกใช้คำสั่งต่อไปนี้เพื่อโคลนที่เก็บ
cd ~ gcloud source repos clone shipping shipping cd ~/shipping
เปิดแถบด้านข้างของแชท Duet AI จากเมนูด้านซ้ายของ Cloud Shell Editor ไอคอนมีลักษณะดังนี้
ตอนนี้คุณใช้ Duet AI เพื่อรับความช่วยเหลือด้านโค้ดได้แล้ว
package-service.yaml
โดยไม่ต้องเปิดไฟล์ใดๆ ให้ขอให้ Duet สร้างข้อกำหนดของ Open API สำหรับบริการจัดส่ง
พรอมต์ 1: สร้างข้อกำหนด OpenAPI yaml สำหรับบริการที่ให้ข้อมูลการจัดส่งและพัสดุภัณฑ์โดยระบุรหัสผลิตภัณฑ์ที่เป็นตัวเลข บริการควรมีข้อมูลเกี่ยวกับความสูง ความกว้าง ความลึก น้ำหนัก และวิธีการจัดการพิเศษของแพ็กเกจ

มี 3 ตัวเลือกที่แสดงที่ด้านขวาบนของหน้าต่างโค้ดที่สร้างขึ้น
คุณสามารถCOPY
โค้ดแล้ววางลงในไฟล์ได้
คุณสามารถ ADD
โค้ดไปยังไฟล์ที่เปิดอยู่ในเครื่องมือแก้ไขได้
หรือจะOPEN
โค้ดในไฟล์ใหม่ก็ได้
คลิก OPEN
รหัสในไฟล์ใหม่
คลิก CTRL/CMD + s เพื่อบันทึกไฟล์ และจัดเก็บไฟล์ไว้ในโฟลเดอร์แอปพลิเคชันโดยใช้ชื่อไฟล์ว่า package-service.yaml คลิก ตกลง

ไฟล์สุดท้ายอยู่ในส่วนภาคผนวกของ Codelab นี้ หากไม่ ให้ทำการเปลี่ยนแปลงที่เหมาะสมด้วยตนเอง
นอกจากนี้ คุณยังลองใช้พรอมต์ต่างๆ เพื่อดูคำตอบของ Duet AI ได้ด้วย
รีเซ็ตประวัติการแชทของ Duet AI โดยคลิกไอคอนถังขยะ
ที่ด้านบนของแถบด้านข้างของ Duet AI
data_model.py
จากนั้นสร้างไฟล์ Python โมเดลข้อมูลสำหรับบริการตามข้อกำหนด OpenAPI
เมื่อเปิดไฟล์ package-service.yaml แล้ว ให้ป้อนพรอมต์ต่อไปนี้
พรอมต์ 1: ใช้ ORM ของ SQLAlchemy ใน Python เพื่อสร้างโมเดลข้อมูลสำหรับบริการ API นี้ รวมถึงฟังก์ชันแยกต่างหากและจุดแรกเข้าหลักที่สร้างตารางฐานข้อมูลด้วย

มาดูแต่ละส่วนที่สร้างขึ้นกัน 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 เล็กน้อยได้โดยการเพิ่มรายละเอียดลงในแชทเธรดเดียวกัน
มาใช้พรอมต์อื่นกัน
พรอมต์ 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: สร้างคลาส Engine, Sessionmaker และ Base ORM โดยใช้เมธอด connect_with_connector

คำตอบอาจต่อท้าย engine, Session และ Base ไปยังไฟล์ connect_connector.py
ไฟล์สุดท้ายอยู่ในส่วนภาคผนวกของ Codelab นี้ หากไม่ ให้ทำการเปลี่ยนแปลงที่เหมาะสมด้วยตนเอง
นอกจากนี้ คุณยังลองใช้พรอมต์ต่างๆ เพื่อดูคำตอบที่ 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 DB ในเครื่องเริ่มต้น)
อัปเดตไฟล์ data_model.py
ไฟล์สุดท้ายอยู่ในส่วนภาคผนวกของ Codelab นี้ หากไม่ ให้ทำการเปลี่ยนแปลงที่เหมาะสมด้วยตนเอง
นอกจากนี้ คุณยังลองใช้พรอมต์ต่างๆ เพื่อดูคำตอบที่หลากหลายของ 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.
เชื่อมต่อกับอินสแตนซ์ Cloud SQL และตรวจสอบว่าได้สร้างฐานข้อมูลแล้ว
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
พิมพ์ \q เพื่อออกจาก Cloud SQL
db_init.py
ต่อไป มาเพิ่มข้อมูลตัวอย่างลงในpackagesกัน
ล้างประวัติการแชทกับ Duet AI เมื่อเปิดไฟล์ data_model.py แล้ว ให้ลองใช้พรอมต์ต่อไปนี้
พรอมต์ 1: สร้างฟังก์ชันที่สร้างแถวแพ็กเกจตัวอย่าง 10 แถวและส่งไปยังตารางแพ็กเกจ
พรอมต์ 2: ใช้เซสชันจาก connect_connector สร้างฟังก์ชันที่สร้างแถวแพ็กเกจตัวอย่าง 10 แถวและส่งไปยังตารางแพ็กเกจ

ใช้ OPEN
รหัสในเวิร์กโฟลว์ไฟล์ใหม่เช่นเดิม บันทึกโค้ดในไฟล์ชื่อ db_init.py
ไฟล์สุดท้ายอยู่ในส่วนภาคผนวกของ Codelab นี้ หากไม่ ให้ทำการเปลี่ยนแปลงที่เหมาะสมด้วยตนเอง
นอกจากนี้ คุณยังลองใช้พรอมต์ต่างๆ เพื่อดูคำตอบที่หลากหลายของ Duet AI ได้ด้วย
รีเซ็ตประวัติการแชทของ Duet AI โดยคลิกไอคอนถังขยะ
ที่ด้านบนของแถบด้านข้างของ Duet AI
การสร้างข้อมูลแพ็กเกจตัวอย่าง
เรียกใช้ db_init.py จากบรรทัดคำสั่ง
python db_init.py
เอาต์พุตจะคล้ายกับตัวอย่างต่อไปนี้
Packages created successfully.
เชื่อมต่อกับอินสแตนซ์ CloudSQL อีกครั้งและตรวจสอบว่าได้เพิ่มข้อมูลตัวอย่างลงในตารางแพ็กเกจแล้ว
เชื่อมต่อกับอินสแตนซ์ Cloud SQL และตรวจสอบว่าได้สร้างฐานข้อมูลแล้ว
gcloud sql connect ${INSTANCE_NAME} --user=evolution --database=product_details
หลังจากป้อนรหัสผ่าน (หรือ evolution) แล้ว ให้รับข้อมูลทั้งหมดจากตารางแพ็กเกจ
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 เพื่อออกจาก Cloud SQL
main.py
เมื่อเปิดไฟล์ data_model.py, package-service.yaml และ connect_connector.py แล้ว ให้สร้าง main.py สำหรับแอปพลิเคชัน
พรอมต์ 1: ใช้ไลบรารี Flask ของ Python - สร้างการติดตั้งใช้งานที่ใช้ปลายทาง REST ของ HTTP สำหรับบริการนี้
พรอมต์ 2: ใช้ไลบรารี Flask ของ Python - สร้างการติดตั้งใช้งานที่ใช้ปลายทาง REST ของ HTTP สำหรับบริการนี้ นำเข้าและใช้ SessionMaker จาก connect_conector.py สำหรับข้อมูลแพ็กเกจ
พรอมต์ 3: ใช้ไลบรารี Python Flask - สร้างการติดตั้งใช้งานที่ใช้ปลายทาง REST ของ HTTP สำหรับบริการนี้ นำเข้าและใช้แพ็กเกจจาก data_model.py และ SessionMaker จาก connect_conector.py สำหรับข้อมูลแพ็กเกจ
พรอมต์ 4: การใช้ไลบรารี Flask ของ Python - สร้างการติดตั้งใช้งานที่ใช้ปลายทาง REST ของ HTTP สำหรับบริการนี้ นำเข้าและใช้แพ็กเกจจาก data_model.py และ SessionMaker จาก connect_conector.py สำหรับข้อมูลแพ็กเกจ ใช้ IP โฮสต์ 0.0.0.0 สำหรับ app.run

อัปเดตข้อกำหนดสำหรับ main.py
พรอมต์: สร้างไฟล์ข้อกำหนดสำหรับ main.py

เพิ่มข้อความนี้ลงในไฟล์ requirements.txt ตรวจสอบว่าใช้ Flask เวอร์ชัน 3.0.0
ใช้ OPEN
รหัสในเวิร์กโฟลว์ไฟล์ใหม่เช่นเดิม บันทึกโค้ดในไฟล์ชื่อ main.py
ไฟล์สุดท้ายอยู่ในส่วนภาคผนวกของ Codelab นี้ หากไม่ ให้ทำการเปลี่ยนแปลงที่เหมาะสมด้วยตนเอง
รีเซ็ตประวัติการแชทของ 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
จากเทอร์มินัลที่ 2 ให้ทดสอบปลายทาง /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 ที่กำลังทำงานในเทอร์มินัล
การสร้างการทดสอบ 1 หน่วย
เมื่อไฟล์ main.py เปิดอยู่ ให้สร้าง Unit Test
พรอมต์ 1: สร้างการทดสอบหน่วย

ใช้ OPEN
รหัสในเวิร์กโฟลว์ไฟล์ใหม่เช่นเดิม บันทึกโค้ดในไฟล์ชื่อ test.py
ในฟังก์ชัน test_get_package ต้องกำหนด product_id คุณเพิ่มด้วยตนเองได้
ไฟล์สุดท้ายอยู่ในส่วนภาคผนวกของ Codelab นี้ หากไม่ ให้ทำการเปลี่ยนแปลงที่เหมาะสมด้วยตนเอง
รีเซ็ตประวัติการแชทของ Duet AI โดยคลิกไอคอนถังขยะ
ที่ด้านบนของแถบด้านข้างของ Duet AI
การเรียกใช้การทดสอบหน่วย
เรียกใช้การทดสอบหน่วย
python test.py
เอาต์พุตจะคล้ายกับตัวอย่างต่อไปนี้
. ---------------------------------------------------------------------- Ran 1 test in 1.061s OK
ปิดไฟล์ทั้งหมดใน Cloud Shell Editor และล้างประวัติการแชทโดยคลิกไอคอนถังขยะ
ในแถบสถานะด้านบน
Dockerfile
สร้าง Dockerfile สำหรับแอปพลิเคชันนี้
เปิด main.py แล้วลองใช้พรอมต์ต่อไปนี้
พรอมต์ 1: สร้าง Dockerfile สำหรับแอปพลิเคชันนี้
พรอมต์ 2: สร้าง Dockerfile สำหรับแอปพลิเคชันนี้ คัดลอกไฟล์ทั้งหมดไปยังคอนเทนเนอร์

นอกจากนี้ คุณยังต้องตั้งค่า 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
รหัสในเวิร์กโฟลว์ไฟล์ใหม่เช่นเดิม บันทึกโค้ดในไฟล์ชื่อ Dockerfile
ไฟล์สุดท้ายอยู่ในส่วนภาคผนวกของ Codelab นี้ หากไม่ ให้ทำการเปลี่ยนแปลงที่เหมาะสมด้วยตนเอง
การเรียกใช้แอปพลิเคชันในเครื่อง
เมื่อDockerfileเปิดอยู่ ให้ลองใช้พรอมต์ต่อไปนี้
พรอมต์ 1: ฉันจะเรียกใช้คอนเทนเนอร์ในเครื่องโดยใช้ Dockerfile นี้ได้อย่างไร

ทำตามวิธีการ
# 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
เข้าถึงคอนเทนเนอร์จากหน้าต่างเทอร์มินัลที่ 2
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 เมื่อคุณสร้างทรัพยากร GCP สำหรับเวิร์กช็อปนี้ เชื่อมต่อกับคลัสเตอร์ 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. คะแนนพิเศษ: การแก้ปัญหาแอปพลิเคชัน
นำบทบาท IAM ของไคลเอ็นต์ Cloud SQL ออกจาก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การติดตั้งใช้งาน แล้วคลิกแท็บบันทึก

คลิกไอคอนดูใน Log Explorer
ที่ด้านขวาของแถบสถานะ ซึ่งจะเป็นการเปิดหน้าต่างเครื่องมือสำรวจบันทึกใหม่

คลิกรายการข้อผิดพลาดรายการใดรายการหนึ่ง Traceback แล้วคลิกอธิบายรายการบันทึกนี้

คุณสามารถอ่านคำอธิบายของข้อผิดพลาดได้
จากนั้นมาดูวิธีให้ Duet AI ช่วยแก้ปัญหาข้อผิดพลาดกัน
ลองใช้พรอมต์ต่อไปนี้
พรอมต์ 1: ช่วยฉันแก้ปัญหาข้อผิดพลาดนี้

ป้อนข้อความแสดงข้อผิดพลาดในพรอมต์
พรอมต์ 2: Forbidden: ดูเหมือนว่า Principal ของ IAM ที่ได้รับการตรวจสอบสิทธิ์จะไม่มีสิทธิ์ส่งคำขอ API ตรวจสอบว่าได้เปิดใช้ "Cloud SQL Admin API" ในโปรเจ็กต์ GCP และได้มอบบทบาท "ไคลเอ็นต์ Cloud SQL" ให้กับหลักการ IAM แล้ว

จากนั้น
พรอมต์ 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 ใน Cloud Logging, Log Explorer และฟีเจอร์ Log Explainer เพื่อแก้ปัญหาเรียบร้อยแล้ว
8. บทสรุป
ยินดีด้วย คุณทำ Codelab นี้เสร็จเรียบร้อยแล้ว
ในโค้ดแล็บนี้ คุณได้เรียนรู้สิ่งต่อไปนี้
- เปิดใช้งาน Duet AI ในโปรเจ็กต์ GCP และกำหนดค่าให้ใช้ใน 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
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"]