1. Введение

В этом практическом занятии вы узнаете, как Gemini Code Assist может помочь вам на ключевых этапах жизненного цикла разработки программного обеспечения (SDLC), таких как проектирование, разработка и тестирование, а также развертывание. Мы спроектируем и разработаем целое приложение и развернем его в облаке Google.
Мы будем разрабатывать API и приложение для поиска по сессиям в рамках технического мероприятия. Каждая сессия будет иметь название, краткое описание, продолжительность, категории и одного или нескольких докладчиков.
Что вы будете делать
- Разработка, создание, тестирование и развертывание веб-приложения на основе спецификации 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
- Облачный проект с включенной функцией выставления счетов.
- Функция Gemini Code Assist включена для вашего облачного проекта.
Эта лабораторная работа предназначена для разработчиков всех уровней, включая начинающих. Хотя пример приложения написан на языке Python, вам не нужно быть знакомым с программированием на Python, чтобы понять, что происходит. Мы сосредоточимся на ознакомлении с возможностями Gemini Code Assist.
2. Настройка Gemini Code Assist
В этом разделе описано все, что вам нужно сделать, чтобы начать работу над этой лабораторной работой.
Включите функцию Gemini Code Assist в IDE Cloud Shell.
Для выполнения оставшейся части практического задания мы будем использовать Cloud Shell IDE — полностью управляемую среду разработки на основе Code OSS . Нам необходимо включить и настроить Code Assist в Cloud Shell IDE, шаги для этого описаны ниже:
- Перейдите по адресу ide.cloud.google.com . Возможно, потребуется некоторое время для отображения IDE, поэтому, пожалуйста, наберитесь терпения и примите все настройки по умолчанию. Если вы увидите инструкции по настройке IDE, пожалуйста, выполните их, используя настройки по умолчанию.
- Нажмите на кнопку « Cloud Code — Войти» в нижней строке состояния, как показано на рисунке. Авторизуйте плагин в соответствии с инструкциями. Если в строке состояния отображается «Cloud Code — нет проекта» , выберите этот пункт, а затем выберите конкретный проект Google Cloud из списка проектов, с которыми вы планируете работать.

- Нажмите на кнопку « Помощь в написании кода» в правом нижнем углу, как показано на рисунке, и еще раз выберите правильный проект Google Cloud. Если вас попросят включить API Cloud AI Companion , сделайте это и продолжите.
- После выбора проекта Google Cloud убедитесь, что он отображается в сообщении о состоянии Cloud Code в строке состояния, а также что функция Code Assist включена справа в строке состояния, как показано ниже:

Gemini Code Assist готов к использованию!
3. Настройка Firestore
Cloud Firestore — это полностью управляемая бессерверная база данных документов, которую мы будем использовать в качестве бэкэнда для данных нашего приложения. Данные в Cloud Firestore структурированы в виде коллекций документов .
Нам необходимо создать коллекцию с именем sessions в нашей базе данных Firestore по умолчанию. Эта коллекция будет содержать примеры данных (документы), которые мы затем будем использовать в нашем приложении.
Откройте терминал из среды разработки Cloud Shell IDE через главное меню, как показано ниже:

Нам необходимо создать коллекцию с именем sessions . Она будет содержать список примеров документов сессий. Каждый документ будет иметь следующие атрибуты:
- заголовок : строка
- категории : массив строк
- speakers : массив строк
- длительность : строка
- краткое содержание : строка
Давайте заполним эту коллекцию примерами данных, скопировав файл, содержащий примеры данных, в хранилище вашего собственного проекта, откуда вы затем сможете импортировать коллекцию с помощью команды gcloud firestore import .
Инициализация базы данных Firestore
Перейдите на страницу Firestore в консоли Cloud.
Если вы ранее не инициализировали базу данных Firestore в проекте, создайте базу данных default . При создании базы данных используйте следующие значения:
- Режим Firestore:
Native - Местоположение: Выберите тип местоположения «
Regionи укажите регион, подходящий для вашего приложения. Запишите это местоположение, так как оно понадобится вам на следующем шаге для определения местоположения хранилища. - Создайте базу данных.

Теперь мы создадим коллекцию sessions , выполнив следующие шаги:
- Создайте корзину в своем проекте с помощью приведенной ниже команды
gsutil. Замените переменную<PROJECT_ID>в приведенной ниже команде на идентификатор вашего проекта Google Cloud. Замените<BUCKET_LOCATION>на имя региона, соответствующее географической области вашей базы данных Firestore по умолчанию (как указано на предыдущем шаге), это может быть US-WEST1, EUROPE-WEST1, ASIA-EAST1:
gsutil mb -l <BUCKET-LOCATION> gs://<PROJECT_ID>-my-bucket
- Теперь, когда бакет создан, нам нужно скопировать подготовленный экспорт базы данных в этот бакет, прежде чем мы сможем импортировать его в базу данных Firebase. Используйте приведенную ниже команду:
gsutil cp -r gs://sessions-master-database-bucket/2024-03-26T09:28:15_95256 gs://<PROJECT_ID>-my-bucket
Теперь, когда у нас есть данные для импорта, мы можем перейти к заключительному шагу — импорту данных в созданную нами базу данных Firebase ( default ).
- Воспользуйтесь приведенной ниже командой gcloud:
gcloud firestore import gs://<PROJECT_ID>-my-bucket/2024-03-26T09:28:15_95256
Импорт займет несколько секунд, и как только он будет готов, вы сможете проверить свою базу данных Firestore и коллекцию, перейдя по адресу https://console.cloud.google.com/firestore/databases , выбрав базу данных default и коллекцию sessions , как показано ниже:

На этом завершается создание коллекции Firestore, которую мы будем использовать в нашем приложении.
4. Создайте шаблон приложения.
Мы создадим тестовое приложение (приложение на Python Flask), которое будем использовать на протяжении всего практического занятия. Это приложение будет осуществлять поиск по сессиям, предлагаемым на технической конференции.
Выполните следующие шаги:
- Щелкните по названию проекта Google Cloud в строке состояния ниже.

- Появится список вариантов. Выберите «Новое приложение» из списка ниже.

- Выберите приложение Cloud Run (это будет среда выполнения для нашего приложения).
- Выберите шаблон приложения Python (Flask): Cloud Run .
- Присвойте приложению имя и сохраните его в нужном месте.
- Уведомление подтверждает создание вашего приложения, и открывается новое окно с загруженным приложением, как показано ниже. Открывается файл
README.md. Вы можете закрыть это окно на данный момент.

5. Взаимодействие с Gemini Code Assist
Для выполнения этой лабораторной работы мы будем использовать чат Gemini Code Assist, доступный в среде разработки Cloud Shell IDE в рамках расширения Cloud Code для VS Code. Вы можете вызвать его, нажав на кнопку Code Assist на левой панели навигации. Найдите значок Code Assist.
в левой панели навигации нажмите на нее.
Это откроет панель чата Code Assist внутри Cloud Shell IDE, и вы сможете общаться с Code Assist.

Обратите внимание на значок корзины вверху — это способ сбросить контекст истории чата Code Assist. Также учтите, что это взаимодействие в чате зависит от файла (или файлов), над которыми вы работаете в IDE.
6. Проектирование API
Первым шагом станет использование сервиса Gemini Code Assist на этапе проектирования. На этом этапе мы сгенерируем спецификацию OpenAPI для тех сущностей (технических сессий на мероприятии), по которым мы хотим осуществлять поиск.
Дайте следующий ответ:
Generate an Open API spec that will allow me to retrieve all sessions, sessions by category, session by id. Each session has the following attributes: id, title, list of speakers, list of categories, summary and duration.
Это должно сгенерировать спецификацию OpenAPI для поиска по сессиям с использованием различных параметров запроса. Пример спецификации приведен ниже:
openapi: 3.0.0
info:
title: Sessions API
description: This API allows you to retrieve all sessions, sessions by category, and session by id.
version: 1.0.0
servers:
- url: https://sessions.example.com
paths:
/sessions:
get:
summary: Get all sessions
operationId: getSessions
responses:
'200':
description: OK
content:
application/json:
schema:
type: array
items:
$ref: '#/components/schemas/Session'
/sessions/{id}:
get:
summary: Get session by id
operationId: getSessionById
parameters:
- name: id
in: path
required: true
description: The id of the session
schema:
type: string
responses:
'200':
description: OK
content:
application/json:
schema:
$ref: '#/components/schemas/Session'
/sessions/categories/{category}:
get:
summary: Get sessions by category
operationId: getSessionsByCategory
parameters:
- name: category
in: path
required: true
description: The category of the sessions
schema:
type: string
responses:
'200':
description: OK
content:
application/json:
schema:
type: array
items:
$ref: '#/components/schemas/Session'
components:
schemas:
Session:
type: object
properties:
id:
type: string
description: The id of the session
title:
type: string
description: The title of the session
speakers:
type: array
items:
type: string
description: The list of speakers for the session
categories:
type: array
items:
type: string
description: The list of categories for the session
summary:
type: string
description: The summary of the session
duration:
type: string
description: The duration of the session
Вы можете заметить, что в спецификации содержится следующее:
- Схема, определенная для типа сессии .
- Определено несколько путей API:
-
/sessions -
/sessions/{id} -
/sessions/categories/{category}
Создайте файл с именем sessionsapi.yaml в корневой папке и скопируйте его содержимое из окна чата Code Assist, используя опцию «вставить в текущий файл» (кнопка + »), и оставьте файл открытым в IDE Cloud Shell.
На этом этапе можно отметить интересную особенность Gemini Code Assist: цитирование . Эта информация отображается разработчику, когда сгенерированный код напрямую и подробно цитирует другой источник, например, существующий открытый исходный код. Она предоставляет разработчику исходный код и лицензию, чтобы тот мог решить, как его использовать.
Если нас устраивает сгенерированный контент, мы можем использовать этот документ со спецификацией для генерации приложения Python Flask.
7. Создайте приложение.
Теперь мы попросим Code Assist сгенерировать приложение. Введите следующую команду, открыв файл sessionsapi.yaml .
Generate a Python Application using the Flask framework, based on the sessionsapi.yaml file. This application uses a local in memory list of sessions. Do not use any Flask extensions.
Это должно предоставить вам основу для приложения Python Flask, базирующуюся на функциональности и путях, указанных в файле спецификации OpenAPI.
Предоставленный код приложения Python Flask должен быть похож на следующий:
from flask import Flask, jsonify, request
app = Flask(__name__)
sessions = [
{
"id": "1",
"title": "Session 1",
"speakers": ["Speaker 1", "Speaker 2"],
"categories": ["Category 1", "Category 2"],
"summary": "This is a summary of session 1.",
"duration": "1 hour",
},
{
"id": "2",
"title": "Session 2",
"speakers": ["Speaker 3", "Speaker 4"],
"categories": ["Category 3", "Category 4"],
"summary": "This is a summary of session 2.",
"duration": "1 hour 30 minutes",
},
]
@app.route('/sessions', methods=['GET'])
def get_sessions():
return jsonify(sessions)
@app.route('/sessions/<id>', methods=['GET'])
def get_session_by_id(id):
session = next((session for session in sessions if session['id'] == id), None)
if session is None:
return jsonify({}), 404
return jsonify(session)
@app.route('/sessions/categories/<category>', methods=['GET'])
def get_sessions_by_category(category):
sessions_by_category = [session for session in sessions if category in session['categories']]
return jsonify(sessions_by_category)
if __name__ == '__main__':
app.run()
В предыдущем шаге уже был создан файл app.py Просто замените его содержимое кодом, сгенерированным Code Assist, и сохраните файл.
Мы хотели бы изменить строку app.run() , чтобы она использовала порт 8080, адрес хоста 0.0.0.0, а также запускалась в режиме отладки во время локального выполнения. Вот как это можно сделать. Для начала выделим/выберем строку:
app.run()
Затем в интерфейсе чата Code Assist введите запрос: Explain this.
Здесь должно быть подробное объяснение данной строки, пример которого приведен ниже:

Теперь воспользуйтесь следующей подсказкой:
update the code to run the application on port 8080, host address 0.0.0.0, and in debug mode
Сгенерированный предлагаемый код должен выглядеть следующим образом:
app.run(host='0.0.0.0', port=8080, debug=True)
Не забудьте обновить файл app.py , добавив этот фрагмент кода.
Запустите приложение локально.
Давайте теперь запустим приложение локально, чтобы проверить, соответствуют ли его требования исходным данным.
Первым шагом будет создание виртуальной среды Python с зависимостями пакетов Python, указанными в файле requirements.txt , которые будут установлены в этой виртуальной среде. Для этого перейдите в палитру команд (Ctrl+Shift+P) в IDE Cloud Shell и введите «Создать среду 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?
Это должно дать вам несколько подсказок, как это сделать. Ниже приведен пример подсказки, которую мы получили, и которая должна быть похожа на вашу:

Давайте последуем этому совету и вынесем наши данные в файл 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 Collection
Следующий шаг — отказаться от локального JSON-списка в оперативной памяти, который мы используем для хранения сессий, и подключить наше приложение к коллекции сессий в базе данных Firestore, которую мы создали в начале этого практического занятия.
Оставьте файл 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 .

Вы можете запрашивать данные с других 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. В результате файл index.html уже существует, и вам нужно просто заменить его содержимое новым файлом, сгенерированным здесь. Code Assist также упоминает о необходимости импортировать render_template в файл app.py
Сохраните код веб-приложения в файл index.html и не забудьте поместить этот файл в папку templates .
Запустите приложение локально.
Давайте теперь запустим приложение локально, чтобы проверить, соответствуют ли его требования исходным данным.
Убедитесь, что локальный Flask-сервер по-прежнему запущен и не выдает никаких ошибок. В случае возникновения ошибок устраните их и запустите сервер.
После запуска приложения перейдите по главной ссылке. Там должен отобразиться файл 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)
Это действительно так, поскольку идентификатор сессии был некорректным в третьем тесте, и категории с именем 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?
Хорошо, что вы спросили, потому что мы, к сожалению, забыли выключить флаг отладки.

Как указано, отключите отладку и обратитесь за помощью в 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 Вас также могут попросить включить API Google Cloud, такие как Artifact Registry, Cloud Build и Cloud Run, и предоставить разрешение на создание репозитория Artifact Registry. Пожалуйста, предоставьте это разрешение.
Процесс развертывания займет около 2 минут, поэтому, пожалуйста, наберитесь терпения.
После успешного развертывания вы увидите URL-адрес службы Cloud Run. Перейдите по этому общедоступному URL-адресу, и вы увидите то же самое веб-приложение, развернутое и успешно работающее.

Поздравляю, отлично справились!
15. (Необязательно) Используйте облачное логирование
Мы можем внедрить систему логирования в наше приложение, централизовав журналы приложения в одном из сервисов Google Cloud (Cloud Logging). Затем мы можем использовать функцию Observability Gemini для анализа записей в журналах.
Для этого нам сначала придётся использовать существующую библиотеку Python Cloud Logging от Google Cloud и применять её для записи информационных, предупреждающих или сообщений об ошибках (в зависимости от уровня серьёзности/серьёзности сообщения).
Давайте сначала попробуем обратиться с этим вопросом к Code Assist. Попробуйте ввести следующую команду:
How do I use the google-cloud-logging package in Python?
Вы должны получить ответ, содержащий некоторую информацию по этому вопросу, как показано ниже:

Давайте добавим в функцию, которая ищет сессии по категориям, сообщения для логирования.
Для начала добавьте пакет Python google-cloud-logging в файл requirements.txt .
Далее представлен фрагмент кода, демонстрирующий, как мы интегрировали код для реализации логирования:
...
from google.cloud import logging
...
app = Flask(__name__)
# Create a logger
logger = logging.Client().logger('my-log')
@app.route('/sessions/categories/<category>', methods=['GET'])
def get_sessions_by_category(category):
logger.log_text(f"Fetching sessions with category {category}")
sessions_by_category = [session for session in sessions.sessions if category in session['categories']]
logger.log_text(f'Found {len(sessions_by_category)} sessions with category {category}')
return jsonify(sessions_by_category)
# # Other App Routes
Разверните сервис в Cloud Run еще раз, используя ту же команду, что и в предыдущем разделе, и после развертывания выполните несколько вызовов к конечной точке /sessions/categories/<category> .
Перейдите в Cloud Console → Logs Explorer

...и вы сможете отфильтровать эти сообщения в журнале, как показано ниже:

Вы можете щелкнуть по любому из сообщений журнала, развернуть его, а затем нажать Explain this log entry , что позволит использовать Gemini для объяснения записи журнала. Обратите внимание, что если вы не включили Gemini для Google Cloud, вам будет предложено включить API Cloud AI Companion. Пожалуйста, сделайте это, следуя инструкциям.
Пример ответа приведён ниже:

16. Поздравляем!
Поздравляем, вы успешно разработали приложение с нуля, используя Gemini Code Assist на различных этапах жизненного цикла разработки программного обеспечения, включая проектирование, сборку, тестирование и развертывание.
Что дальше?
Посмотрите некоторые из этих практических занятий по программированию...
- Обзор Duet AI для разработчиков
- Использование Duet AI на протяжении всего жизненного цикла разработки программного обеспечения
- Стильный дизайн с Duet AI для разработчиков.