運用 Gemini Code Assist 大幅簡化開發工作流程

1. 簡介

e5b98fd4e417c877.png

在這個程式碼研究室中,您將瞭解 Gemini Code Assist 如何在軟體開發生命週期 (SDLC) 的重要階段提供支援,例如設計、建構、測試及部署。我們會設計及開發整個應用程式,並將其部署至 Google Cloud。

我們將建構 API 和應用程式,以便在技術活動中搜尋各工作階段。每個講座都有一個標題、摘要、時間長度、類別和一或多位講者。

執行步驟

  • 根據 OpenAPI 規格設計、建構、測試及部署網頁應用程式

課程內容

  • 如何使用 Gemini Code Assist 產生 OpenAPI 規格
  • 如何使用 Gemini Code Assist 程式碼產生功能,開發符合 OpenAPI 規格的 Python Flask 應用程式
  • 如何使用 Gemini Code Assist 產生 Python Flask 應用程式的網路前端
  • 如何使用 Gemini Code Assist,將應用程式部署至 Google Cloud Run
  • 使用 Gemini Code Assist 功能,例如程式碼說明、產生測試案例,同時建構及測試應用程式

軟硬體需求

  • Chrome 網路瀏覽器
  • Gmail 帳戶
  • 已啟用計費功能的 Cloud 專案
  • 你的 Cloud 專案已啟用 Gemini Code Assist

本研究室的適用對象為各級開發人員,包括初學者。雖然範例應用程式採用 Python 語言,但您不需要熟悉 Python 程式也能瞭解實際情況。我們的重點將放在熟悉 Gemini Code Assist 的功能。

2. 設定 Gemini Code Assist

本節說明開始使用這個研究室所需的一切資源。

在 Cloud Shell IDE 中啟用 Gemini Code Assist

我們將在程式碼研究室的其餘部分,使用 Cloud Shell IDE (全代管的程式碼 OSS 開發環境)。您必須在 Cloud Shell IDE 中啟用及設定 Code Assist,步驟如下:

  1. 前往 ide.cloud.google.com。IDE 可能需要一點時間才會顯示,請耐心等候,並接受所有預設選項。如果需要查看設定 IDE 的操作說明,請繼續按照預設設定完成這些設定。
  2. 按一下底部狀態列中的「Cloud Code - 登入」按鈕 (如圖所示)。按照指示授權外掛程式。如果您在狀態列中看到「Cloud Code - no project」,請選取該專案,然後從您打算使用的專案清單中選取特定的 Google Cloud 專案。

6f5ce865fc7a3ef5.png

  1. 點選右下角的「Code Assist」按鈕,然後選取最後一次正確的 Google Cloud 專案。如果系統要求您啟用 Cloud AI Companion API,請啟用該 API 並繼續操作。
  2. 選取 Google Cloud 專案後,請確認狀態列的 Cloud Code 狀態訊息中會顯示,且右側狀態列中顯示 Code Assist 已啟用,如下所示:

709e6c8248ac7d88.png

Gemini Code Assist 已可使用!

3. 設定 Firestore

Cloud Firestore 是全代管的無伺服器文件資料庫,我們會使用這組資料庫做為應用程式資料的後端。Cloud Firestore 中的資料是以「文件」「集合」建立而成。

必須在預設的 Firestore 資料庫中建立名為 sessions 的集合。這個集合會包含我們稍後在應用程式中使用的範例資料 (文件)。

透過主選單,從 Cloud Shell IDE 內部開啟終端機,如下所示:

f1535e14c9beeec6.png

我們必須建立名為「sessions的集合。其中保留工作階段範例文件的清單。每份文件都包含以下屬性:

  1. title:字串
  2. categories:字串陣列
  3. speakers:字串陣列
  4. duration:字串
  5. summary:字串

為了將這個集合填入範例資料,請將含有範例資料的檔案複製到自有專案的值區,然後透過 gcloud firestore import 指令匯入集合。

Firestore 資料庫初始化

前往 Cloud 控制台的 Firestore 頁面

如果您尚未在專案中初始化 Firestore 資料庫,請建立 default 資料庫。建立資料庫時,請使用下列值:

  • Firestore 模式:Native
  • 位置:將「位置類型」設為 Region,然後選取應用程式適用的區域。請記下這個位置,在下個步驟中將會用到該值區位置。
  • 建立資料庫。

504cabdb99a222a5.png

我們將按照下列步驟建立 sessions 集合:

  1. 使用以下提供的 gsutil 指令,在專案中建立值區。將下方指令中的 <PROJECT_ID> 變數替換為您的 Google Cloud 專案 ID。將 <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

匯入作業需要幾秒鐘的時間。完成後,請前往 https://console.cloud.google.com/firestore/databases 選取 default 資料庫和 sessions 集合來驗證 Firestore 資料庫和集合,如下所示:

d3e294d46ba29cd5.png

完成建立應用程式要使用的 Firestore 集合。

4. 建立應用程式範本

我們會建立範例應用程式 (Python Flask 應用程式),用於程式碼研究室的其他部分。這個應用程式會搜尋技術會議提供的各場講座。

請按照下列步驟操作:

  1. 在下方狀態列中點選 Google Cloud 專案名稱

f151759c156c124e.png

  1. 畫面上會顯示選項清單。在下方清單中點選「New Application」

91ea9836f38b7f74.png

  1. 選取「Cloud Run application」(Cloud Run 應用程式) (這會是應用程式的執行階段)。
  2. 選取「Python (Flask): Cloud Run」應用程式範本。
  3. 為該應用程式命名,然後儲存在您偏好的位置。
  4. 您會收到確認應用程式已建立的通知,同時系統會開啟一個新視窗,並顯示您的應用程式,如下所示。系統隨即會開啟 README.md 檔案。您現在可以關閉該檢視畫面。

aaa3725b17ce27cf.png

5. 與 Gemini Code Assist 互動

在本研究室中,我們將使用 Cloud Shell IDE 中的 Gemini Code Assist Chat,做為 VS Code 的 Cloud Code 擴充功能。按一下左側導覽列中的 [程式碼小幫手] 按鈕即可啟用該功能。找出左側導覽列中的程式碼輔助圖示 a489f98a34898727.png,然後按一下該圖示。

系統會在 Cloud Shell IDE 中顯示 Code Assist 即時通訊窗格,方便您與 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.

這樣您應該能根據 OpenAPI 規格檔案中指定的功能和路徑,取得 Python Flask 應用程式的架構。

提供的 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 Chat 介面中輸入提示: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 檔案。

在本機執行應用程式

現在讓我們在本機執行應用程式,依照我們一開始的方式驗證應用程式需求。

首先,請建立具有 requirements.txt 中 Python 套件依附元件的虛擬 Python 環境,以便安裝在虛擬環境中。方法是前往 Cloud Shell IDE 中的「Command Palette」(Ctrl+Shift+P),然後輸入「Create PythonEnvironment」 (建立 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。我們假設您的開發伺服器是在通訊埠 8080 上執行。如果沒有,請將其變更為適當的通訊埠號碼。

  • https://<host-name>:8080/sessions
  • https://<host-name>:8080/sessions/{id}
  • https://<host-name>:8080/sessions/categories/{category}

請按照下列步驟操作,確保您可以使用這些網址擷取 app.py 檔案中包含的 JSON 資料:

開啟新的終端機視窗,然後嘗試下列任一指令:

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

讓我們按照 Code Assist 的建議,將資料拆分為 sessions.py 檔案。

建立名為 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 資料庫中的 sessions 集合 (也就是我們在本程式碼研究室一開始建立的這個集合)。

請將 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 檔案。

如要使用新增的模組 (google-cloud-firestore) 重新建立 Python 環境,請在現有的終端機視窗中執行下列指令:

pip install -r requirements.txt

再次執行應用程式 (使用 python app.py 重新啟動應用程式),然後造訪 /sessions 網址。您現在應該可取得我們新增至 sessions 集合的範例文件。

975d05e6518f1a6a.png

您可以查詢其他 URI,擷取特定類別的特定工作階段或所有工作階段,如前幾個步驟所述。

10. 程式碼說明

建議您趁現在使用 Gemini Code Assist 的 "Explain this" 功能,進一步瞭解程式碼。您可以直接前往任何檔案或選取特定程式碼片段,然後向 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.

這樣就能產生內嵌 JavaScript 和 CSS 的網頁應用程式 HTML。系統也會要求您在 app.py 檔案中新增路徑,讓造訪根或基準網址的任何使用者都能看到首頁。如果內容並未提及該項資訊,請主動詢問或使用下列程式碼片段:

@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 範本產生應用程式,因此可以找到這個資料夾。因此,系統已有 index.html 檔案,您只需將其內容替換為此處產生的新檔案即可。Code Assist 也提及匯入您的 app.py 檔案中 render_template

請將網頁應用程式程式碼儲存在 index.html 檔案中,並請記得將該檔案放在 templates 資料夾中。

在本機執行應用程式

現在讓我們在本機執行應用程式,依照我們一開始的方式驗證應用程式需求。

確認本機 Flask 伺服器仍然執行,且沒有顯示任何錯誤。如果發生錯誤,請予以解決並啟動伺服器。

當應用程式啟動並開始運作後,請造訪應用程式的首頁網址。畫面上會顯示 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 應用程式,以便我們叫用測試案例。

if __name__ == '__main__':

`unittest.main()`

需要上述程式碼才能執行測試案例。

建議您查看每個測試案例,確認所產生程式碼中的 assertEqual 和其他條件,確保能正常運作。由於資料不在 Firestore 集合內,因此可能無法存取,且可能會因為測試失敗而使用一些虛擬資料。因此,請根據實際狀況修改測試案例,或從一些您可能立即不需要的測試案例中檢視意見。

為了示範,我們使用下列指令執行了測試案例 (由於呼叫將會對本機 API 端點進行,因此請務必執行本機開發伺服器):

python tests.py

我們得到以下摘要結果:

Ran 4 tests in 0.274s

FAILED (failures=2)

沒錯,因為第 3 次測試中的工作階段 ID 不正確,且沒有名為「category1的類別

.

因此請視情況調整測試案例並進行測試。

13. 以測試為導向的開發過程

現在,讓我們瞭解如何按照測試開發 (TDD) 方法,在工作階段 API 中新增新的搜尋方法。也就是先撰寫測試案例,說明如何因缺少實作方法而失敗,以及使用 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 中的資料微調,並在 Python 單元測試案例中納入適當的 assert* 方法。

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。系統可能也會要求你啟用 Artifact Registry、Cloud Build 和 Cloud Run 等 Google Cloud API,以及建立 Artifact Registry 存放區的權限。請直接授予權限。

部署程序大約需要 2 分鐘才能完成,請耐心等候。

部署成功之後,您會看到 Cloud Run 服務網址。造訪公開網址,您應該會看到成功部署及執行的同一個網頁應用程式。

c5322d0fd3e0f616.png

恭喜您做得好!

15. (選用) 使用 Cloud Logging

我們可以在應用程式中加入記錄功能,將應用程式記錄集中在其中一項 Google Cloud 服務 (Cloud Logging) 中。然後,我們也能透過 Observability Gemini 功能瞭解記錄項目。

為此,我們必須先使用 Google Cloud 中現有的 Python Cloud Logging 程式庫,並使用這個程式庫記錄資訊、警告或錯誤訊息 (視記錄檔 / 嚴重性等級而定)。

請先試試「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> 端點。

前往 Cloud Console → Logs Explorer

59e297577570695.png

...您應該可以按照下列方式篩選記錄為:

914f1fb6cac30a89.png

只要點選任一記錄陳述式,即可展開內容,然後點選 Explain this log entry,即可使用 Gemini 說明記錄項目。請注意,如果尚未啟用 Google Cloud 專用 Gemini,系統會要求你啟用 Cloud AI Companion API。請按照指示進行。

以下是回應範例:

7fc9783910fa92cc.png

16. 恭喜

恭喜!您已成功從頭建構應用程式,並將 Gemini Code Assist 用於 SDLC 中的多個層面,包括設計、建構、測試及部署。

後續步驟

查看一些程式碼研究室…

參考文件