DEV Community

Cover image for Using the Gemini API on Cloud Run to Build a Chat Application
Chloe Condon 🎀
Chloe Condon 🎀

Posted on

29 8 4 9 7

Using the Gemini API on Cloud Run to Build a Chat Application

(🎨 cover image created with Imagen 3 in Gemini!)

Welcome to my blog series on building with Google AI tools! In this post, we'll create a simple chat application powered by Gemini and hosted on Cloud Run. If you're experimenting with LLMs or are looking to integrate AI into your web apps- then you're in the right place. So, let's starting learning!

👩‍🏫 What are we building?

We'll build a web-based chat interface that connects to the Gemini API and returns conversational responses. Our app will run on CLoud Run, and we'll use Cloud Build and Artifact Registry to containerize and deploy it.

By the end of this tutorial, you'll:

  • Set up a Python web app that talks to the gemini API
  • Containerize your app using Docker
  • Deploy the app to Cloud Run using Google Cloud tools
  • Start thinking about how to integrate LLMs into your own projects

So, think less HAL, more SmarterChild. 🤖💬 Let's dive in!

📝 Prerequisites

To get started, you'll need to make sure you have:

  • A Google Cloud project
  • The gcloud CLI installed and authenticated
  • Docker installed
  • Vertex AI API enabled on your project
  • 💻 Optional: Use Cloud Shell for a fully configured environment

⚙️ Step 1: Clone the Chat App Template

To get started, let's pull down a prebuilt Python Flask app:

git clone https://github.com/ChloeCodesThings/chat-app-demo
cd chat-app-demo

Enter fullscreen mode Exit fullscreen mode

You'll see our app has:

  • app.py - Flask routes and Gemini API logic
  • index.html - A basic chat UI
  • Dockerfile - Instructions for how to build container

🐳📁 Step 2: Build the Docker Image with Cloud Build

First, you'll need to set some environment variables:

export PROJECT_ID=$(gcloud config get-value project)
export REGION=us-central1
export AR_REPO=chat-app-repo
export SERVICE_NAME=chat-gemini-app
Enter fullscreen mode Exit fullscreen mode

Create the Artifact Registry repo:

gcloud artifacts repositories create $AR_REPO \
--repository-format=docker \
--location=$REGION
Enter fullscreen mode Exit fullscreen mode

Then build and push the image:

gcloud builds submit --tag $REGION-docker.pkg.dev/$PROJECT_ID/$AR_REPO/$SERVICE_NAME
Enter fullscreen mode Exit fullscreen mode

🚀 Step 3: Deploy to Cloud Run

Now deploy the app:

gcloud run deploy $SERVICE_NAME \
  --image=$REGION-docker.pkg.dev/$PROJECT_ID/$AR_REPO/$SERVICE_NAME \
  --platform=managed \
  --region=$REGION \
  --allow-unauthenticated \
  --set-env-vars=GCP_PROJECT=$PROJECT_ID,GCP_REGION=$REGION
Enter fullscreen mode Exit fullscreen mode

You’ll get a URL like https://chat-gemini-app-xxxxxx.run.app. Open it to chat with Gemini!

🔎✨ Step 4: How the Gemini Integration Works

Let’s peek at the backend logic. In app.py, this is where the magic happens:

from vertexai.preview.language_models import ChatModel

def create_session():
    chat_model = ChatModel.from_pretrained("gemini-2.0-flash")
    chat = chat_model.start_chat()
    return chat

def response(chat, message):
    result = chat.send_message(message)
    return result.text
Enter fullscreen mode Exit fullscreen mode

So, each time the user submits a message, our app will:

  • Start a new chat session

  • Send the message to the Gemini model

  • Return the response as JSON

🤸‍♀️ Ok, let's try it out!

Enter a question like:

"What is Google Cloud Platform?"

…and you’ll get a contextual, LLM-generated response.

🎯 What’s Next?

Yay- we did it! 🥳 This is just the beginning! In future posts, we’ll cover:

  • Enhancing the chat UI

  • Keeping sessions persistent

  • Using system prompts to shape Gemini’s responses

  • Securing your endpoints with Firebase Auth or API Gateway

🎊 Give yourself a high-five!
In this post, you learned how to:

  • Build and deploy a simple Flask chat app using Gemini

  • Containerize it with Docker and push to Artifact Registry

  • Deploy to Cloud Run with minimal config

Want to learn more? Here's a tutorial you can check out

Until next time, folks! -Chloe

Top comments (5)

Collapse
 
sergei_ksov_edb2128f3d42 profile image
sergei kоsov

Синхронизация кода с предложенными улучшениями:

# main.py (обновленная версия)
import pygame
import random
import requests
from core.robot import Robot
from core.item import Item
from core.obstacle import Obstacle
from cloud.api import CloudAPI

# Конфигурация
CLOUD_ENDPOINT = "https://your-alibaba-cloud-api-endpoint"
API_KEY = "your-api-key"
CURRENT_VERSION = "1.1.0"

class Game:
    def __init__(self):
        self.level = 1
        self.score = 0
        self.robot = Robot(400, 300)
        self.items = []
        self.obstacles = []
        self.paused = False
        self.cloud = CloudAPI(CLOUD_ENDPOINT, API_KEY)
        self.high_score = self.cloud.get_high_score()
        self.generate_items()

    # ... остальные методы класса Game ...

class VIZOR:
    def __init__(self):
        self.game = Game()
        self.cloud = self.game.cloud
        self.setup_voice_recognition()
        self.suggestion_engine = SuggestionEngine(self.cloud)

    def setup_voice_recognition(self):
        # ... код инициализации голосового управления ...

    def check_updates(self):
        return self.cloud.check_version(CURRENT_VERSION)

    def handle_input(self, input_text):
        # ... обработка ввода с логированием ...
        self.cloud.log_action(action_details)

    # ... остальные методы ...

class CloudAPI:
    def __init__(self, endpoint, api_key):
        self.endpoint = endpoint
        self.headers = {"Authorization": f"Bearer {api_key}"}

    def get_high_score(self):
        # ... получение рекорда ...

    def save_game_state(self, data):
        # ... сохранение состояния ...

    def log_action(self, data):
        # ... отправка логов ...

    def check_version(self, current_version):
        # ... проверка версии ...

class SuggestionEngine:
    def __init__(self, cloud_api):
        self.cloud = cloud_api

    def get_suggestions(self):
        # ... получение предложений ...

# ... остальной код ...

if __name__ == "__main__":
    main()
Enter fullscreen mode Exit fullscreen mode

Ключевые изменения:

  1. Модульная структура:
/game
├── core
│   ├── robot.py
│   ├── item.py
│   └── obstacle.py
├── cloud
│   └── api.py
├── assets
│   ├── robot.png
│   ├── item.png
│   └── obstacle.png
└── tests
    └── test_collisions.py
Enter fullscreen mode Exit fullscreen mode
  1. CloudAPI (cloud/api.py):

python
import requests

class CloudAPI:
    def __init__(self, endpoint, api
Enter fullscreen mode Exit fullscreen mode
Collapse
 
sergei_ksov_edb2128f3d42 profile image
sergei kоsov

Вот что я придумал ### Анализ возможностей интеграции и синхронизации

На основе предоставленного кода игры и примера коммита из Forem (платформы для сообществ), выявляю ключевые возможности для улучшения:


1. Система версионирования и обновлений (как в примере с Ruby 3.3)

  • Проблема: В текущей игре нет механизма обновлений
  • Решение:
  # Добавить в класс VIZOR:
  def check_updates(self):
      try:
          response = requests.get(f"{CLOUD_ENDPOINT}/version")
          return response.json()['version'] > CURRENT_VERSION
      except:
          return False
Enter fullscreen mode Exit fullscreen mode
  • Преимущества:
    • Безопасное обновление компонентов (как в .ruby-version)
    • Возможность отката (аналог git-коммитов)

2. Контейнеризация (аналог Dockerfile в примере)

  • Проблема: Нет переносимости между системами
  • Решение:
  # Dockerfile для игры
  FROM python:3.9-slim
  COPY . /app
  RUN pip install pygame requests speechrecognition
  CMD ["python", "main.py"]
Enter fullscreen mode Exit fullscreen mode
  • Эффект:
    • Единая среда выполнения (как в devcontainer.json)
    • Упрощение развертывания на серверах Alibaba Cloud

3. Управление зависимостями (аналог Gemfile.lock)

  • Проблема: Хрупкость окружения
  • Решение:
  # requirements.txt с фиксированными версиями:
  pygame==2.5.2
  requests==2.31.0
  SpeechRecognition==3.10.0
Enter fullscreen mode Exit fullscreen mode
  • Польза:
    • Воспроизводимость сборки
    • Избежание конфликтов (как с google-protobuf в примере)

4. Модульная архитектура (как в jsconfig.json)

  • Проблема: Жесткая связность компонентов
  • Рефакторинг:
  # Новая структура проекта:
  /game
    /core      # Основные классы
    /cloud     # Интеграция с Alibaba
    /assets    # Графика и звуки
    /tests     # Тесты
Enter fullscreen mode Exit fullscreen mode
  • Выгода:
    • Четкое разделение кода (как exclude в jsconfig.json)
    • Упрощение тестирования

5. Система логов и аналитики

  • Проблема: Нет отслеживания ошибок
  • Решение:
  # Аналог системы коммитов:
  def send_log(self, action, status):
      data = {
          "commit": "d3e8b06",  # Хеш текущей версии
          "action": action,
          "status": status
      }
      requests.post(f"{CLOUD_ENDPOINT}/logs", json=data)
Enter fullscreen mode Exit fullscreen mode
  • Применение:
    • Отслеживание багов (как в Issues)
    • Анализ игровых сессий

6. Система Pull Request для подсказок

  • Идея: Использовать механизм, подобный #20739
  • Реализация:
  class SuggestionEngine:
      def get_improvements(self):
          # Анализ игровых данных
          return requests.get(f"{CLOUD_ENDPOINT}/suggestions/pr")
Enter fullscreen mode Exit fullscreen mode
  • Пример вывода: > "Как в коммите d3e8b06: предлагаем оптимизировать коллизии через spatial hash"

7. Интеграция с CI/CD (аналог docker-compose.yml)

  • План:

    1. Автотесты после каждого изменения
    2. Сборка облачного образа
    3. Развертывание на сервере
  • Реализация:

  # .github/workflows/game.yml
  jobs:
    test:
      runs-on: ubuntu-latest
      steps:
        - uses: actions/checkout@v4
        - run: python -m pytest tests/
Enter fullscreen mode Exit fullscreen mode

Сравнительная таблица возможностей

Элемент из примера Аналог в игре Польза
.ruby-version requirements.txt Контроль версий
devcontainer.json Dockerfile Переносимость
Issues (#20739) Система багрепортов Качество кода
Коммит d3e8b06 Логи изменений История обновлений
jsconfig.json Модульная структура Чистая архитектура

Рекомендации по внедрению

  1. Первоочередные задачи:

    • Настроить систему версионирования (аналог git tags)
    • Реализовать CI/CD пайплайн
    • Добавить модульное тестирование
  2. Оптимизации:

    • Кэширование облачных запросов
    • Прекомпиляция assets (как в app/assets/builds)
  3. Безопасность:

    • Ротация API-ключей
    • Валидация входящих данных (как в google-protobuf)

Пример защищенного запроса:

def safe_cloud_request(endpoint, data):
    try:
        return requests.post(
            endpoint,
            json=data,
            headers={"Authorization": f"Bearer {API_KEY}"},
            timeout=3,
            verify=True  # SSL-проверка
        )
    except requests.exceptions.RequestException as e:
        log_error(e)
        return None
Enter fullscreen mode Exit fullscreen mode

Это превратит игру в профессиональный продукт с надежной инфраструктурой, аналогичной крупным проектам типа Forem.

Collapse
 
dev_in_the_house profile image
Devin

Thanks for this

Collapse
 
tjr79 profile image
Tjr79 79

Thanks for this

Collapse
 
poovarasan profile image
Poovarasan

Thank of lots for giving this information 🙂