1. はじめに
この Codelab では、Gemini Code Assist がソフトウェア開発ライフサイクル(SDLC)の主なステージ(設計、構築、デプロイします。アプリケーション全体を設計、開発し、Google Cloud にデプロイします。
技術イベントのセッションを横断して検索するための API とアプリケーションを構築する予定です。各セッションには、タイトル、サマリー、時間、カテゴリ、1 人以上の講演者が割り当てられます。
演習内容
- 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 を有効にする
この Codelab の残りの部分では、Code OSS ベースのフルマネージド開発環境である Cloud Shell IDE を使用します。Cloud Shell IDE で Code Assist を有効にして構成する必要があります。手順は次のとおりです。
- ide.cloud.google.com にアクセスします。IDE が表示されるまで時間がかかることがあります。その場合は、セットアップのデフォルトの選択をすべて受け入れ、そのままお待ちください。IDE の設定手順が表示されたら、デフォルトの設定で手順を進めてください。
- 下のステータスバーにある [Cloud Code - Sign in] ボタンをクリックします。指示に従ってプラグインを承認します。ステータスバーに「Cloud Code - no project」と表示されている場合は、それを選択して、使用するプロジェクトのリストから特定の Google Cloud プロジェクトを選択します。
- 画面右下の [Code Assist] ボタンをクリックし、最後に正しい Google Cloud プロジェクトを選択します。Cloud AI Companion API を有効にするように求められた場合は、有効にして続行してください。
- Google Cloud プロジェクトを選択したら、ステータスバーの Cloud Code ステータス メッセージでそれを確認できます。また、右側にあるステータスバーの Code Assist が有効になっていることも確認します。
Gemini Code Assist をご利用いただけるようになりました。
3. Firestore を設定する
Cloud Firestore は、アプリケーション データのバックエンドとして使用する、フルマネージドのサーバーレス ドキュメント データベースです。Cloud Firestore のデータは、ドキュメントのコレクションで構造化されています。
デフォルトの Firestore データベースに sessions
という名前のコレクションを作成する必要があります。このコレクションには、アプリケーションで使用するサンプルデータ(ドキュメント)が格納されます。
以下に示すように、Cloud Shell IDE 内からメインメニューを使用してターミナルを開きます。
sessions
という名前のコレクションを作成する必要があります。これにより、サンプル セッション ドキュメントのリストが保持されます。各ドキュメントには次の属性があります。
- title: 文字列
- category: 文字列の配列
- speakers: 文字列の配列
- duration: 文字列
- summary: string
サンプルデータを含むファイルを自分のプロジェクトのバケットにコピーして、このコレクションにサンプルデータを追加しましょう。バケットから gcloud firestore import
コマンドを使用してコレクションをインポートできます。
Firestore データベースの初期化
Cloud コンソールで Firestore ページにアクセスします。
プロジェクトで Firestore データベースをまだ初期化していない場合は、default
データベースを作成します。データベースの作成時に、次の値を使用します。
- Firestore モード:
Native
- ロケーション: [ロケーション タイプ] で [
Region
] を選択し、アプリケーションに適したリージョンを選択します。この場所は、次のステップでバケットの場所を確認するときに必要になるため、メモしておきます。 - データベースを作成します。
次に、以下の手順に沿って sessions
コレクションを作成します。
- 以下の
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
- バケットが作成されたので、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
インポートには数秒かかります。準備が整ったら、Firestore データベースとコレクションを検証できます。https://console.cloud.google.com/firestore/databases にアクセスし、以下に示すように default
データベースと sessions
コレクションを選択します。
これで、アプリケーションで使用する Firestore コレクションの作成が完了しました。
4. アプリケーション テンプレートを作成する
この Codelab の残りの部分で使用するサンプルアプリ(Python Flask アプリケーション)を作成します。このアプリケーションは、技術カンファレンスで開催されるセッション全体を検索します。
手順は次のとおりです。
- 下のステータスバーで Google Cloud プロジェクト名をクリックします。
- オプション一覧が表示されます。下のリストで [New Application] をクリックします。
- [Cloud Run application] を選択します(これはアプリのランタイムになります)。
- [Python (Flask): Cloud Run] アプリケーション テンプレートを選択します。
- アプリケーションに名前を付けて、任意の場所に保存します。
- アプリケーションが作成されたことを確認する通知が表示され、下に示すように、アプリケーションが読み込まれた状態で新しいウィンドウが開きます。
README.md
ファイルが開きます。このビューは一旦閉じて構いません。
5. Gemini Code Assist を操作する
このラボでは、VS Code の Cloud Code 拡張機能の一部として、Cloud Shell IDE 内で利用可能な Gemini Code Assist Chat を使用します。これを表示するには、左側のナビゲーション バーにある [Code Assist] ボタンをクリックします。左側のナビゲーション ツールバーにあるコード アシスト アイコン をクリックします。
これにより、Cloud Shell IDE 内に Code Assist のチャットペインが表示され、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
というファイルを作成し、[現在のファイルに挿入] オプションを使用してコード アシスト チャット ウィンドウから内容をコピーします。(+
ボタン)をクリックし、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
ファイルがあります。コード アシスタンスによって生成されたコードに置き換えて、ファイルを保存するだけです。
app.run()
行を変更して、ポート 8080、ホストアドレス 0.0.0.0 を使用し、ローカル実行中はデバッグモードでも実行したいと思います。その方法は次のとおりです。まず、この行をハイライト表示/選択します。
app.run()
次に、コード アシスト チャット インターフェースで、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
ファイルを更新してください。
アプリケーションをローカルで実行する
今度はアプリケーションをローカルで実行し、当初のとおりにアプリケーションの要件を検証してみましょう。
まず、仮想環境にインストールするために、requirements.txt の Python パッケージ依存関係を使用して仮想 Python 環境を作成します。そのためには、Cloud Shell IDE でコマンド パレット(Ctrl+Shift+P)に移動し、「Create Python environment」と入力します。次の数ステップに従って、仮想環境(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
次の URL で API をプレビューできるようになりました。ここでは、開発サーバーがポート 8080 で実行されていることを前提としています。そうでない場合は、適切なポート番号に変更してください。
https://<host-name>:8080/sessions
https://<host-name>:8080/sessions/{id}
https://<host-name>:8080/sessions/categories/{category}
以下の手順に沿って、これらの URL(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. コードのリファクタリング
ハードコードされたサンプル JSON データを app.py
に含める代わりに、これを別のモジュールに分離/抽出することで、コードとデータを明確に分離できます。やってみる!
app.py
ファイルを開いたまま、次のプロンプトを入力します。
Can I improve this code and separate out the sessions data from this app.py file?
その方法に関する提案が表示されます。たとえば、次のような提案が表示されます。
それでは、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 リストから移動して、この Codelab の冒頭で作成した 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 開発用サーバーをローカルで実行している場合、Python モジュールが見つからないというエラーが理由でアプリケーションが終了している可能性があります。
たとえば、requirements.txt
ファイルに追加する必要がある Python モジュールについては、次のように Code Assist に質問できます。
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
URL にアクセスします。sessions
コレクションに追加したサンプル ドキュメントが表示されます。
前のステップで説明したように、他の URI にクエリを実行して、特定のカテゴリのセッションまたはすべてのセッションを取得することもできます。
10. コードの説明
ここで Gemini Code Assist の "Explain this"
機能を使用して、コードについて理解を深めましょう。任意のファイルに移動するか、特定のコード スニペットを選択して、Explain this
というプロンプトで Code Assist に話しかけてみましょう。
演習として、sessions.py
ファイルにアクセスして Firestore 固有のコードをハイライト表示し、コードの説明を取得します。Python コードだけでなく、プロジェクト内の他のファイルでもこの機能を使用することをおすすめします。
11. ウェブ アプリケーションを生成する
API を生成し、Firestore のライブ コレクションと統合したので、次はアプリケーション用のウェブベースのフロントエンドを生成します。ウェブ フロントエンドは現在、特定のカテゴリに属するセッションを検索できる機能を最小限に抑えています。そのための API パス(/sessions/categories/{category}
)があるので、ウェブ アプリケーションでこれを呼び出して結果を取得する必要があります。
それでは詳しく見ていきましょう。コード アシスタンスに次のプロンプトを入力します。
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 が生成されます。また、ルート URL またはベース URL にアクセスしたすべてのユーザーにホームページが表示されるように、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
フォルダ内に配置する必要があります。このフォルダは、この Codelab の冒頭で Flask テンプレートに基づいてアプリケーションを生成したため、利用可能になっています。その結果、既存の index.html
ファイルが作成されます。このファイルの内容を、ここで生成した新しいファイルに置き換えるだけです。Code Assist では、app.py
ファイルに render_template
をインポートするよう指定することもできます。
次に、ウェブ アプリケーションのコードを index.html
ファイルに保存します。このファイルは必ず templates
フォルダに配置します。
アプリケーションをローカルで実行する
今度はアプリケーションをローカルで実行し、当初のとおりにアプリケーションの要件を検証してみましょう。
ローカル Flask サーバーがまだ実行されており、エラーが表示されないことを確認します。エラーが発生した場合は、対処してサーバーを起動します。
起動したら、アプリケーションのホーム URL にアクセスします。以下のように、index.html
ファイルが表示されます。
データのカテゴリのいずれか(AI
など)を入力として指定し、[Search
] ボタンをクリックします。これにより、AI
カテゴリでタグ付けされたセッションが表示されます。
オプションの演習では、各セッションの期間、カテゴリ、話し手、サマリーなどの追加のメタデータを表示できます。
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
ファイルに移動し、コード アシスタンスに次のプロンプトを入力します。
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?
デバッグ フラグを off に設定するのを忘れていたため、お問い合わせいただきありがとうございます。
示されているように、デバッグをオフにし、gcloud
コマンドを使用して Gemini Code Assist にサポートを依頼してください。このコマンドを使用すると、最初にコンテナをビルドすることなく、ソースから直接 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 サービスの URL が表示されます。その公開 URL にアクセスすると、同じウェブ アプリケーションがデプロイされ、正常に実行されるはずです。
お疲れさまでした。
15. (省略可)Cloud Logging を使用する
アプリケーションにロギングを導入すれば、アプリケーション ログを Google Cloud サービスの一つ(Cloud Logging)に一元化できます。その後、Gemini のオブザーバビリティ機能を使用して、ログエントリを理解できます。
これを行うには、まず Google Cloud の既存の Python Cloud Logging ライブラリを使用し、(ログや重大度のレベルに応じて)情報メッセージ、警告メッセージ、エラー メッセージをロギングするために使用します。
まずは Code Assist にリクエストしてみましょう。次のプロンプトを試します。
How do I use the google-cloud-logging package in Python?
以下のように、情報を含むレスポンスが返されます。
カテゴリ別にセッションを検索する関数に、ロギング ステートメントを追加しましょう。
まず、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
に移動します。
すると、次のように、これらのログ ステートメントにフィルタできるはずです。
ログ ステートメントのいずれかをクリックして開き、Explain this log entry
をクリックします。これにより、Gemini を使用してログエントリが説明されます。Gemini for Google Cloud を有効にしていない場合は、Cloud AI Companion API を有効にするように求められます。手順に沿って設定してください。
レスポンスの例を以下に示します。
16. 完了
これで、アプリケーションをゼロから構築し、設計、構築、テスト、デプロイなど、SDLC のさまざまな側面で Gemini Code Assist を使用できました。
次のステップ
以下の Codelab をご覧ください。