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

1. บทนำ

e5b98fd4e417c877.png

ในโค้ดแล็บนี้ คุณจะได้ดูว่า Gemini Code Assist ช่วยคุณในขั้นตอนสำคัญของวงจรการพัฒนาซอฟต์แวร์ (SDLC) เช่น การออกแบบ การสร้างและการทดสอบ รวมถึงการติดตั้งใช้งานได้อย่างไร เราจะออกแบบและพัฒนาแอปพลิเคชันทั้งหมด แล้วนำไปใช้งานใน Google Cloud

เราจะสร้าง API และแอปพลิเคชันเพื่อค้นหาในเซสชันต่างๆ ในกิจกรรมทางเทคนิค แต่ละเซสชันจะมีชื่อ ข้อมูลสรุป ระยะเวลา หมวดหมู่ และวิทยากรอย่างน้อย 1 คน

สิ่งที่คุณต้องทำ

  • ออกแบบ สร้าง ทดสอบ และนำเว็บแอปพลิเคชันไปใช้งานโดยอิงตามข้อกำหนด OpenAPI ตั้งแต่ต้น

สิ่งที่คุณจะได้เรียนรู้

  • วิธีใช้ Gemini Code Assist เพื่อสร้างข้อกำหนด OpenAPI
  • วิธีใช้ฟีเจอร์การสร้างโค้ดของ Gemini Code Assist เพื่อพัฒนาแอปพลิเคชัน Python Flask สำหรับข้อกำหนด OpenAPI
  • วิธีใช้ Gemini Code Assist เพื่อสร้างฟรอนท์เอนด์ของเว็บสำหรับแอปพลิเคชัน Python Flask
  • วิธีใช้ Gemini Code Assist เพื่อรับความช่วยเหลือเกี่ยวกับวิธีติดตั้งใช้งานแอปพลิเคชันใน Google Cloud Run
  • ใช้ฟีเจอร์ Gemini Code Assist เช่น คำอธิบายโค้ด การสร้างกรณีทดสอบ ขณะสร้างและทดสอบแอปพลิเคชัน

สิ่งที่คุณต้องมี

  • เว็บเบราว์เซอร์ Chrome
  • บัญชี Gmail
  • โปรเจ็กต์ Cloud ที่เปิดใช้การเรียกเก็บเงิน
  • เปิดใช้ Gemini Code Assist สำหรับโปรเจ็กต์ Cloud

แล็บนี้มีไว้สำหรับนักพัฒนาซอฟต์แวร์ทุกระดับ รวมถึงผู้เริ่มต้น แม้ว่าแอปพลิเคชันตัวอย่างจะอยู่ในภาษา Python แต่คุณไม่จำเป็นต้องคุ้นเคยกับการเขียนโปรแกรม Python เพื่อทำความเข้าใจสิ่งที่เกิดขึ้น เราจะมุ่งเน้นไปที่การทำความคุ้นเคยกับความสามารถของ Gemini Code Assist

2. ตั้งค่า Gemini Code Assist

ส่วนนี้จะครอบคลุมทุกอย่างที่คุณต้องทำเพื่อเริ่มต้นใช้งานแล็บนี้

เปิดใช้ Gemini Code Assist ใน Cloud Shell IDE

เราจะใช้ Cloud Shell IDE ซึ่งเป็นสภาพแวดล้อมในการพัฒนาซอฟต์แวร์ที่อิงตาม Code OSS ที่มีการจัดการครบวงจรสำหรับส่วนที่เหลือของโค้ดแล็บ เราต้องเปิดใช้และกำหนดค่า Code Assist ใน Cloud Shell IDE โดยขั้นตอนมีดังนี้

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

6f5ce865fc7a3ef5.png

  1. คลิกปุ่มช่วยเขียนโค้ดที่มุมขวาล่างตามที่แสดง แล้วเลือกโปรเจ็กต์ 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 เริ่มต้น คอลเล็กชันนี้จะเก็บข้อมูลตัวอย่าง (เอกสาร) ที่เราจะใช้ในแอปพลิเคชัน

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

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. สร้าง Bucket ในโปรเจ็กต์ด้วยคำสั่ง 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. เมื่อสร้าง Bucket แล้ว เราต้องคัดลอกการส่งออกฐานข้อมูลที่เราเตรียมไว้ลงใน Bucket นี้ก่อนจึงจะนำเข้าไปยังฐานข้อมูล 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

การนำเข้าจะใช้เวลาไม่กี่วินาที และเมื่อพร้อมแล้ว คุณจะตรวจสอบฐานข้อมูล 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

ในแล็บนี้ เราจะใช้แชท Gemini Code Assist ที่มีอยู่ใน 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()

จากนั้นในอินเทอร์เฟซแชทของตัวช่วยเขียนโค้ด ให้พิมพ์พรอมต์ 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 ที่มีการอ้างอิงแพ็กเกจ 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}

ทําตามขั้นตอนด้านล่างเพื่อให้แน่ใจว่าคุณสามารถดึงข้อมูล JSON ที่อยู่ในไฟล์ app.py โดยใช้ URL เหล่านี้ได้

เปิดหน้าต่างเทอร์มินัลใหม่แล้วลองใช้คำสั่งต่อไปนี้

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

@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. การสร้างกรณีทดสอบ

เราได้สร้าง API ของเซสชันแล้ว และตอนนี้ก็ถึงเวลาใช้ Gemini Code Assist เพื่อสร้างกรณีทดสอบหน่วยสำหรับเส้นทาง 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 App ที่มีอยู่ซึ่งเราจะเรียกใช้กรณีทดสอบ

if __name__ == '__main__':

`unittest.main()`

คุณต้องใช้โค้ดด้านบนเพื่อเรียกใช้กรณีทดสอบ

เราขอแนะนำให้ดูที่กรณีทดสอบแต่ละกรณี ตรวจสอบ assertEqual และเงื่อนไขอื่นๆ ในโค้ดที่สร้างขึ้นเพื่อให้แน่ใจว่าโค้ดจะทำงานได้ เนื่องจากข้อมูลอยู่ภายนอกในคอลเล็กชัน Firestore คุณจึงอาจไม่มีสิทธิ์เข้าถึงข้อมูลดังกล่าว และอาจใช้ข้อมูลจำลองบางอย่าง ซึ่งอาจทำให้การทดสอบล้มเหลว ดังนั้น ให้แก้ไขกรณีทดสอบตามนั้น หรือแสดงความคิดเห็นในกรณีทดสอบบางรายการที่คุณอาจไม่จำเป็นต้องใช้ในทันที

เราได้เรียกใช้กรณีทดสอบโดยใช้คำสั่งต่อไปนี้เพื่อเป็นการสาธิต (โปรดเรียกใช้เซิร์ฟเวอร์การพัฒนาในเครื่องเนื่องจากจะมีการเรียกไปยังปลายทาง API ในเครื่อง)

python tests.py

เราได้รับผลสรุปต่อไปนี้

Ran 4 tests in 0.274s

FAILED (failures=2)

ซึ่งถูกต้องแล้วเนื่องจากรหัสเซสชันไม่ถูกต้องในการทดสอบครั้งที่ 3 และไม่มีหมวดหมู่ชื่อ category1

ดังนั้นให้ปรับกรณีทดสอบตามนั้นแล้วทดสอบ

13. การพัฒนาที่ขับเคลื่อนด้วยการทดสอบ

ตอนนี้เรามาดูการเพิ่มเมธอดค้นหาใหม่ใน API ของเซสชันตามวิธีการพัฒนาแบบทดสอบขับเคลื่อน (TDD) ซึ่งเกี่ยวกับการเขียนกรณีทดสอบก่อน ทำให้กรณีทดสอบล้มเหลวเนื่องจากไม่มีการติดตั้งใช้งาน และใช้ Gemini Code Assist เพื่อสร้างการติดตั้งใช้งานที่ขาดหายไปเพื่อให้การทดสอบผ่าน

ไปที่ไฟล์ tests.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?

ลองใช้พรอมต์ด้านบนในรูปแบบต่างๆ อีกวิธีที่เราลองใช้คือ

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 APIs เช่น Artifact Registry, Cloud Build และ Cloud Run รวมถึงสิทธิ์ในการสร้างที่เก็บ Artifact Registry โปรดให้สิทธิ์ดังกล่าว

กระบวนการติดตั้งใช้งานจะใช้เวลาประมาณ 2 นาที โปรดรอสักครู่

เมื่อทำให้ใช้งานได้สำเร็จแล้ว คุณจะเห็น URL ของบริการ Cloud Run ไปที่ URL สาธารณะนั้น แล้วคุณจะเห็นเว็บแอปพลิเคชันเดียวกันที่ได้รับการติดตั้งใช้งานและทำงานได้สำเร็จ

c5322d0fd3e0f616.png

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

15. (ไม่บังคับ) ใช้ Cloud Logging

เราสามารถนำการบันทึกมาใช้ในแอปพลิเคชันเพื่อให้บันทึกของแอปพลิเคชันรวมอยู่ที่บริการใดบริการหนึ่งของ Google Cloud (Cloud Logging) จากนั้นเราจะใช้ฟีเจอร์ Observability Gemini เพื่อทำความเข้าใจรายการบันทึกได้ด้วย

ในการดำเนินการนี้ เราจะต้องใช้ไลบรารี Cloud Logging ของ Python ที่มีอยู่จาก Google Cloud ก่อน แล้วใช้ไลบรารีดังกล่าวเพื่อบันทึกข้อความข้อมูล คำเตือน หรือข้อผิดพลาด (ขึ้นอยู่กับระดับบันทึก / ความรุนแรง)

มาลองถาม Code Assist ก่อน ลองใช้พรอมต์ต่อไปนี้

How do I use the google-cloud-logging package in Python?

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

2472e1ccaf8a217d.png

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

ก่อนอื่น ให้เพิ่มแพ็กเกจ google-cloud-logging Python ลงในไฟล์ 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 อีกครั้งโดยใช้คำสั่งเดียวกับในส่วนก่อนหน้า และเมื่อทำให้ใช้งานได้แล้ว ให้เรียกใช้ปลายทาง /sessions/categories/<category> สัก 2-3 ครั้ง

ไปที่ 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 เหล่านี้

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