เพิ่มประสิทธิภาพให้กับเวิร์กโฟลว์การพัฒนาของคุณด้วย Gemini Code Assist

1. เกริ่นนำ

e5b98fd4e417c877.png

ใน 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 โดยทำตามขั้นตอนดังนี้

  1. ไปที่ ide.cloud.google.com อาจใช้เวลาสักพักกว่า IDE จะปรากฏ ดังนั้นโปรดอดทนรอและยอมรับตัวเลือกเริ่มต้นในการตั้งค่า ถ้าคุณเห็นคำแนะนำในการตั้งค่า IDE โปรดดำเนินการต่อและกรอกการตั้งค่าเริ่มต้น
  2. คลิกปุ่ม Cloud Code - Sign inในแถบสถานะด้านล่างตามที่แสดง ให้สิทธิ์ปลั๊กอินตามคำแนะนำ หากเห็น "Cloud Code - ไม่มีโปรเจ็กต์" ในแถบสถานะ ให้เลือกโปรเจ็กต์ดังกล่าวแล้วเลือกโปรเจ็กต์ Google Cloud ที่ต้องการจากรายการโปรเจ็กต์ที่คุณวางแผนจะทำงานด้วย

6f5ce865fc7a3ef5.png

  1. คลิกปุ่ม Code Assist ที่มุมขวาล่างตามที่แสดง แล้วเลือกโปรเจ็กต์ Google Cloud ที่ถูกต้องเป็นครั้งสุดท้าย หากระบบขอให้คุณเปิดใช้ Cloud AI Companion API โปรดเปิดใช้และดําเนินการต่อ
  2. เมื่อคุณเลือกโปรเจ็กต์ Google Cloud แล้ว ให้ตรวจสอบว่าคุณเห็นในข้อความสถานะ Cloud Code ในแถบสถานะ รวมทั้งได้เปิดใช้ Code Assist ทางด้านขวาในแถบสถานะดังที่แสดงด้านล่างแล้ว

709e6c8248ac7d88.png

Gemini Code Assist พร้อมใช้งานแล้ว

3. ตั้งค่า Firestore

Cloud Firestore คือฐานข้อมูลเอกสารแบบ Serverless ที่มีการจัดการโดยสมบูรณ์ โดยเราจะใช้เป็นแบ็กเอนด์สำหรับข้อมูลแอปพลิเคชัน ข้อมูลใน Cloud Firestore มีโครงสร้างในคอลเล็กชันของเอกสาร

เราต้องสร้างคอลเล็กชันชื่อ sessions ในฐานข้อมูล Firestore เริ่มต้น คอลเล็กชันนี้จะเก็บข้อมูลตัวอย่าง (เอกสาร) ที่เราจะใช้ในแอปพลิเคชันของเรา

เปิดเทอร์มินัลจากภายใน Cloud Shell IDE ผ่านเมนูหลักดังที่แสดงด้านล่าง

f1535e14c9beeec6.png

เราต้องสร้างคอลเล็กชันชื่อ sessions การดำเนินการนี้จะมีรายการเอกสารเซสชันตัวอย่าง เอกสารแต่ละรายการจะมีแอตทริบิวต์ต่อไปนี้

  1. title: สตริง
  2. categories: อาร์เรย์ของสตริง
  3. speakers: อาร์เรย์ของสตริง
  4. duration: สตริง
  5. summary: สตริง

มาสร้างคอลเล็กชันนี้ด้วยข้อมูลตัวอย่างโดยการคัดลอกไฟล์ที่มีข้อมูลตัวอย่างลงในที่เก็บข้อมูลในโปรเจ็กต์ของคุณเอง แล้วให้คุณนำเข้าคอลเล็กชันผ่านคำสั่ง gcloud firestore import

การเริ่มต้นฐานข้อมูล Firestore

ไปที่หน้า Firestore ใน Cloud Console

หากคุณยังไม่เคยเริ่มต้นฐานข้อมูล Firestore มาก่อนในโปรเจ็กต์ ให้สร้างฐานข้อมูล default ระหว่างสร้างฐานข้อมูล ให้ใช้ค่าต่อไปนี้

  • โหมด Firestore: Native
  • สถานที่ตั้ง: เลือกประเภทสถานที่ตั้งเป็น Region แล้วเลือกภูมิภาคที่เหมาะกับแอปพลิเคชันของคุณ จดบันทึกตำแหน่งนี้ไว้ เนื่องจากคุณจะต้องใช้ในขั้นตอนถัดไปสำหรับตำแหน่งที่เก็บข้อมูล
  • สร้างฐานข้อมูล

504cabdb99a222a5.png

ตอนนี้เราจะสร้างคอลเล็กชัน sessions โดยทำตามขั้นตอนที่ระบุไว้ด้านล่าง

  1. สร้างที่เก็บข้อมูลในโปรเจ็กต์ด้วยคำสั่ง gsutil ตามที่ระบุไว้ด้านล่าง แทนที่ตัวแปร <PROJECT_ID> ในคำสั่งด้านล่างด้วยรหัสโปรเจ็กต์ Google Cloud แทนที่ <BUCKET_LOCATION> ด้วยชื่อภูมิภาคที่สอดคล้องกับพื้นที่ทางภูมิศาสตร์ของฐานข้อมูล Firestore เริ่มต้น (ตามที่ระบุไว้ในขั้นตอนก่อนหน้า) ซึ่งอาจเป็น US-WEST1, EUROPE-WEST1, ASIA-EAST1 ดังนี้
gsutil mb -l <BUCKET-LOCATION> gs://<PROJECT_ID>-my-bucket
  1. เมื่อสร้างที่เก็บข้อมูลแล้ว เราต้องคัดลอกการส่งออกฐานข้อมูลที่เราเตรียมไว้ลงในที่เก็บข้อมูลนี้ ก่อนที่เราจะนำเข้าไปยังฐานข้อมูล Firebase ได้ ใช้คำสั่งที่ระบุด้านล่าง
gsutil cp -r gs://sessions-master-database-bucket/2024-03-26T09:28:15_95256  gs://<PROJECT_ID>-my-bucket

ตอนนี้เรามีข้อมูลที่จะนำเข้าแล้ว เรามาดูกันที่ขั้นตอนสุดท้ายสำหรับการนำเข้าข้อมูลไปยังฐานข้อมูล Firebase (default) ที่สร้างขึ้น

  1. ใช้คำสั่ง 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 ดังที่แสดงด้านล่าง

d3e294d46ba29cd5.png

เป็นการสร้างคอลเล็กชัน Firestore ที่เราจะใช้ในแอปพลิเคชันของเรา

4. สร้างเทมเพลตใบสมัคร

เราจะสร้างแอปพลิเคชันตัวอย่าง (แอปพลิเคชัน Python Flask) ซึ่งเราจะใช้ใน Codelab ที่เหลือ แอปพลิเคชันนี้จะค้นหาข้ามเซสชันที่มีในการประชุมทางเทคนิค

โปรดทำตามขั้นตอนต่อไปนี้

  1. คลิกชื่อโปรเจ็กต์ Google Cloud ในแถบสถานะด้านล่าง

f151759c156c124e.png

  1. รายการตัวเลือกจะปรากฏขึ้น คลิกแอปพลิเคชันใหม่จากรายการด้านล่าง

91ea9836f38b7f74.png

  1. เลือกแอปพลิเคชัน Cloud Run (นี่จะเป็นรันไทม์สำหรับแอปของเรา)
  2. เลือกเทมเพลตแอปพลิเคชัน Python (Flask): Cloud Run
  3. ตั้งชื่อแอปพลิเคชันและบันทึกไว้ในตำแหน่งที่คุณต้องการ
  4. การแจ้งเตือนจะยืนยันว่าได้สร้างแอปพลิเคชันของคุณแล้ว และหน้าต่างใหม่จะเปิดขึ้นพร้อมแสดงแอปพลิเคชันของคุณดังที่แสดงด้านล่าง ไฟล์ README.md เปิดขึ้น ปิดมุมมองนั้นได้ก่อน

aaa3725b17ce27cf.png

5. การโต้ตอบกับ Gemini Code Assist

สำหรับวัตถุประสงค์ของ Lab นี้ เราจะใช้ Gemini Code Assist Chat ที่มีอยู่ใน Cloud Shell IDE เป็นส่วนหนึ่งของส่วนขยาย Cloud Code ใน VS Code คุณสามารถดึงข้อมูลได้ด้วยการคลิกที่ปุ่ม Code Assist ในแถบนำทางด้านซ้าย มองหาไอคอน Code Assist a489f98a34898727.png ในแถบเครื่องมือการนำทางด้านซ้าย แล้วคลิกไอคอนนั้น

ซึ่งจะเป็นการเปิดแผงแชท Code Assist ภายใน Cloud Shell IDE โดยคุณแชทกับ Code Assist ได้

14ad103efaa0ddaa.png

สังเกตที่ไอคอนถังขยะที่ด้านบน - นี่คือวิธีการรีเซ็ตบริบทสำหรับประวัติการแชทของ 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.

ซึ่งควรแสดงคำอธิบายบรรทัดนั้นๆ อย่างละเอียด ดังตัวอย่างด้านล่างนี้

58ec896a32a4fb68.png

จากนั้นใช้พรอมต์ต่อไปนี้

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 ทำตามขั้นตอนอีก 2-3 ขั้นตอนเพื่อเลือกไฟล์สภาพแวดล้อมเสมือน (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?

จึงจะให้คำแนะนำเกี่ยวกับวิธีดำเนินการได้ ตัวอย่างคำแนะนำที่เราได้รับและคุณจะได้รับคำแนะนำที่คล้ายคลึงกัน มีดังนี้

9b9c56cb527dac4c.png

ลองทำแบบนั้นและแยกข้อมูลของเราออกเป็นไฟล์ 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 แล้ว

975d05e6518f1a6a.png

คุณสามารถค้นหา 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 ที่แสดงตามที่แสดงด้านล่าง

8ca586acc4536879.png

ระบุหมวดหมู่ใดหมวดหมู่หนึ่งจากข้อมูลเป็นอินพุต (เช่น AI) แล้วคลิกปุ่ม Search ซึ่งควรแสดงเซสชันที่ติดแท็กด้วยหมวดหมู่ AI

165faded790a6c.png

แบบฝึกหัดที่ไม่บังคับคือการแสดงข้อมูลเมตาเพิ่มเติม เช่น ระยะเวลา หมวดหมู่ ผู้บรรยาย และสรุปสำหรับแต่ละเซสชัน

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 Guide driven Development (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?

ดีนะที่คุณถาม เราลืมตั้งธงการดีบักเป็นปิด :

2f87ed3a811fb218.png

ตามที่ระบุไว้ ให้ปิดการแก้ไขข้อบกพร่องและขอความช่วยเหลือจาก 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 สาธารณะดังกล่าว แล้วคุณจะเห็นเว็บแอปพลิเคชันเดียวกันนี้และทำงานได้สำเร็จ

c5322d0fd3e0f616.png

ขอแสดงความยินดี ทำได้ดีมาก!

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?

คุณควรได้รับการตอบกลับที่ให้ข้อมูลเกี่ยวกับเรื่องนี้ตามที่ระบุไว้ด้านล่าง

2472e1ccaf8a217d.png

มาเพิ่มคำสั่งการบันทึกลงในฟังก์ชันที่ค้นหาเซสชันตามหมวดหมู่

ก่อนอื่นให้เพิ่มแพ็กเกจ 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

59e297577570695.png

...ซึ่งคุณควรจะสามารถกรองเป็นคำสั่งการบันทึกเหล่านี้ได้ตามที่แสดงด้านล่าง

914f1fb6cac30a89.png

คุณสามารถคลิกข้อความบันทึกใดก็ได้ ขยายข้อความ แล้วคลิก Explain this log entry ซึ่งจะใช้ Gemini เพื่ออธิบายรายการบันทึก โปรดทราบว่าหากคุณยังไม่ได้เปิดใช้ Gemini สำหรับ Google Cloud ระบบจะขอให้คุณเปิดใช้ Cloud AI Companion API โปรดดําเนินการดังกล่าวตามคำแนะนำ

ตัวอย่างคำตอบมีดังนี้

7fc9783910fa92cc.png

16. ขอแสดงความยินดี

ยินดีด้วย คุณสร้างแอปพลิเคชันใหม่ตั้งแต่ต้นและใช้ Gemini Code Assist ได้สำเร็จใน SDLC ในด้านต่างๆ รวมถึงการออกแบบ การสร้าง การทดสอบ และการติดตั้งใช้งาน

สิ่งที่ต้องทำต่อไป

ลองดู Codelab เหล่านี้...

เอกสารอ้างอิง