1. Mục tiêu
Mục đích của hội thảo này là nhằm phổ biến kiến thức thực tế về Duet AI cho người dùng và chuyên viên.
Trong lớp học lập trình này, bạn sẽ tìm hiểu các nội dung sau:
- Kích hoạt Duet AI trong dự án GCP và định cấu hình để sử dụng trong IDE và Cloud Console.
- Sử dụng Duet AI để tạo, hoàn thành và giải thích mã.
- Sử dụng Duet AI để giải thích và khắc phục sự cố về ứng dụng.
- Các tính năng của Duet AI như trò chuyện IDE và trò chuyện nhiều lượt, trò chuyện so với tạo mã cùng dòng, các thao tác thông minh như giải thích mã và xác nhận trích dẫn cùng nhiều tính năng khác.
Narrative
Để chứng minh cách Duet AI cho Nhà phát triển được áp dụng đúng cách trong hoạt động phát triển hằng ngày, các hoạt động của hội thảo này diễn ra theo bối cảnh nhiều câu chuyện.
Một nhà phát triển mới gia nhập một công ty thương mại điện tử. Họ có nhiệm vụ thêm dịch vụ mới vào ứng dụng thương mại điện tử hiện có (bao gồm nhiều dịch vụ). Dịch vụ mới cung cấp thêm thông tin (kích thước, trọng lượng, v.v.) về các sản phẩm trong danh mục sản phẩm. Dịch vụ này sẽ giúp bạn cải thiện chi phí vận chuyển dựa trên kích thước và trọng lượng sản phẩm.
Vì nhà phát triển mới tham gia công ty, nên họ sẽ sử dụng Duet AI để tạo mã, nội dung giải thích và tài liệu.
Sau khi dịch vụ được mã hoá, một quản trị viên nền tảng sẽ sử dụng Duet AI (trò chuyện) để giúp tạo cấu phần phần mềm (vùng chứa Docker) và các tài nguyên cần thiết để triển khai cấu phần phần mềm cho GCP (ví dụ: Artifact Registry, quyền IAM, kho lưu trữ mã, cơ sở hạ tầng điện toán như GKE hoặc CloudRun, v.v.)
Sau khi ứng dụng được triển khai cho GCP, một nhà điều hành ứng dụng/SRE sẽ sử dụng Duet AI (và Cloud Ops) để giúp khắc phục lỗi trong dịch vụ mới.
Đối tượng sử dụng
Hội thảo bao gồm các đối tượng sau:
- Nhà phát triển ứng dụng – Cần có một số kiến thức về lập trình và phát triển phần mềm.
Phiên bản hội thảo này của Duet AI chỉ dành cho nhà phát triển. Bạn không cần phải có kiến thức về tài nguyên trên đám mây của GCP. Bạn có thể tìm thấy các tập lệnh về cách tạo các tài nguyên GCP cần thiết để chạy ứng dụng này tại đây. Bạn có thể làm theo các bước trong hướng dẫn này để triển khai các tài nguyên GCP bắt buộc.
2. Chuẩn bị môi trường
Kích hoạt Duet AI
Bạn có thể kích hoạt Duet AI trong một dự án GCP thông qua API (các công cụ gcloud hoặc IaC như Terraform) hoặc thông qua giao diện người dùng của Cloud Console.
Để kích hoạt Duet AI trong một dự án trên Google Cloud, bạn cần bật Cloud AI Companion API và cấp cho người dùng vai trò Quản lý danh tính và quyền truy cập (IAM) của người dùng Cloud AI Companion cũng như vai trò Quản lý danh tính và quyền truy cập (IAM) của người xem theo mức sử dụng dịch vụ.
Qua gcloud
Kích hoạt Cloud Shell:
Định cấu hình PROJECT_ID
, USER
và bật 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}
Kết quả đầu ra sẽ có dạng như sau:
Updated property [core/project]. Operation "operations/acat.p2-60565640195-f37dc7fe-b093-4451-9b12-934649e2a435" finished successfully.
Cấp cho Người dùng Cloud AI Companion và vai trò Quản lý danh tính và quyền truy cập (IAM) của người xem mức sử dụng dịch vụ cho tài khoản NGƯỜI DÙNG. Cloud Companion API bao gồm các tính năng trong cả IDE và bảng điều khiển mà chúng ta sẽ sử dụng. Quyền Trình xem mức sử dụng dịch vụ được dùng để kiểm tra nhanh trước khi bật giao diện người dùng trong bảng điều khiển (để giao diện người dùng Duet chỉ xuất hiện trong các dự án có bật 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
Kết quả đầu ra sẽ có dạng như sau:
... - members: - user:<YOUR USER ACCOUNT> role: roles/cloudaicompanion.user ... - members: - user:<YOUR USER ACCOUNT> role: roles/serviceusage.serviceUsageViewer
Thông qua Cloud Console
Để bật API này, hãy truy cập vào trang Cloud AI Companion API trong bảng điều khiển Google Cloud.
Trong bộ chọn dự án, hãy chọn một dự án.
Nhấp vào Bật.
Trang sẽ cập nhật và hiển thị trạng thái Đã bật. Duet AI hiện đã có trong một dự án được chọn trên Google Cloud cho tất cả người dùng có vai trò quản lý danh tính và quyền truy cập (IAM) bắt buộc.
Để cấp các vai trò IAM bắt buộc để sử dụng Duet AI, hãy chuyển đến trang IAM.
Trong cột Chính, hãy tìm NGƯỜI DÙNG mà bạn muốn bật quyền truy cập vào Duet AI, sau đó nhấp vào biểu tượng bút chì ✏️ Chỉnh sửa đối tượng chính trong hàng đó.
Trong ngăn quyền truy cập Chỉnh sửa, hãy nhấp vào nút thêm Thêm vai trò khác.
Trong phần Chọn vai trò, hãy chọn Người dùng đồng hành Cloud AI.
Nhấp vào Add another role (Thêm vai trò khác) rồi chọn Service Usage Inspector (Người xem cách sử dụng dịch vụ).
Nhấp vào Lưu.
Thiết lập IDE
Nhà phát triển có thể chọn trong số nhiều IDE phù hợp nhất với nhu cầu của mình. Tính năng hỗ trợ lập trình Duet AI hiện có trong nhiều IDE như Visual Studio Code, JetBrains IDE (IntelliJ, PyCharm, GoLand, WebStorm, v.v.), Cloud Workstations, Cloud Shell Editor.
Trong phòng thí nghiệm này, bạn có thể sử dụng Cloud Workstations hoặc Cloud Shell Editor.
Hội thảo này sử dụng Cloud Shell Editor.
Lưu ý rằng các máy trạm trên đám mây có thể mất 20-30 phút để thiết lập.
Để sử dụng ngay lập tức, hãy dùng Cloud Shell Editor.
Mở Cloud Shell Editor bằng cách nhấp vào biểu tượng bút chì ✏️ trong thanh trình đơn trên cùng của Cloud Shell.
Cloud Shell Editor có giao diện người dùng và trải nghiệm người dùng rất giống với VSCode.
Nhấp vào Ctrl (trong Windows)/CMD (trong Mac) + , (dấu phẩy) để vào ngăn Cài đặt.
Trên thanh Tìm kiếm, hãy nhập "Duet ai".
Đảm bảo hoặc bật Cloudcode › Duet AI: Bật và Cloudcode › Duet AI › Đề xuất cùng dòng: Bật Auto
Trong Thanh trạng thái ở dưới cùng, hãy nhấp vào Mã đám mây – Đăng nhập và làm theo quy trình đăng nhập.
Nếu bạn đã đăng nhập, thanh trạng thái sẽ hiển thị Mã đám mây – Không có dự án.
Nhấp vào Cloud Code – Không có dự án nào và một ngăn thả xuống gồm các thao tác sẽ xuất hiện ở trên cùng. Nhấp vào Chọn một dự án Google Cloud.
Bắt đầu nhập mã DỰ ÁN và dự án của bạn sẽ xuất hiện trong danh sách.
Chọn PROJECT_ID của bạn trong danh sách dự án.
Thanh trạng thái ở dưới cùng sẽ cập nhật để hiển thị mã dự án của bạn. Nếu không thì bạn có thể phải làm mới thẻ Cloud Shell Editor.
Nhấp vào biểu tượng Duet AI trong thanh trình đơn bên trái và cửa sổ trò chuyện của Duet AI sẽ xuất hiện. Nếu bạn thấy thông báo có nội dung Chọn dự án GCP. Nhấp và chọn lại dự án.
Giờ đây, bạn sẽ thấy cửa sổ trò chuyện của Duet AI
3. Thiết lập cơ sở hạ tầng
Để chạy dịch vụ vận chuyển mới trong GCP, bạn cần có các tài nguyên sau đây trên GCP:
- Một thực thể Cloud SQL, có một cơ sở dữ liệu.
- Một cụm GKE để chạy dịch vụ trong vùng chứa.
- Một Artifact Registry để lưu trữ hình ảnh Docker.
- Kho lưu trữ nguồn trên đám mây cho mã.
Trong cửa sổ dòng lệnh Cloud Shell, hãy sao chép kho lưu trữ sau đây rồi chạy các lệnh sau để thiết lập cơ sở hạ tầng trong dự án GCP của bạn.
# Set your project export PROJECT_ID=<INSERT_YOUR_PROJECT_ID> gcloud config set core/project ${PROJECT_ID} # Enable Cloudbuild and grant Cloudbuild SA owner role export PROJECT_NUMBER=$(gcloud projects describe ${PROJECT_ID} --format 'value(projectNumber)') gcloud services enable cloudbuild.googleapis.com gcloud projects add-iam-policy-binding ${PROJECT_ID} --member serviceAccount:${PROJECT_NUMBER}@cloudbuild.gserviceaccount.com --role roles/owner # Clone the repo git clone https://github.com/duetailabs/dev.git ~/duetaidev cd ~/duetaidev # Run Cloudbuild to create the necessary resources gcloud builds submit --substitutions=_PROJECT_ID=${PROJECT_ID} # To destroy all GCP resources, run the following # gcloud builds submit --substitutions=_PROJECT_ID=${PROJECT_ID} --config=cloudbuild_destroy.yaml
4. Phát triển dịch vụ python Flask
Dịch vụ mà chúng ta sẽ tạo cuối cùng sẽ bao gồm các tệp sau đây. Bạn không cần phải tạo các tệp này ngay bây giờ và sẽ tạo từng tệp một theo hướng dẫn bên dưới:
package-service.yaml
– Thông số API mở cho dịch vụ gói có dữ liệu như chiều cao, chiều rộng, trọng lượng và hướng dẫn xử lý đặc biệt.data_model.py
– Mô hình dữ liệu cho quy cách API dịch vụ gói. Đồng thời, tạo bảngpackages
trong DB product_details.connect_connector.py
– Kết nối CloudSQL (xác định công cụ, Phiên và ORM cơ sở)db_init.py
– Tạo dữ liệu mẫu vào bảngpackages
.main.py
– Dịch vụ Python Flask có điểm cuốiGET
để truy xuất thông tin chi tiết về gói từ dữ liệupackages
dựa trên product_id.test.py
– Kiểm thử đơn vịrequirement.txt
– Các yêu cầu về PythonDockerfile
– Để chứa ứng dụng này
Nếu bạn gặp bất kỳ vấn đề cố định nào trong khi làm bài tập, các tệp cuối cùng đều nằm trong APPENDIX của lớp học lập trình này để tham khảo.
Ở bước trước, bạn đã tạo một Kho lưu trữ nguồn đám mây. Sao chép kho lưu trữ. Bạn sẽ tạo các tệp ứng dụng trong thư mục kho lưu trữ được sao chép.
Trong cửa sổ dòng lệnh của Cloud Shell, hãy chạy lệnh sau để sao chép kho lưu trữ.
cd ~ gcloud source repos clone shipping shipping cd ~/shipping
Mở thanh bên trò chuyện của Duet AI trong trình đơn bên trái của Cloud Shell Editor. Biểu tượng này có dạng . Giờ đây, bạn có thể sử dụng Duet AI để hỗ trợ viết mã.
package-service.yaml
Khi không mở tệp nào, hãy yêu cầu Duet tạo thông số API Mở cho dịch vụ vận chuyển.
Câu lệnh 1: Tạo thông số kỹ thuật yaml OpenAPI cho dịch vụ cung cấp thông tin vận chuyển và gói hàng dựa trên mã sản phẩm dạng số. Dịch vụ phải bao gồm thông tin về chiều cao, chiều rộng, chiều sâu, trọng lượng của gói hàng và mọi hướng dẫn xử lý đặc biệt.
Có ba tuỳ chọn được liệt kê ở trên cùng bên phải của cửa sổ mã đã tạo.
Bạn có thể COPY
mã và DÁN mã vào tệp.
Bạn có thể ADD
mã vào tệp hiện đang mở trong Trình chỉnh sửa.
Hoặc bạn có thể OPEN
mã trong một tệp mới.
Nhấp vào OPEN
mã trong tệp mới.
Nhấp vào CTRL/CMD + s
để lưu tệp rồi lưu trữ tệp đó trong thư mục ứng dụng bằng tên tệp có tên là package-service.yaml
. Nhấp vào OK.
Tệp cuối cùng nằm trong phần PHỤ LỤC của lớp học lập trình này. Nếu không, hãy thực hiện các thay đổi thích hợp theo cách thủ công.
Bạn cũng có thể thử nhiều câu lệnh để xem câu trả lời của Duet AI.
Đặt lại nhật ký trò chuyện trên Duet AI bằng cách nhấp vào biểu tượng thùng rác ở đầu thanh bên của Duet AI.
data_model.py
Tiếp theo, bạn tạo tệp python mô hình dữ liệu cho dịch vụ dựa trên thông số kỹ thuật OpenAPI.
Khi tệp package-service.yaml
đang mở, hãy nhập lời nhắc sau.
Câu lệnh 1: Sử dụng ORM sqlalchemy của python để tạo một mô hình dữ liệu cho dịch vụ API này. Ngoài ra, hãy thêm một hàm riêng biệt và một điểm truy cập chính để tạo bảng cơ sở dữ liệu.
Hãy cùng xem từng phần đã được tạo ra. Duet AI vẫn là một trợ lý và mặc dù có thể giúp bạn nhanh chóng viết mã, nhưng bạn vẫn nên xem xét nội dung được tạo và hiểu nội dung đó trong quá trình thực hiện.
Đầu tiên, có một lớp Class (Lớp) tên là Package
thuộc loại kiểu Base
xác định mô hình dữ liệu cho cơ sở dữ liệu packages
như sau:
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))
Tiếp theo, bạn cần một hàm tạo bảng trong cơ sở dữ liệu như sau:
def create_tables(engine):
Base.metadata.create_all(engine)
Cuối cùng, bạn cần một hàm chính chạy hàm create_tables
để thực sự tạo bảng trong cơ sở dữ liệu CloudSQL, như sau:
if __name__ == '__main__':
from sqlalchemy import create_engine
engine = create_engine('sqlite:///shipping.db')
create_tables(engine)
print('Tables created successfully.')
Xin lưu ý rằng hàm main
đang tạo một công cụ bằng cách sử dụng cơ sở dữ liệu sqlite
cục bộ. Để sử dụng CloudSQL, bạn sẽ cần phải thay đổi dịch vụ đó. Bạn sẽ thực hiện việc đó muộn hơn một chút.
Sử dụng mã OPEN
trong quy trình công việc mới của tệp như trước đây. Lưu mã này vào tệp có tên là
data_model.py
(lưu ý rằng dấu gạch dưới trong tên chứ không phải dấu gạch ngang).
Đặt lại nhật ký trò chuyện trên Duet AI bằng cách nhấp vào biểu tượng thùng rác ở đầu thanh bên của Duet AI.
connect-connector.py
Tạo trình kết nối CloudSQL.
Khi tệp data_model.py
đang mở, hãy nhập các câu lệnh sau.
Câu lệnh 1: Sử dụng thư viện Cloud-sql-python-connector, tạo một hàm Khởi chạy nhóm kết nối cho một thực thể Cloud SQL của Postgres.
Xin lưu ý rằng phản hồi này không sử dụng thư viện cloud-sql-python-connector
. Bạn có thể tinh chỉnh câu lệnh để Duet có đôi chút gợi ý, bằng cách thêm thông tin cụ thể vào cùng một chuỗi trò chuyện.
Hãy sử dụng một câu lệnh khác.
Câu lệnh 2: Phải sử dụng thư viện Cloud-sql-python-connector.
Hãy đảm bảo tệp này sử dụng thư viện cloud-sql-python-connector
.
Sử dụng mã OPEN
trong quy trình công việc mới của tệp như trước đây. Lưu mã trong tệp có tên
connect_conector.py
. Có thể bạn sẽ phải nhập thư viện pg8000
theo cách thủ công, vui lòng xem tệp bên dưới.
Xoá nhật ký trò chuyện của Duet AI và khi tệp connect_connector.py
đang mở, hãy tạo ORM DB engine
, sessionmaker
và base
để dùng trong ứng dụng.
Lời nhắc 1: Tạo một công cụ, lớp sessionmaker và ORM cơ sở bằng phương thức connect_with_connector
Phản hồi có thể thêm engine
, Session
và Base
vào tệp connect_connector.py
.
Tệp cuối cùng nằm trong phần PHỤ LỤC của lớp học lập trình này. Nếu không, hãy thực hiện các thay đổi thích hợp theo cách thủ công.
Bạn cũng có thể thử nhiều câu lệnh để xem câu trả lời mà Duet AI có thể đưa ra.
Đặt lại nhật ký trò chuyện trên Duet AI bằng cách nhấp vào biểu tượng thùng rác ở đầu thanh bên của Duet AI.
Đang cập nhật data_model.py
Bạn cần sử dụng công cụ mà bạn đã tạo ở bước trước (trong tệp connect_connector.py
) để tạo bảng trong cơ sở dữ liệu CloudSQL.
Xoá nhật ký trò chuyện trên Duet AI. Mở tệp data_model.py
. Hãy thử câu lệnh sau.
Câu lệnh 1: Trong hàm chính, hãy nhập và sử dụng công cụ từ connect_connector.py
Bạn sẽ thấy phản hồi nhập engine
từ connect_connector
(đối với CloudSQL). create_table
sử dụng công cụ đó (thay vì DB mặc định sqlite
cục bộ).
Cập nhật tệp data_model.py
.
Tệp cuối cùng nằm trong phần PHỤ LỤC của lớp học lập trình này. Nếu không, hãy thực hiện các thay đổi thích hợp theo cách thủ công.
Bạn cũng có thể thử nhiều câu lệnh để xem nhiều câu trả lời của Duet AI.
Đặt lại nhật ký trò chuyện trên Duet AI bằng cách nhấp vào biểu tượng thùng rác ở đầu thanh bên của Duet AI.
requirements.txt
Tạo một tệp requirements.txt
cho ứng dụng.
Mở cả tệp connect_connector.py
và data_model.py
rồi nhập lời nhắc sau đây.
Câu lệnh 1: Tạo tệp yêu cầu pip cho mô hình dữ liệu và dịch vụ này
Câu lệnh 2: Tạo tệp yêu cầu về pip cho mô hình dữ liệu và dịch vụ này bằng các phiên bản mới nhất
Xác minh tên và phiên bản là chính xác. Ví dụ: trong phản hồi ở trên, cả tên và phiên bản google-cloud-sql-connecter
đều không chính xác. Sửa các phiên bản theo cách thủ công và tạo một tệp requirements.txt
có dạng như sau:
cloud-sql-python-connector==1.2.4
sqlalchemy==1.4.36
pg8000==1.22.0
Trong cửa sổ dòng lệnh, hãy chạy lệnh sau:
pip3 install -r requirements.txt
Đặt lại nhật ký trò chuyện trên Duet AI bằng cách nhấp vào biểu tượng thùng rác ở đầu thanh bên của Duet AI.
Tạo bảng gói trong CloudSQL
Đặt các biến môi trường cho trình kết nối cơ sở dữ liệu 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
Bây giờ, hãy chạy data_model.py.
python data_model.py
Kết quả tương tự như sau (kiểm tra mã để xem điều gì thực sự được mong đợi):
Tables created successfully.
Kết nối với thực thể CloudSQL và kiểm tra xem cơ sở dữ liệu đã được tạo hay chưa.
gcloud sql connect ${INSTANCE_NAME} --user=evolution --database=product_details
Sau khi nhập mật khẩu (cũng là tiến hoá), lấy bảng.
product_details=> \dt
Kết quả sẽ tương tự như sau:
List of relations Schema | Name | Type | Owner --------+----------+-------+----------- public | packages | table | evolution (1 row)
Bạn cũng có thể kiểm tra mô hình dữ liệu và thông tin chi tiết về bảng.
product_details=> \d+ packages
Kết quả sẽ tương tự như sau:
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
Nhập \q
để thoát khỏi CloudSQL.
db_init.py
Tiếp theo, hãy thêm một số dữ liệu mẫu vào bảng packages
.
Xoá nhật ký trò chuyện trên Duet AI. Khi tệp data_model.py
đang mở, hãy thử các lời nhắc sau.
Lời nhắc 1: Tạo một hàm tạo 10 hàng gói mẫu rồi cam kết chúng vào bảng gói
Lời nhắc 2: Sử dụng phiên từ connect_connector, tạo một hàm tạo 10 hàng gói mẫu và cam kết chúng vào bảng gói
Sử dụng mã OPEN
trong quy trình công việc mới của tệp như trước đây. Lưu mã trong tệp có tên
db_init.py
.
Tệp cuối cùng nằm trong phần PHỤ LỤC của lớp học lập trình này. Nếu không, hãy thực hiện các thay đổi thích hợp theo cách thủ công.
Bạn cũng có thể thử nhiều câu lệnh để xem nhiều câu trả lời của Duet AI.
Đặt lại nhật ký trò chuyện trên Duet AI bằng cách nhấp vào biểu tượng thùng rác ở đầu thanh bên của Duet AI.
Tạo dữ liệu gói mẫu
Chạy db_init.py
từ dòng lệnh.
python db_init.py
Kết quả sẽ tương tự như sau:
Packages created successfully.
Kết nối lại với thực thể CloudSQL và xác minh rằng dữ liệu mẫu đã được thêm vào bảng gói.
Kết nối với thực thể CloudSQL và kiểm tra xem cơ sở dữ liệu đã được tạo hay chưa.
gcloud sql connect ${INSTANCE_NAME} --user=evolution --database=product_details
Sau khi nhập mật khẩu (cũng là tiến hoá), lấy tất cả dữ liệu trong bảng gói.
product_details=> SELECT * FROM packages;
Kết quả sẽ tương tự như sau:
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)
Nhập \q
để thoát khỏi CloudSQL.
main.py
Khi các tệp data_model.py
, package-service.yaml
và connect_connector.py
mở, hãy tạo một main.py
cho ứng dụng.
Câu lệnh 1: Sử dụng thư viện bình python – tạo một phương thức triển khai sử dụng các điểm cuối http còn lại cho dịch vụ này
Câu lệnh 2: Sử dụng thư viện bình python – tạo một phương thức triển khai sử dụng các điểm cuối http còn lại cho dịch vụ này. nhập và sử dụng SessionMaker từ connect_conector.py đến dữ liệu gói.
Câu lệnh 3: Sử dụng thư viện bình python – tạo một phương thức triển khai sử dụng các điểm cuối http còn lại cho dịch vụ này. nhập và sử dụng Gói từ data_model.py và SessionMaker từ connect_conector.py đến dữ liệu gói.
Câu lệnh 4: Sử dụng thư viện bình python – tạo một phương thức triển khai sử dụng các điểm cuối http còn lại cho dịch vụ này. nhập và sử dụng Gói từ data_model.py và SessionMaker từ connect_conector.py đến dữ liệu gói. Sử dụng IP của máy chủ lưu trữ 0.0.0.0 cho app.run
Hãy cập nhật các yêu cầu đối với main.py
.
Câu lệnh: Tạo tệp yêu cầu cho main.py
Thêm tệp này vào tệp requirements.txt
. Hãy nhớ sử dụng Flask phiên bản 3.0.0.
Sử dụng mã OPEN
trong quy trình công việc mới của tệp như trước đây. Lưu mã trong tệp có tên
main.py
.
Tệp cuối cùng nằm trong phần PHỤ LỤC của lớp học lập trình này. Nếu không, hãy thực hiện các thay đổi thích hợp theo cách thủ công.
Đặt lại nhật ký trò chuyện trên Duet AI bằng cách nhấp vào biểu tượng thùng rác ở đầu thanh bên của Duet AI.
5. Kiểm thử và chạy ứng dụng
Cài đặt các yêu cầu.
pip3 install -r requirements.txt
Chạy main.py
.
python main.py
Kết quả sẽ tương tự như sau:
* 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
Trên một thiết bị đầu cuối thứ hai, hãy kiểm thử điểm cuối /packages/<product_id>
.
curl localhost:5000/packages/1
Kết quả sẽ tương tự như sau:
{"depth":10.0,"height":10.0,"special_handling_instructions":"No special handling instructions.","weight":10.0,"width":10.0}
Bạn cũng có thể thử nghiệm bất kỳ mã sản phẩm nào khác trong dữ liệu mẫu.
Nhập CTRL_C
để thoát khỏi vùng chứa docker đang chạy trong dòng lệnh.
Đang tạo mã kiểm thử đơn vị
Khi tệp main.py
đang mở, hãy tạo các bài kiểm thử đơn vị.
Câu lệnh 1: Tạo bài kiểm thử đơn vị.
Sử dụng mã OPEN
trong quy trình công việc mới của tệp như trước đây. Lưu mã trong tệp có tên
test.py
.
Trong hàm test_get_package
, bạn phải định nghĩa product_id
. Bạn có thể tự thêm.
Tệp cuối cùng nằm trong phần PHỤ LỤC của lớp học lập trình này. Nếu không, hãy thực hiện các thay đổi thích hợp theo cách thủ công.
Đặt lại nhật ký trò chuyện trên Duet AI bằng cách nhấp vào biểu tượng thùng rác ở đầu thanh bên của Duet AI.
Chạy kiểm thử đơn vị
Chạy kiểm thử đơn vị.
python test.py
Kết quả sẽ tương tự như sau:
. ---------------------------------------------------------------------- Ran 1 test in 1.061s OK
Đóng tất cả các tệp trong Cloud Shell Editor và xoá nhật ký trò chuyện bằng cách nhấp vào biểu tượng thùng rác ở thanh trạng thái trên cùng.
tệp Docker
Tạo một Dockerfile
cho ứng dụng này.
Hãy mở main.py
rồi thử các câu lệnh sau.
Câu lệnh 1: Tạo một Dockerfile cho ứng dụng này.
Nhắc 2: Tạo một Dockerfile cho ứng dụng này. Sao chép tất cả các tệp vào vùng chứa.
Bạn cũng cần đặt ENVARS
cho INSTANCE_CONNECTION_NAME
, DB_USER
, DB_PASS
và DB_NAME
. Bạn có thể thực hiện việc này theo cách thủ công. Dockerfile của bạn sẽ có dạng như sau:
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"]
Sử dụng mã OPEN
trong quy trình công việc mới của tệp như trước đây. Lưu mã trong tệp có tên Dockerfile.
Tệp cuối cùng nằm trong phần PHỤ LỤC của lớp học lập trình này. Nếu không, hãy thực hiện các thay đổi thích hợp theo cách thủ công.
Chạy ứng dụng trên máy
Khi Dockerfile
mở, hãy thử lời nhắc sau.
Lời nhắc 1: Làm cách nào để chạy một vùng chứa cục bộ bằng Dockerfile này
Làm theo hướng dẫn.
# Build docker build -t shipping . # And run docker run -p 5000:5000 -it shipping
Kết quả sẽ tương tự như sau:
* 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
Từ cửa sổ dòng lệnh thứ hai, hãy truy cập vào vùng chứa.
curl localhost:5000/packages/1
Kết quả sẽ tương tự như sau:
{"depth":10.0,"height":10.0,"special_handling_instructions":"No special handling instructions.","weight":10.0,"width":10.0}
Ứng dụng trong vùng chứa đang hoạt động.
Nhập CTRL_C
để thoát khỏi vùng chứa docker đang chạy trong dòng lệnh.
Hình ảnh vùng chứa toà nhà trong Artifact Registry
Tạo hình ảnh vùng chứa và đẩy đến 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
Vùng chứa ứng dụng hiện đặt tại us-central1-docker.pkg.dev/${PROJECT_ID}/shipping/shipping
và có thể triển khai cho GKE.
6. Triển khai ứng dụng cho cụm GKE
Một cụm Tự động triển khai GKE đã được tạo khi bạn xây dựng tài nguyên GCP cho hội thảo này. Kết nối với cụm GKE.
gcloud container clusters get-credentials gke1 \ --region=us-central1
Chú thích tài khoản dịch vụ mặc định của Kubernetes bằng tài khoản dịch vụ của Google.
kubectl annotate serviceaccount default iam.gke.io/gcp-service-account=cloudsqlsa@${PROJECT_ID}.iam.gserviceaccount.com
Kết quả sẽ tương tự như sau:
serviceaccount/default annotated
Chuẩn bị và áp dụng tệp 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
Kết quả sẽ tương tự như sau:
deployment.apps/shipping created service/shipping created
Đợi cho đến khi Nhóm đang chạy và Dịch vụ được chỉ định địa chỉ IP của trình cân bằng tải bên ngoài.
kubectl get pods kubectl get service shipping
Kết quả sẽ tương tự như sau:
# 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
Đối với các cụm Tự động điều khiển GKE, hãy đợi vài giây cho đến khi tài nguyên sẵn sàng.
Truy cập dịch vụ thông qua địa chỉ EXTERNAL-IP
.
export EXTERNAL_IP=$(kubectl get svc shipping --output jsonpath='{.status.loadBalancer.ingress[0].ip}') curl http://${EXTERNAL_IP}/packages/1
Kết quả sẽ tương tự như sau:
{"depth":10.0,"height":10.0,"special_handling_instructions":"No special handling instructions.","weight":10.0,"width":10.0}
7. Tín dụng bổ sung: Khắc phục sự cố khi đăng ký
Xoá vai trò IAM của ứng dụng CloudSQL khỏi tài khoản dịch vụ cloudsqlsa
. Điều này gây ra lỗi khi kết nối với cơ sở dữ liệu CloudSQL.
gcloud projects remove-iam-policy-binding ${PROJECT_ID} \ --member="serviceAccount:cloudsqlsa@${PROJECT_ID}.iam.gserviceaccount.com" \ --role="roles/cloudsql.client"
Khởi động lại Nhóm vận chuyển.
kubectl rollout restart deployment shipping
Sau khi Nhóm khởi động lại, hãy thử truy cập lại vào dịch vụ shipping
.
export EXTERNAL_IP=$(kubectl get svc shipping --output jsonpath='{.status.loadBalancer.ingress[0].ip}') curl http://${EXTERNAL_IP}/packages/1
Kết quả sẽ tương tự như sau:
... <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>
Kiểm tra Nhật ký bằng cách chuyển đến Kubernetes Engine > Khối lượng công việc
Nhấp vào thẻ triển khai shipping
rồi nhấp vào thẻ Logs (Nhật ký).
Nhấp vào biểu tượng Xem trong trình khám phá nhật ký ở bên phải thanh trạng thái. Thao tác này sẽ mở ra một cửa sổ mới có tên là Log Explorer (Trình khám phá nhật ký).
Nhấp vào một trong các mục lỗi Traceback
, sau đó nhấp vào Giải thích mục nhập nhật ký này.
Bạn có thể đọc phần giải thích về lỗi.
Tiếp theo, hãy để Duet AI giúp khắc phục lỗi.
Hãy thử câu lệnh sau.
Câu lệnh 1: Giúp tôi khắc phục lỗi này
Nhập thông báo lỗi vào lời nhắc.
Lời nhắc 2: Bị cấm: Tên chính IAM đã xác thực có vẻ như không được phép gửi yêu cầu API. Xác minh "API Quản trị Cloud SQL" được bật trong dự án GCP và "Ứng dụng Cloud SQL" vai trò đã được cấp cho người gốc IAM
Sau đó.
Câu lệnh 3: Làm cách nào để chỉ định vai trò Ứng dụng Cloud SQL cho một tài khoản dịch vụ của Google bằng gcloud?
Chỉ định vai trò Ứng dụng Cloud SQL cho cloudsqlsa
.
gcloud projects add-iam-policy-binding ${PROJECT_ID} \ --member="serviceAccount:cloudsqlsa@${PROJECT_ID}.iam.gserviceaccount.com" \ --role="roles/cloudsql.client"
Hãy đợi một lát và thử truy cập lại vào ứng dụng.
export EXTERNAL_IP=$(kubectl get svc shipping --output jsonpath='{.status.loadBalancer.ingress[0].ip}') curl http://${EXTERNAL_IP}/packages/1
Kết quả sẽ tương tự như sau:
{"depth":10.0,"height":10.0,"special_handling_instructions":"No special handling instructions.","weight":10.0,"width":10.0}
Bạn đã sử dụng thành công Duet AI trong tính năng Cloud Logging, Log Explorer (Trình khám phá nhật ký) và tính năng Log giải thích (Trình giải thích nhật ký) để khắc phục vấn đề này.
8. Kết luận
Xin chúc mừng! Bạn đã hoàn tất thành công lớp học lập trình này.
Trong lớp học lập trình này, bạn đã tìm hiểu các nội dung sau:
- Kích hoạt Duet AI trong dự án GCP và định cấu hình để sử dụng trong IDE và Cloud Console.
- Sử dụng Duet AI để tạo, hoàn thành và giải thích mã.
- Sử dụng Duet AI để giải thích và khắc phục sự cố về ứng dụng.
- Các tính năng của Duet AI như trò chuyện IDE và trò chuyện nhiều lượt, trò chuyện so với tạo mã cùng dòng, các thao tác thông minh như giải thích mã và xác nhận trích dẫn cùng nhiều tính năng khác.
9. Phụ lục
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
tệp Docker
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"]