1. บทนำ
ใน Codelab นี้ คุณจะได้ดูวิธีที่ Gemini Code Assist ช่วยสนับสนุนคุณในขั้นตอนสำคัญๆ ของวงจรการพัฒนาซอฟต์แวร์ (SDLC) เช่น การออกแบบ การสร้าง และ ทดสอบและใช้งาน เราจะออกแบบและพัฒนาแอปพลิเคชันทั้งหมดและทำให้ใช้งานได้บน Google Cloud
เราจะสร้าง API และแอปพลิเคชันเพื่อค้นหาข้ามเซสชันในกิจกรรมทางเทคนิค แต่ละเซสชันจะมีชื่อ สรุป ระยะเวลา หมวดหมู่ และมีผู้บรรยายอย่างน้อย 1 คน
สิ่งที่คุณจะต้องทำ
- ออกแบบ สร้าง ทดสอบ และทำให้เว็บแอปพลิเคชันใช้งานได้ตามข้อกำหนดของ OpenAPI ตั้งแต่ต้น
สิ่งที่คุณจะได้เรียนรู้
- วิธีใช้ Gemini Code Assist เพื่อสร้างข้อกำหนดของ OpenAPI
- วิธีใช้ฟีเจอร์การสร้างโค้ดช่วยเหลือของ Gemini Code เพื่อพัฒนาแอปพลิเคชัน Python Flask สำหรับข้อกำหนด OpenAPI
- วิธีใช้ Gemini Code Assist เพื่อสร้างฟรอนท์เอนด์ของเว็บสำหรับแอปพลิเคชัน Python Flask
- วิธีใช้ Gemini Code Assist เพื่อรับความช่วยเหลือเกี่ยวกับวิธีทำให้แอปพลิเคชันใช้งานได้ใน Google Cloud Run
- ใช้ฟีเจอร์ตัวช่วยโค้ดของ Gemini เช่น คำอธิบายโค้ด การสร้างเคสทดสอบ ขณะสร้างและทดสอบแอปพลิเคชัน
สิ่งที่คุณต้องมี
- เว็บเบราว์เซอร์ Chrome
- บัญชี Gmail
- โปรเจ็กต์ที่อยู่ในระบบคลาวด์ที่เปิดใช้การเรียกเก็บเงิน
- เปิดใช้ Gemini Code Assist สำหรับโปรเจ็กต์ระบบคลาวด์ของคุณแล้ว
ห้องทดลองนี้มุ่งเป้าไปที่นักพัฒนาซอฟต์แวร์ทุกระดับ รวมถึงผู้เริ่มต้น แม้ว่าแอปพลิเคชันตัวอย่างจะเป็นภาษา Python แต่คุณไม่จําเป็นต้องทำความคุ้นเคยกับการเขียนโปรแกรม Python เพื่อทําความเข้าใจถึงสิ่งที่เกิดขึ้น โดยจะมุ่งเน้นที่การทำความคุ้นเคยกับความสามารถของ Gemini Code Assist
2. ตั้งค่า Gemini Code Assist
ส่วนนี้จะครอบคลุมทุกสิ่งที่คุณต้องทำเพื่อเริ่มต้นใช้งานห้องทดลองนี้
เปิดใช้ Gemini Code Assist ใน Cloud Shell IDE
เราจะใช้ Cloud Shell IDE ซึ่งเป็นสภาพแวดล้อมการพัฒนาซอฟต์แวร์ที่อิงตาม Code OSS ที่มีการจัดการครบวงจรสำหรับ Codelab อื่นๆ เราจำเป็นต้องเปิดใช้และกำหนดค่า Code Assist ใน Cloud Shell IDE โดยทำตามขั้นตอนดังนี้
- ไปที่ ide.cloud.google.com อาจใช้เวลาสักครู่กว่าที่ IDE จะปรากฏ ดังนั้นโปรดอดทนรอและยอมรับตัวเลือกเริ่มต้นในการตั้งค่า ถ้าคุณเห็นคำแนะนำในการตั้งค่า IDE โปรดดำเนินการต่อและกรอกการตั้งค่าเริ่มต้น
- คลิกปุ่ม Cloud Code - Sign inในแถบสถานะด้านล่างตามที่แสดง ให้สิทธิ์ปลั๊กอินตามคำแนะนำ หากเห็น "Cloud Code - ไม่มีโปรเจ็กต์" ในแถบสถานะ ให้เลือกโปรเจ็กต์ดังกล่าวแล้วเลือกโปรเจ็กต์ Google Cloud ที่ต้องการจากรายการโปรเจ็กต์ที่คุณวางแผนจะทำงานด้วย
- คลิกปุ่ม Code Assist ที่มุมขวาล่างตามที่แสดง แล้วเลือกโปรเจ็กต์ Google Cloud ที่ถูกต้องเป็นครั้งสุดท้าย หากระบบขอให้คุณเปิดใช้ Cloud AI Companion API โปรดเปิดใช้และดําเนินการต่อ
- เมื่อคุณเลือกโปรเจ็กต์ Google Cloud แล้ว ให้ตรวจสอบว่าคุณเห็นในข้อความสถานะ Cloud Code ในแถบสถานะ รวมทั้งได้เปิดใช้ Code Assist ทางด้านขวาในแถบสถานะดังที่แสดงด้านล่างแล้ว
Gemini Code Assist พร้อมใช้งานแล้ว
3. ตั้งค่า Firestore
Cloud Firestore คือฐานข้อมูลเอกสารแบบ Serverless ที่มีการจัดการโดยสมบูรณ์ โดยเราจะใช้เป็นแบ็กเอนด์สำหรับข้อมูลแอปพลิเคชัน ข้อมูลใน Cloud Firestore มีโครงสร้างในคอลเล็กชันของเอกสาร
เราต้องสร้างคอลเล็กชันชื่อ sessions
ในฐานข้อมูล Firestore เริ่มต้น คอลเล็กชันนี้จะเก็บข้อมูลตัวอย่าง (เอกสาร) ที่เราจะใช้ในแอปพลิเคชันของเรา
เปิดเทอร์มินัลจากภายใน Cloud Shell IDE ผ่านเมนูหลักดังที่แสดงด้านล่าง
เราต้องสร้างคอลเล็กชันชื่อ sessions
การดำเนินการนี้จะมีรายการเอกสารเซสชันตัวอย่าง เอกสารแต่ละรายการจะมีแอตทริบิวต์ต่อไปนี้
- title: สตริง
- categories: อาร์เรย์ของสตริง
- speakers: อาร์เรย์ของสตริง
- duration: สตริง
- summary: สตริง
มาสร้างคอลเล็กชันนี้ด้วยข้อมูลตัวอย่างโดยการคัดลอกไฟล์ที่มีข้อมูลตัวอย่างลงในที่เก็บข้อมูลในโปรเจ็กต์ของคุณเอง แล้วให้คุณนำเข้าคอลเล็กชันผ่านคำสั่ง gcloud firestore import
การเริ่มต้นฐานข้อมูล Firestore
ไปที่หน้า Firestore ใน Cloud Console
หากคุณยังไม่เคยเริ่มต้นฐานข้อมูล Firestore มาก่อนในโปรเจ็กต์ ให้สร้างฐานข้อมูล default
ระหว่างสร้างฐานข้อมูล ให้ใช้ค่าต่อไปนี้
- โหมด Firestore:
Native
- สถานที่ตั้ง: เลือกประเภทสถานที่ตั้งเป็น
Region
แล้วเลือกภูมิภาคที่เหมาะกับแอปพลิเคชันของคุณ จดบันทึกตำแหน่งนี้ไว้ เนื่องจากคุณจะต้องใช้ในขั้นตอนถัดไปสำหรับตำแหน่งที่เก็บข้อมูล - สร้างฐานข้อมูล
ตอนนี้เราจะสร้างคอลเล็กชัน sessions
โดยทำตามขั้นตอนที่ระบุไว้ด้านล่าง
- สร้างที่เก็บข้อมูลในโปรเจ็กต์ด้วยคำสั่ง
gsutil
ตามที่ระบุไว้ด้านล่าง แทนที่ตัวแปร<PROJECT_ID>
ในคำสั่งด้านล่างด้วยรหัสโปรเจ็กต์ Google Cloud แทนที่<BUCKET_LOCATION>
ด้วยชื่อภูมิภาคที่สอดคล้องกับพื้นที่ทางภูมิศาสตร์ของฐานข้อมูล Firestore เริ่มต้น (ตามที่ระบุไว้ในขั้นตอนก่อนหน้า) ซึ่งอาจเป็น US-WEST1, EUROPE-WEST1, ASIA-EAST1 ดังนี้
gsutil mb -l <BUCKET-LOCATION> gs://<PROJECT_ID>-my-bucket
- เมื่อสร้างที่เก็บข้อมูลแล้ว เราต้องคัดลอกการส่งออกฐานข้อมูลที่เราเตรียมไว้ลงในที่เก็บข้อมูลนี้ ก่อนที่เราจะนำเข้าไปยังฐานข้อมูล Firebase ได้ ใช้คำสั่งที่ระบุด้านล่าง
gsutil cp -r gs://sessions-master-database-bucket/2024-03-26T09:28:15_95256 gs://<PROJECT_ID>-my-bucket
ตอนนี้เรามีข้อมูลที่จะนำเข้าแล้ว เรามาดูกันที่ขั้นตอนสุดท้ายสำหรับการนำเข้าข้อมูลไปยังฐานข้อมูล Firebase (default
) ที่สร้างขึ้น
- ใช้คำสั่ง gcloud ที่ระบุด้านล่าง
gcloud firestore import gs://<PROJECT_ID>-my-bucket/2024-03-26T09:28:15_95256
การนำเข้าจะใช้เวลา 2-3 วินาที และเมื่อพร้อมแล้ว คุณตรวจสอบฐานข้อมูล Firestore และคอลเล็กชันได้โดยไปที่ https://console.cloud.google.com/firestore/databases เลือกฐานข้อมูล default
และคอลเล็กชัน sessions
ดังที่แสดงด้านล่าง
เป็นการสร้างคอลเล็กชัน Firestore ที่เราจะใช้ในแอปพลิเคชันของเรา
4. สร้างเทมเพลตใบสมัคร
เราจะสร้างแอปพลิเคชันตัวอย่าง (แอปพลิเคชัน Python Flask) ซึ่งเราจะใช้ใน Codelab ที่เหลือ แอปพลิเคชันนี้จะค้นหาข้ามเซสชันที่มีในการประชุมทางเทคนิค
โปรดทำตามขั้นตอนต่อไปนี้
- คลิกชื่อโปรเจ็กต์ Google Cloud ในแถบสถานะด้านล่าง
- รายการตัวเลือกจะปรากฏขึ้น คลิกแอปพลิเคชันใหม่จากรายการด้านล่าง
- เลือกแอปพลิเคชัน Cloud Run (นี่จะเป็นรันไทม์สำหรับแอปของเรา)
- เลือกเทมเพลตแอปพลิเคชัน Python (Flask): Cloud Run
- ตั้งชื่อแอปพลิเคชันและบันทึกไว้ในตำแหน่งที่คุณต้องการ
- การแจ้งเตือนจะยืนยันว่าได้สร้างแอปพลิเคชันของคุณแล้ว และหน้าต่างใหม่จะเปิดขึ้นพร้อมแสดงแอปพลิเคชันของคุณดังที่แสดงด้านล่าง ไฟล์
README.md
เปิดขึ้น ปิดมุมมองนั้นได้ก่อน
5. การโต้ตอบกับ Gemini Code Assist
สำหรับวัตถุประสงค์ของ Lab นี้ เราจะใช้ Gemini Code Assist Chat ที่มีอยู่ใน Cloud Shell IDE เป็นส่วนหนึ่งของส่วนขยาย Cloud Code ใน VS Code คุณสามารถดึงข้อมูลได้ด้วยการคลิกที่ปุ่ม Code Assist ในแถบนำทางด้านซ้าย มองหาไอคอน Code Assist ในแถบเครื่องมือการนำทางด้านซ้าย แล้วคลิกไอคอนนั้น
ซึ่งจะเป็นการเปิดแผงแชท Code Assist ภายใน Cloud Shell IDE โดยคุณแชทกับ Code Assist ได้
สังเกตที่ไอคอนถังขยะที่ด้านบน - นี่คือวิธีการรีเซ็ตบริบทสำหรับประวัติการแชทของ Code Assist โปรดทราบด้วยว่าการโต้ตอบทางแชทนี้เป็นไปตามบริบทของไฟล์ที่คุณกำลังดำเนินการใน IDE
6. การออกแบบ API
ขั้นตอนแรกของเราคือการรับความช่วยเหลือจาก Gemini Code Assist ในขั้นตอนการออกแบบ ในขั้นตอนนี้ เราจะสร้างข้อกำหนด OpenAPI สำหรับเอนทิตี (เซสชันทางเทคนิคในเหตุการณ์) ที่เราต้องการค้นหา
ระบุพรอมต์ต่อไปนี้
Generate an Open API spec that will allow me to retrieve all sessions, sessions by category, session by id. Each session has the following attributes: id, title, list of speakers, list of categories, summary and duration.
การดำเนินการนี้ควรสร้างข้อกำหนดของ OpenAPI สำหรับการค้นหาข้ามเซสชันผ่านพารามิเตอร์การค้นหาต่างๆ ตัวอย่างข้อมูลจำเพาะมีดังนี้
openapi: 3.0.0
info:
title: Sessions API
description: This API allows you to retrieve all sessions, sessions by category, and session by id.
version: 1.0.0
servers:
- url: https://sessions.example.com
paths:
/sessions:
get:
summary: Get all sessions
operationId: getSessions
responses:
'200':
description: OK
content:
application/json:
schema:
type: array
items:
$ref: '#/components/schemas/Session'
/sessions/{id}:
get:
summary: Get session by id
operationId: getSessionById
parameters:
- name: id
in: path
required: true
description: The id of the session
schema:
type: string
responses:
'200':
description: OK
content:
application/json:
schema:
$ref: '#/components/schemas/Session'
/sessions/categories/{category}:
get:
summary: Get sessions by category
operationId: getSessionsByCategory
parameters:
- name: category
in: path
required: true
description: The category of the sessions
schema:
type: string
responses:
'200':
description: OK
content:
application/json:
schema:
type: array
items:
$ref: '#/components/schemas/Session'
components:
schemas:
Session:
type: object
properties:
id:
type: string
description: The id of the session
title:
type: string
description: The title of the session
speakers:
type: array
items:
type: string
description: The list of speakers for the session
categories:
type: array
items:
type: string
description: The list of categories for the session
summary:
type: string
description: The summary of the session
duration:
type: string
description: The duration of the session
คุณจะสังเกตเห็นว่าข้อกำหนดมีข้อมูลต่อไปนี้
- สคีมาที่กำหนดไว้สำหรับประเภทเซสชัน
- เส้นทาง API หลายเส้นทางมีคำจำกัดความดังนี้
/sessions
/sessions/{id}
/sessions/categories/{category}
สร้างไฟล์ชื่อ sessionsapi.yaml
ในโฟลเดอร์ด้านบน แล้วคัดลอกเนื้อหาจากหน้าต่างแชทของ Code Assist โดยใช้ตัวเลือก "แทรกในไฟล์ปัจจุบัน" (ปุ่ม +
) และเปิดไฟล์ใน Cloud Shell IDE
ถึงตอนนี้ คุณจะบันทึกฟีเจอร์ที่น่าสนใจของ Gemini Code Assist ได้ดังต่อไปนี้ การอ้างอิง ข้อมูลนี้จะปรากฏให้นักพัฒนาซอฟต์แวร์เห็นเมื่อโค้ดที่สร้างขึ้นนั้นอ้างอิงโดยตรงจากแหล่งที่มาอื่น เช่น โค้ดโอเพนซอร์สที่มีอยู่ โดยมีแหล่งที่มาและใบอนุญาตให้นักพัฒนาแอปตัดสินใจว่าต้องทำอย่างไร
สมมติว่าเราพอใจกับเนื้อหาที่สร้างขึ้น เราสามารถใช้เอกสารข้อกำหนดนี้ในการสร้างแอปพลิเคชัน Python Flask ได้
7. สร้างแอปพลิเคชัน
ตอนนี้เราจะขอให้ Code Assist สร้างแอปพลิเคชันดังกล่าว ใส่ข้อความแจ้งต่อไปนี้เมื่อเปิดไฟล์ sessionsapi.yaml
Generate a Python Application using the Flask framework, based on the sessionsapi.yaml file. This application uses a local in memory list of sessions. Do not use any Flask extensions.
การดำเนินการนี้ควรจะให้ข้อมูลโครงกระดูกสำหรับแอปพลิเคชัน Python Flask ซึ่งอิงตามฟังก์ชันและเส้นทางที่ระบุไว้ในไฟล์ข้อมูลจำเพาะของ OpenAPI
รหัสแอปพลิเคชัน Python Flask ที่ให้ไว้ควรคล้ายกับรหัสต่อไปนี้
from flask import Flask, jsonify, request
app = Flask(__name__)
sessions = [
{
"id": "1",
"title": "Session 1",
"speakers": ["Speaker 1", "Speaker 2"],
"categories": ["Category 1", "Category 2"],
"summary": "This is a summary of session 1.",
"duration": "1 hour",
},
{
"id": "2",
"title": "Session 2",
"speakers": ["Speaker 3", "Speaker 4"],
"categories": ["Category 3", "Category 4"],
"summary": "This is a summary of session 2.",
"duration": "1 hour 30 minutes",
},
]
@app.route('/sessions', methods=['GET'])
def get_sessions():
return jsonify(sessions)
@app.route('/sessions/<id>', methods=['GET'])
def get_session_by_id(id):
session = next((session for session in sessions if session['id'] == id), None)
if session is None:
return jsonify({}), 404
return jsonify(session)
@app.route('/sessions/categories/<category>', methods=['GET'])
def get_sessions_by_category(category):
sessions_by_category = [session for session in sessions if category in session['categories']]
return jsonify(sessions_by_category)
if __name__ == '__main__':
app.run()
มีการสร้างไฟล์ app.py
ที่มีอยู่แล้วซึ่งเป็นส่วนหนึ่งของขั้นตอนก่อนหน้า เพียงแทนที่เนื้อหาด้วยโค้ดที่ Code Assist สร้างขึ้นแล้วบันทึกไฟล์
เราต้องการเปลี่ยนบรรทัด app.run()
ให้ใช้พอร์ต 8080, ที่อยู่โฮสต์ 0.0.0.0 และทำงานในโหมดแก้ไขข้อบกพร่องด้วยในระหว่างการดำเนินการในเครื่อง วิธีการมีดังนี้ อย่างแรก มาไฮไลต์/เลือกบรรทัดกัน
app.run()
จากนั้น ในอินเทอร์เฟซ Code Assist ให้พิมพ์พรอมต์: Explain this.
ซึ่งควรแสดงคำอธิบายบรรทัดนั้นๆ อย่างละเอียด ดังตัวอย่างด้านล่างนี้
จากนั้นใช้พรอมต์ต่อไปนี้
update the code to run the application on port 8080, host address 0.0.0.0, and in debug mode
โค้ดที่แนะนำที่สร้างขึ้นควรมีลักษณะดังนี้
app.run(host='0.0.0.0', port=8080, debug=True)
อย่าลืมอัปเดตไฟล์ app.py
ด้วยข้อมูลโค้ดนี้
เรียกใช้แอปพลิเคชันในเครื่อง
มาลองเรียกใช้แอปพลิเคชันภายในระบบกันก่อน เพื่อตรวจสอบข้อกำหนดของแอปพลิเคชันตามสิ่งที่เราเริ่มทำไว้
ขั้นตอนแรกคือการสร้างสภาพแวดล้อม Python เสมือนที่มีทรัพยากร Dependency ของแพ็กเกจ Python ใน requirements.txt เพื่อติดตั้งในสภาพแวดล้อมเสมือนจริง โดยไปที่แผงคำสั่ง (Ctrl+Shift+P) ใน Cloud Shell IDE และพิมพ์สร้างสภาพแวดล้อม Python ทำตามขั้นตอนต่อไปนี้เพื่อเลือกไฟล์สภาพแวดล้อมเสมือน (venv), อินเตอร์พรีเตอร์ของ Python 3.x และไฟล์ requirements.txt
เมื่อสร้างสภาพแวดล้อมแล้ว ให้เปิดหน้าต่างเทอร์มินัลใหม่ (Ctrl+Shift+`) และใช้คำสั่งต่อไปนี้
python app.py
ตัวอย่างการดำเนินการแสดงอยู่ด้านล่าง
(.venv) romin@cloudshell: $ python app.py
* Serving Flask app 'app'
* Debug mode: on
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:8080
* Running on http://10.88.0.3:8080
Press CTRL+C to quit
* Restarting with stat
* Debugger is active!
* Debugger PIN: 132-247-368
ตอนนี้คุณสามารถดูตัวอย่าง API ได้ที่ URL ต่อไปนี้ สมมติว่าเซิร์ฟเวอร์การพัฒนาของคุณกำลังทำงานบนพอร์ต 8080 หากไม่ใช่ โปรดเปลี่ยนเป็นหมายเลขพอร์ตที่เหมาะสม
https://<host-name>:8080/sessions
https://<host-name>:8080/sessions/{id}
https://<host-name>:8080/sessions/categories/{category}
ทำตามขั้นตอนด้านล่างเพื่อให้คุณสามารถเรียกข้อมูลโดยใช้ URL ซึ่งเป็นข้อมูล JSON ที่มีอยู่ในไฟล์ app.py
ได้
เปิดหน้าต่างเทอร์มินัลใหม่และลองใช้คำสั่งต่อไปนี้
curl -X GET http://127.0.0.1:8080/sessions
curl -X GET http://127.0.0.1:8080/sessions/<ID>
curl -X GET http://127.0.0.1:8080/sessions/categories/<CATEGORY_NAME>
8. การเปลี่ยนโครงสร้างโค้ด
แทนที่จะให้ app.py
มีข้อมูล JSON ตัวอย่างแบบฮาร์ดโค้ด เราอาจต้องการแยก/ดึงข้อมูลไปไว้ในโมดูลอื่น เพื่อให้สามารถแยกโค้ดและข้อมูลออกจากกันได้ มาเริ่มกันเลย
ให้เปิดไฟล์ app.py
ไว้และแจ้งเตือนต่อไปนี้
Can I improve this code and separate out the sessions data from this app.py file?
จึงจะให้คำแนะนำเกี่ยวกับวิธีดำเนินการได้ ตัวอย่างคำแนะนำที่เราได้รับและคุณจะได้รับคำแนะนำที่คล้ายคลึงกัน มีดังนี้
ลองทำแบบนั้นและแยกข้อมูลของเราออกเป็นไฟล์ sessions.py
ตามที่ Code Assist แนะนำ
สร้างไฟล์ใหม่ชื่อ sessions.py
, เนื้อหาในรายการ JSON ตามข้อมูลที่เราสร้างไว้ด้านล่างนี้
sessions = [
{
"id": "1",
"title": "Session 1",
"speakers": ["Speaker 1", "Speaker 2"],
"categories": ["Category 1", "Category 2"],
"summary": "This is a summary of session 1.",
"duration": "1 hour",
},
{
"id": "2",
"title": "Session 2",
"speakers": ["Speaker 3", "Speaker 4"],
"categories": ["Category 3", "Category 4"],
"summary": "This is a summary of session 2.",
"duration": "1 hour 30 minutes",
},
]
ตอนนี้ไฟล์ app.py
มีลักษณะเรียบง่ายขึ้นมากดังที่แสดงด้านล่างนี้
from flask import Flask, jsonify, request
from sessions import sessions
app = Flask(__name__)
@app.route('/sessions', methods=['GET'])
def get_sessions():
return jsonify(sessions.sessions)
@app.route('/sessions/<id>', methods=['GET'])
def get_session_by_id(id):
session = next((session for session in sessions.sessions if session['id'] == id), None)
if session is None:
return jsonify({}), 404
return jsonify(session)
@app.route('/sessions/categories/<category>', methods=['GET'])
def get_sessions_by_category(category):
sessions_by_category = [session for session in sessions.sessions if category in session['categories']]
return jsonify(sessions_by_category)
if __name__ == '__main__':
app.run(host='0.0.0.0', port=8080, debug=True)
โปรดตรวจสอบว่าคุณยังเรียกใช้แอปพลิเคชันในเครื่องและใช้ API ด้วยการเปลี่ยนแปลงแบบปรับโครงสร้างใหม่เหล่านี้ได้ เซิร์ฟเวอร์การพัฒนา Python น่าจะยังทำงานอยู่ คุณจึงต้องเรียกใช้เฉพาะคำสั่ง curl
จากขั้นตอนก่อนหน้าเท่านั้น
9. ผสานรวมกับคอลเล็กชัน Firestore
ขั้นตอนถัดไปคือการย้ายออกจากรายการ JSON ในหน่วยความจำในเครื่องที่เรามีสำหรับเซสชัน และเชื่อมต่อแอปพลิเคชันกับคอลเล็กชันเซสชันในฐานข้อมูล Firestore ซึ่งเราสร้างขึ้นในตอนเริ่มต้น Codelab นี้
ให้เปิดไฟล์ sessions.py
ไว้และแจ้งเตือนต่อไปนี้
Can you further refactor the sessions.py code to read from a Firestore database that has a collection named sessions. The collection has the same attributes as the session object that we have defined. Use the Python module google-cloud-firestore.
เราได้รับคำแนะนำต่อไปนี้ให้อ่านเซสชันทั้งหมดจากคอลเล็กชัน Firestore
import google.cloud.firestore
# Create a Firestore client
db = google.cloud.firestore.Client()
# Get the sessions collection
sessions_collection = db.collection("sessions")
# Create a list of sessions
sessions = []
# Iterate over the documents and add them to the list
for doc in sessions_collection.stream():
session = doc.to_dict()
session["id"] = doc.id
sessions.append(session)
ใส่โค้ดใน sessions.py
ได้เลย
หากเซิร์ฟเวอร์ Flask Development ทำงานภายในเครื่อง แอปพลิเคชันอาจปิดลงเนื่องจากไม่พบโมดูล Python
เช่น คุณสามารถถาม Code Assist ว่าต้องเพิ่มโมดูล Python ใดลงในไฟล์ requirements.txt
ดังนี้
Which Python package needs to be installed to make the firestore code work?
ซึ่งจะแสดงชื่อของโมดูล Python (เช่น google-cloud-firestore
) เพิ่มลงในไฟล์ requirements.txt
คุณจะต้องสร้างสภาพแวดล้อม Python ใหม่ด้วยโมดูลที่เพิ่มเข้ามาใหม่ (google-cloud-firestore
) หากต้องการดำเนินการดังกล่าว ให้ใช้คำสั่งต่อไปนี้ในหน้าต่างเทอร์มินัลที่มีอยู่
pip install -r requirements.txt
เรียกใช้แอปพลิเคชันอีกครั้ง (รีสตาร์ทด้วย python app.py
) และไปที่ URL ของ /sessions
ตอนนี้คุณควรจะได้รับเอกสารตัวอย่างที่เราเพิ่มในคอลเล็กชัน sessions
แล้ว
คุณสามารถค้นหา URI อื่นๆ เพื่อดึงข้อมูลเซสชันที่ต้องการหรือเซสชันทั้งหมดสำหรับหมวดหมู่ที่ต้องการตามที่อธิบายไว้ในขั้นตอนก่อนหน้านี้
10. คำอธิบายโค้ด
ตอนนี้เป็นโอกาสที่ดีในการใช้ฟีเจอร์ของ "Explain this"
ของ Gemini Code Assist เพื่อทำความเข้าใจโค้ดได้เป็นอย่างดี คุณสามารถไปที่ไฟล์ใดก็ได้หรือเลือกข้อมูลโค้ดที่ต้องการ แล้วถาม Code Assist โดยใช้คำสั่งต่อไปนี้ Explain this
สำหรับแบบฝึกหัด ให้ไปที่ไฟล์ sessions.py
แล้วไฮไลต์โค้ดเฉพาะสำหรับ Firestore แล้วดูคำอธิบายโค้ด ลองใช้ฟีเจอร์นี้ในไฟล์อื่นๆ ในโปรเจ็กต์ด้วย ไม่ใช่แค่โค้ด Python
11. สร้างเว็บแอปพลิเคชัน
เมื่อเราสร้าง API และผสานรวมกับคอลเล็กชัน Firestore แบบสดแล้ว ต่อไปเราจะสร้างฟรอนท์เอนด์บนเว็บสำหรับแอปพลิเคชัน ปัจจุบันฟรอนท์เอนด์ของเว็บจะมีฟังก์ชันการทำงานอยู่น้อยที่สุด กล่าวคือ สามารถค้นหาเซสชันที่อยู่ในหมวดหมู่เฉพาะได้ โปรดทราบว่าเรามีเส้นทาง API ดังกล่าว เช่น /sessions/categories/{category}
ดังนั้นเว็บแอปพลิเคชันของเราควรเรียกใช้และเรียกข้อมูลผลลัพธ์
มาเริ่มกันเลย ส่งข้อความแจ้งต่อไปนี้ให้กับ Code Assist
Generate a web application that allows me to search for sessions by category and uses the Flask application that we created. Please use basic HTML, CSS and JS. Embed all the Javascript and CSS code into a single HTML file only.
ซึ่งจะสร้าง HTML ของเว็บแอปพลิเคชันที่มี JavaScript และ CSS ฝังอยู่ นอกจากนี้ยังขอให้คุณเพิ่มเส้นทางใหม่ไปยังไฟล์ app.py
เพื่อให้ผู้ใช้ที่เข้าชม URL รากหรือ URL ฐานแสดงหน้าแรก หากไม่ได้กล่าวถึงข้อมูลดังกล่าว โปรดถามคุณหรือใช้ตัวอย่างข้อมูลที่ระบุไว้ด้านล่าง
@app.route('/')
def index():
return render_template('index.html')
คุณสามารถบันทึกไฟล์นี้เป็น index.html
แต่อาจมีคำถามเกี่ยวกับตําแหน่งที่จะบันทึกไฟล์ (เช่น โฟลเดอร์ใด) เราสามารถถามคำถามติดตามผลกับ Code Assist ได้
Given that I am using the flask framework, where should I put the index.html file?
โดยควรให้ข้อมูลที่ชัดเจนว่าระบบใช้เฟรมเวิร์ก render_template
ด้วยเหตุนี้จึงต้องนำไฟล์index.html ไปไว้ภายในโฟลเดอร์ templates
คุณจะพบว่าโฟลเดอร์นี้พร้อมใช้งานเนื่องจากเราได้สร้างแอปพลิเคชันตามเทมเพลต Flask ในช่วงเริ่มต้นของ Codelab นี้ ผลที่ได้คือไฟล์ index.html
ที่มีอยู่แล้วและคุณควรแทนที่เนื้อหาด้วยไฟล์ใหม่ที่สร้างขึ้นที่นี่ นอกจากนี้ Code Assist ยังกล่าวถึงการนำเข้า render_template
ในไฟล์ app.py
อีกด้วย
บันทึกโค้ดเว็บแอปพลิเคชันในไฟล์ index.html
ได้เลย และอย่าลืมวางไฟล์นั้นไว้ในโฟลเดอร์ templates
เรียกใช้แอปพลิเคชันในเครื่อง
มาลองเรียกใช้แอปพลิเคชันภายในระบบกันก่อน เพื่อตรวจสอบข้อกำหนดของแอปพลิเคชันตามสิ่งที่เราเริ่มทำไว้
ตรวจสอบว่าเซิร์ฟเวอร์ Flask ในเครื่องยังคงทำงานอยู่และไม่แสดงข้อผิดพลาด ในกรณีที่เกิดข้อผิดพลาด ให้จัดการและเริ่มต้นเซิร์ฟเวอร์
เมื่อทำงานอยู่ ให้ไปที่ URL หน้าแรกของแอปพลิเคชัน ซึ่งควรแสดงไฟล์ index.html
ที่แสดงตามที่แสดงด้านล่าง
ระบุหมวดหมู่ใดหมวดหมู่หนึ่งจากข้อมูลเป็นอินพุต (เช่น AI
) แล้วคลิกปุ่ม Search
ซึ่งควรแสดงเซสชันที่ติดแท็กด้วยหมวดหมู่ AI
แบบฝึกหัดที่ไม่บังคับคือการแสดงข้อมูลเมตาเพิ่มเติม เช่น ระยะเวลา หมวดหมู่ ผู้บรรยาย และสรุปสำหรับแต่ละเซสชัน
12. การสร้างกรอบการทดสอบ
เราสร้าง Session API ไว้แล้วและตอนนี้ก็ถึงเวลาใช้ Gemini Code Assist ในตอนนี้เพื่อสร้างกรอบการทดสอบ 1 หน่วยสำหรับเส้นทาง API ต่างๆ
ให้เปิดไฟล์ app.py
ไว้และแจ้งเตือนต่อไปนี้
Generate unit test cases for app routes. Use unittest module.
เราได้รับคำตอบต่อไปนี้
import unittest
from app import app
class FlaskAppTestCase(unittest.TestCase):
def test_index(self):
tester = app.test_client()
response = tester.get('/')
self.assertEqual(response.status_code, 200)
def test_get_sessions(self):
tester = app.test_client()
response = tester.get('/sessions')
self.assertEqual(response.status_code, 200)
def test_get_session_by_id(self):
tester = app.test_client()
response = tester.get('/sessions/1')
self.assertEqual(response.status_code, 200)
def test_get_sessions_by_category(self):
tester = app.test_client()
response = tester.get('/sessions/categories/category1')
self.assertEqual(response.status_code, 200)
if __name__ == '__main__':
unittest.main()
สร้างไฟล์ชื่อ tests.py
ด้วยโค้ดด้านบน
หมายเหตุเกี่ยวกับการสร้างกรอบการทดสอบ
คุณอาจเห็นรายการโค้ดที่ต่างจากรายการด้านบน ซึ่งอาจทำให้เกิดปัญหาบางอย่างในการเรียกใช้กรอบการทดสอบ เช่น เราพบว่าในบางการทำงานของเรา โค้ดที่สำคัญต่อไปนี้ขาดหายไป:
from app import app
ต้องใช้โค้ดข้างต้นเพื่อนำเข้าแอป Flask ที่มีอยู่ซึ่งเราจะเรียกใช้กรอบการทดสอบ
if __name__ == '__main__':
`unittest.main()`
ต้องใช้โค้ดข้างต้นเพื่อเรียกใช้กรอบการทดสอบ
เราขอแนะนำให้ดูกรอบการทดสอบแต่ละรายการ ตรวจสอบ assertEqual
และเงื่อนไขอื่นๆ ในโค้ดที่สร้างขึ้นเพื่อให้แน่ใจว่าใช้งานได้ เนื่องจากข้อมูลอยู่ภายนอกในคอลเล็กชัน Firestore จึงอาจไม่มีสิทธิ์เข้าถึงข้อมูลดังกล่าวและอาจใช้ข้อมูลจำลองบางอย่างซึ่งอาจทำให้การทดสอบล้มเหลว ดังนั้น ให้แก้ไขกรอบการทดสอบให้เหมาะสม หรือแสดงความคิดเห็นเกี่ยวกับกรอบการทดสอบบางส่วนที่คุณอาจไม่จำเป็นต้องใช้ในทันที
ในการสาธิต เราได้ทำการทดสอบในกรณีต่างๆ โดยใช้คำสั่งต่อไปนี้ (โปรดเรียกใช้เซิร์ฟเวอร์การพัฒนาในเครื่องเนื่องจากระบบจะเรียกใช้ไปยังปลายทาง API ในเครื่อง)
python tests.py
เราได้ผลลัพธ์สรุปดังต่อไปนี้
Ran 4 tests in 0.274s
FAILED (failures=2)
ใช่แล้ว เนื่องจากรหัสเซสชันไม่ถูกต้องในการทดสอบครั้งที่ 3 และไม่มีหมวดหมู่ที่ชื่อ category1
ดังนั้นจึงควรปรับเปลี่ยนกรอบการทดสอบให้เหมาะสมแล้วทดสอบ
13. การพัฒนาเชิงทดสอบ
ตอนนี้เรามาดูการเพิ่มวิธีการค้นหาแบบใหม่ใน Session API ตามวิธีการทดสอบแบบ Test Develop ปฏิบัติตามนโยบาย (TDD) ที่เกี่ยวกับการเขียนกรอบการทดสอบก่อน แล้วดำเนินการไม่ผ่านเนื่องจากขาดการติดตั้งใช้งาน และใช้ Gemini Code Assist ในการสร้างการติดตั้งใช้งานที่ขาดหายไปเพื่อให้ผ่านการทดสอบ
ไปที่ไฟล์ test.py (สมมติว่าคุณได้แก้ไขไฟล์ tests.py
เพื่อให้การทดสอบทั้งหมดผ่านแล้ว) ถาม Code Assist จากข้อความแจ้งต่อไปนี้
Generate a new test case to search for sessions by speaker
ซึ่งทำให้เราได้ติดตั้งใช้งานกรอบการทดสอบดังต่อไปนี้ และได้แทรกลงในไฟล์ tests.py
อย่างถูกต้องแล้ว
def test_get_sessions_by_speaker(self):
tester = app.test_client()
response = tester.get('/sessions/speakers/speaker1')
self.assertEqual(response.status_code, 200)
self.assertEqual(response.json, [sessions.sessions[0], sessions.sessions[1]])
หากทำการทดสอบ คุณควรเห็นข้อผิดพลาดต่อไปนี้
$ python tests.py
.F.
======================================================================
FAIL: test_get_sessions_by_speaker (__main__.FlaskAppTestCase)
----------------------------------------------------------------------
Traceback (most recent call last):
File "/home/romin/hello-world-5/tests.py", line 21, in test_get_sessions_by_speaker
self.assertEqual(response.status_code, 200)
AssertionError: 404 != 200
----------------------------------------------------------------------
Ran 3 tests in 0.010s
FAILED (failures=1)
ทั้งนี้เนื่องจากกรอบการทดสอบได้เรียกใช้เส้นทางต่อไปนี้ (
/sessions/speakers/
)
และไม่มีการใช้เส้นทางดังกล่าวใน app.py
ให้เราขอให้ Code Assist ช่วยติดตั้งใช้งาน ไปที่ไฟล์ app.py
แล้วส่งข้อความแจ้งต่อไปนี้ให้กับ Code Assist
Add a new route to search for sessions by a specific speaker
เราได้รับคำแนะนำการติดตั้งใช้งานจาก Code Assist ดังต่อไปนี้ ซึ่งได้เพิ่มลงในไฟล์ app.py
แล้ว
@app.route('/sessions/speakers/<speaker>', methods=['GET'])
def get_sessions_by_speaker(speaker):
sessions_by_speaker = [session for session in sessions.sessions if speaker in session['speakers']]
return jsonify(sessions_by_speaker)
กลับไปที่ไฟล์ tests.py
อีกครั้งแล้วแก้ไขกรอบการทดสอบเพื่อให้เราตรวจสอบเบื้องต้นดังนี้
def test_get_sessions_by_speaker(self):
tester = app.test_client()
response = tester.get('/sessions/speakers/Romin Irani')
self.assertEqual(response.status_code, 200)
self.assertEqual(len(response.json), 1)
การทดสอบดำเนินไปได้ดี เราจะให้คุณดูกรอบการทดสอบที่สร้างขึ้น ปรับเปลี่ยนเล็กน้อยตามข้อมูลที่อาจมีใน Firestore และมีเมธอด assert*
ที่เหมาะสมในกรอบการทดสอบหน่วย Python
14. การทำให้ใช้งานได้กับ Google Cloud Run
ตอนนี้เราพอใจกับคุณภาพของการพัฒนาแล้ว ขั้นตอนสุดท้ายคือการทำให้แอปพลิเคชันนี้ใช้งานได้ใน Google Cloud Run แต่สำหรับมาตรการที่ดี เราควรถาม Code Assist ว่าลืมอะไรไปบ้างไหม เมื่อ app.py
เปิดอยู่ ให้ส่งข้อความแจ้งต่อไปนี้
Is there something here I should change before I deploy to production?
ดีนะที่คุณถาม เราลืมตั้งธงการดีบักเป็นปิด :
ตามที่ระบุไว้ ให้ปิดการแก้ไขข้อบกพร่องและขอความช่วยเหลือจาก Gemini Code Assist โดยใช้คำสั่ง gcloud
ที่สามารถใช้ทำให้แอปพลิเคชันใช้งานได้กับ Cloud Run ได้โดยตรงจากต้นทาง (โดยไม่ต้องสร้างคอนเทนเนอร์ก่อน)
ระบุพรอมต์ต่อไปนี้
I would like to deploy the application to Cloud Run directly from source. What is the gcloud command to do that?
ลองใช้ข้อความแจ้งด้านบนสัก 2-3 แบบ อีกสิ่งหนึ่งที่เราลองทำคือ
I would like to deploy this application to Cloud Run. I don't want to build a container image locally but deploy directly from source to Cloud Run. What is the gcloud command for that?
โดยหลักการแล้ว คุณควรได้รับคำสั่ง gcloud
ต่อไปนี้
gcloud run deploy sessions --source .
นอกจากนี้ คุณยังอาจได้รับสิทธิประโยชน์ต่อไปนี้
gcloud run deploy <service-name> --source . \
—-platform managed \
—-allow-unauthenticated
เรียกใช้คำสั่งข้างต้นจากโฟลเดอร์รูทของแอปพลิเคชัน เมื่อระบบขอ region
ให้เลือก us-central1
และเมื่อระบบขอให้อนุญาต unauthenticated invocations
ให้เลือก Y
ระบบอาจขอให้คุณเปิดใช้ Google Cloud API เช่น Artifact Registry, Cloud Build และ Cloud Run รวมถึงสิทธิ์ในการสร้างที่เก็บ Artifact Registry โปรดดำเนินการต่อและให้สิทธิ์
กระบวนการติดตั้งใช้งานจะใช้เวลาประมาณ 2 นาที โปรดอดทนรอ
เมื่อทำให้ใช้งานได้เรียบร้อยแล้ว คุณจะเห็น URL ของบริการ Cloud Run โดยไปที่ URL สาธารณะดังกล่าว แล้วคุณจะเห็นเว็บแอปพลิเคชันเดียวกันนี้และทำงานได้สำเร็จ
ขอแสดงความยินดี ทำได้ดีมาก!
15. (ไม่บังคับ) ใช้ Cloud Logging
เราสามารถเริ่มใช้การบันทึกในแอปพลิเคชันเพื่อให้บันทึกแอปพลิเคชันรวมอยู่ที่ศูนย์กลางในบริการใดบริการหนึ่งของ Google Cloud (Cloud Logging) จากนั้น เราจะใช้ฟีเจอร์ Gemini ในการสังเกตการณ์เพื่อทำความเข้าใจรายการบันทึกได้ด้วย
ในการดำเนินการ ก่อนอื่นเราต้องใช้ไลบรารี Python Cloud Logging ที่มีอยู่จาก Google Cloud และใช้สำหรับการบันทึกการให้ข้อมูล คำเตือน หรือข้อความแสดงข้อผิดพลาด (ขึ้นอยู่กับระดับการบันทึก / ความรุนแรง)
เรามาลองถามเรื่องดังกล่าวกับ Code Assist ก่อนกัน ลองใช้คำสั่งต่อไปนี้
How do I use the google-cloud-logging package in Python?
คุณควรได้รับการตอบกลับที่ให้ข้อมูลเกี่ยวกับเรื่องนี้ตามที่ระบุไว้ด้านล่าง
มาเพิ่มคำสั่งการบันทึกลงในฟังก์ชันที่ค้นหาเซสชันตามหมวดหมู่
ขั้นแรก ให้เพิ่มแพ็กเกจ Python google-cloud-logging
ลงในไฟล์ requirements.txt
ถัดไปเป็นข้อมูลโค้ดที่แสดงวิธีที่เราผสานรวมโค้ดเพื่อใช้การบันทึก
...
from google.cloud import logging
...
app = Flask(__name__)
# Create a logger
logger = logging.Client().logger('my-log')
@app.route('/sessions/categories/<category>', methods=['GET'])
def get_sessions_by_category(category):
logger.log_text(f"Fetching sessions with category {category}")
sessions_by_category = [session for session in sessions.sessions if category in session['categories']]
logger.log_text(f'Found {len(sessions_by_category)} sessions with category {category}')
return jsonify(sessions_by_category)
# # Other App Routes
ทำให้บริการใช้งานได้กับ Cloud Run อีกครั้งโดยใช้คำสั่งเดียวกันกับในส่วนก่อนหน้า และเมื่อทำให้ใช้งานได้แล้ว ให้ดำเนินการเรียก 2-3 ครั้งไปยังปลายทาง /sessions/categories/<category>
ไปที่ Cloud Console → Logs Explorer
...ซึ่งคุณควรจะสามารถกรองเป็นคำสั่งการบันทึกเหล่านี้ได้ตามที่แสดงด้านล่าง
คุณสามารถคลิกข้อความบันทึกใดก็ได้ ขยายข้อความ แล้วคลิก Explain this log entry
ซึ่งจะใช้ Gemini เพื่ออธิบายรายการบันทึก โปรดทราบว่าหากคุณยังไม่ได้เปิดใช้ Gemini สำหรับ Google Cloud ระบบจะขอให้คุณเปิดใช้ Cloud AI Companion API โปรดดําเนินการตามคำแนะนำ
ตัวอย่างคำตอบมีดังนี้
16. ขอแสดงความยินดี
ยินดีด้วย คุณสร้างแอปพลิเคชันใหม่ตั้งแต่ต้นและใช้ Gemini Code Assist ได้สำเร็จใน SDLC ในด้านต่างๆ รวมถึงการออกแบบ การสร้าง การทดสอบ และการติดตั้งใช้งาน
สิ่งที่ต้องทำต่อไป
ลองดู Codelab เหล่านี้...
- ทัวร์ชม Duet AI สำหรับนักพัฒนาซอฟต์แวร์
- การใช้ Duet AI ตลอดวงจรการพัฒนาซอฟต์แวร์
- มีสไตล์การใช้งานด้วย Duet AI สำหรับนักพัฒนาซอฟต์แวร์