Draw a Website:使用 Gemini 模型将想象力转化为网站!

1. 简介

在 Web 开发领域,将设计概念转化为可正常运行的网站既耗时又复杂。不过,随着 Gemini 等生成式 AI 模型的出现,这一流程变得越来越精简,也越来越容易上手。我们将打造一款专门用于将手绘线框图转换为网站代码的解决方案。借助这款强大的工具,设计人员和开发者都能以前所未有的轻松高效地将网站创意变为现实。

在本实验中,我们将构建一个 Web 应用,让用户能够使用 Vertex AI 的生成式 AI 模型(Gemini 1.5 Flash、Gemini 1.5 Pro 等)根据用户输入的线框图和提示生成网站代码(HTML、CSS 和 JavaScript)。该应用将使用热门的 Python Web 框架 Flask 构建,并使用 Vertex AI 客户端库与生成式模型服务进行交互。

构建内容

完成本实验后,您将获得一个可根据线框和提示生成图片的 Web 应用。您还将更好地了解如何使用 Vertex AI 的生成式 AI 模型。

您的 Web 应用将如下所示:

5bccb261882c1bf0.png

应用流程

  1. 上传手绘线框图:用户可以将手绘线框图的图片上传到应用中。
  2. 选择模型:该应用提供了一系列针对不同设计风格优化的预训练 Gemini 模型。
  3. 提供提示:用户可以选择性地提供文本提示来引导模型生成内容。
  4. 生成网站代码:应用将线框图和提示发送给 Gemini,后者会生成相应的网站代码。
  5. 显示结果:生成的代码会显示在应用的回答页面中。

我们将首先讨论线框和提示的基础知识,以及如何使用它们生成网站代码。然后,我们将逐步介绍如何构建 Web 应用,包括如何处理用户输入、生成回答和显示结果。

2. 准备工作

  1. Google Cloud Console 的项目选择器页面上,选择或创建一个 Google Cloud 项目
  2. 确保您的 Google Cloud 项目已启用结算功能。了解如何检查项目是否已启用结算功能
  3. 您将使用 Cloud Shell,它是在 Google Cloud 中运行的命令行环境。如需访问该工具,请点击 Google Cloud 控制台顶部的“激活 Cloud Shell”。

1829c3759227c19b.png

  1. 连接到 Cloud Shell 后,您可以使用以下命令检查自己是否已通过身份验证,以及项目是否已设置为您的项目 ID:
gcloud auth list
  1. 在 Cloud Shell 中运行以下命令,以确认 gcloud 命令了解您的项目。
gcloud config list project
  1. 如果项目未设置,请使用以下命令进行设置:
gcloud config set project <YOUR_PROJECT_ID>
  1. 确保已启用以下 API:
  • Cloud Run
  • Vertex AI

除了使用 gcloud 命令之外,您还可以通过此链接在控制台中完成操作。如需了解 gcloud 命令和用法,请参阅文档

3. 第 1 步:引导启动 Python Cloud Run Web 应用

我们将先从 Cloud Shell 创建 Python Cloud Run Web 应用模板。

前往 Cloud Shell 终端,然后点击“打开编辑器”按钮。b16d56e4979ec951.png

确保 Cloud Code 项目已在 Cloud Shell 编辑器的左下角(状态栏)中设置,如下图中突出显示的那样,并且已设置为已启用结算的有效 Google Cloud 项目。在系统提示时点击授权

f5003b9c38b43262.png

点击状态栏中的活跃项目,然后等待 Cloud Code 弹出式窗口打开。在弹出式窗口中,选择“New Application”。70f80078e01a02d8.png

从应用列表中选择 Cloud Run 应用

39abad102a72ae74.png

对于第 2/2 页,请选择 Python Flask 模板:

a78b3a0311403ad.png

根据需要提供项目名称(例如“amazing-gemini-app”),然后点击确定

4d8f77279d9509cb.png

系统随即会打开您刚刚设置的新项目的模板。

e85a020a20d38e17.png

使用 Google Cloud Shell 引导启动 Web 应用就是这么简单。

4. 第 2 步:构建前端

为此,我们需要一个 HTML 页面。该页面将包含用于定义 Web 应用界面的代码。它包含一个表单,用户可以在其中上传手绘线框图、选择生成模型并提供文本提示。提交表单后,系统会在另一个标签页中显示结果。

复制以下代码,并替换 templates 文件夹中的 index.html 文件:

<!DOCTYPE html>
<html>
<head>
   <title>Draw a Website</title>
   <style>
       body {
           font-family: sans-serif;
           display: flex;
           justify-content: center;
           align-items: center;
           min-height: 100vh; /* Ensure form is centered vertically */
           background-color: #f4f4f4;
       }
       .container {
           background-color: white;
           padding: 30px;
           border-radius: 8px;
           box-shadow: 0 2px 5px rgba(0, 0, 0, 0.1);
           text-align: center;
       }
       h2 {
           text-align: center;
           margin-bottom: 20px;
       }
       input[type="file"], textarea, select {
           width: 100%;
           padding:10px;
           margin-bottom: 15px;
           border: 1px solid #ccc;
           border-radius: 4px;
           box-sizing: border-box;
       }
       button {
           background-color: #4CAF50;
           color: white;
           padding: 12px 20px;
           border: none;
           border-radius: 4px;
           cursor: pointer;
       }
   </style>
</head>
<body>
   <div class="container">
       <h2>Draw a Website</h2>
       <form action="/response" target="_blank" method="post" enctype="multipart/form-data">
           <input type="file" id="image-upload" name="image-upload" accept=".png, .jpg, .jpeg">
           <select name="model">
               <option value="gemini-1.5-flash-001">Gemini 1.5 Flash</option>
               <option value="gemini-1.5-pro-001">Gemini 1.5 Pro</option>
               <option value="gemini-1.0-pro-vision-001">Gemini 1.0 Pro Vision</option>
               </select>
           <textarea name="prompt" placeholder="Write your prompt here. For example: 'Convert this drawing into an html page'">Convert this drawing into an html page</textarea>
           <button type="submit">Submit</button>
       </form>
   </div>
</body>
</html>

当用户与应用互动时,会发生以下操作:

  1. 用户选择线框图像、选择模型并输入提示。
  2. 当用户点击“提交”按钮时,表单数据(图片、模型和提示)会使用 HTTP POST 方法发送到 /response 网址。
  3. 服务器端代码(在 app.py 中实现)会处理表单数据,并使用指定的模型和提示生成响应。
  4. 生成的回答会显示在新标签页中。

现在,我们已准备好 Web 应用的前端部分。

5. 第 3 步:构建后端(生成式 AI)

我们来编写此 Web 应用的主要部分。app.py 文件,用于接收用户输入的图片、模型选择和提示,并将其转换为网站代码。

复制 app.py 的完整代码:

# Import the necessary libraries.
import os
import random
from flask import (
    Flask,
    render_template,
    request,
    redirect
)

import vertexai
from vertexai.generative_models import (
    GenerativeModel,
    Image
)

# Initialize the Flask app.
app = Flask(__name__)
app.config['MAX_CONTENT_LENGTH'] = 16 * 1024 * 1024  # 16 MB per image

# TODO: Replace "YOUR_PROJECT_ID" before running
# Initialize the Vertex AI client library.
vertexai.init(project="YOUR_PROJECT_ID", location="us-central1")

# Define a function to generate response from a wireframe and a prompt.
def generate(wireframe, model, prompt):
    '''Generates a response from a wireframe and a prompt.
    Args:
    wireframe: The wireframe image.
    model: The generative model to use.
    prompt: The prompt to use.
    Returns:The generated response.
    '''
    # Create a GenerativeModel object.
    model = GenerativeModel(model)

    # Create a list of contents to pass to the model.
    contents = [
        wireframe,
        prompt
    ]
   
    # Generate the response.
    responses = model.generate_content(
        contents=contents,
        stream=True,
    )

    # Concatenate the response text.
    response = ""
    for res in responses:
        response += res.text.strip()
   
    # Return the generated response.
    return response

# Define the home page route.
@app.route('/', methods=['GET'])
def index():
    '''Renders the home page.
    Returns:The rendered template.
    '''
    return render_template('index.html')

# Define the response route.
@app.route('/response', methods=['GET', 'POST'])
def response():
    '''Handles the response to the user's input.
    Returns:The rendered template.
    '''
    # If the request is a POST request, process the form data.
    if request.method == 'POST':
        # Get the uploaded image from the request.
        uploaded_image = request.files['image-upload']
       
        # Convert the uploaded image to a wireframe image.
        wireframe = Image.from_bytes(uploaded_image.read())

        # Get the model and prompt from the request.
        model = request.form['model']
        prompt = request.form['prompt']
       
        # Generate the response and render the response.
        try:
            response = generate(wireframe, model, prompt)
            response = response.replace("```html", "").replace("```", "").strip()
            return response
        except ValueError as e:
            raise e
   
    # If the request is a GET request, redirect to the home page.
    else:
        return redirect('/')

# Run the app.
if __name__ == '__main__':
    # Get the server port from the environment variables.
    server_port = os.environ.get('PORT', '8080')

    # Run the app.
    app.run(debug=False, port=server_port, host='0.0.0.0')

以下是代码的本质作用:

  1. 此代码会导入应用所需的库:

Flask:适用于 Python 的轻量级 Web 框架。

os:用于与操作系统交互。

random:用于生成随机数。

vertexai:Vertex AI 客户端库。

GenerativeModel 和 Image:Vertex AI 生成式模型库中的类。

  1. 初始化 Flask 应用:

接下来,它会初始化 Flask 应用,并将上传图片的允许大小上限设置为 16 MB。

  1. 初始化 Vertex AI 客户端

它使用指定的项目 ID 和位置初始化 Vertex AI 客户端库。请务必将 YOUR_PROJECT_ID 替换为您的项目 ID。

  1. 定义生成函数

此函数将线框图片、生成模型和提示作为输入。然后,使用指定的模型和提示生成网站 HTML。生成的回答以字符串形式返回。

  1. 定义首页路由

此函数定义了首页路由。当用户访问应用的根网址时,系统会调用此函数。它会呈现 index.html 模板,即应用的首页。

  1. 定义响应路由

此函数定义了响应路由。当用户提交首页上的表单时,系统会调用此函数。它会处理上传的图片、模型和提示,然后生成网站代码。生成的回答会显示在新标签页中。

  1. 运行应用

这部分代码用于检查脚本是否作为主程序运行。如果存在,则从环境变量中获取服务器端口,并在指定端口上运行应用。

6. 第 4 步:准备依赖项和 Dockerfile

确保您在 requirements.txt 文件中包含以下依赖项:

Flask==2.3.3
requests==2.31.0
debugpy # Required for debugging.
google-cloud-aiplatform>=1.38

将 Dockerfile 内容替换为以下内容:

# Python image to use.
FROM python:3.11-slim

# Set the working directory to /app
WORKDIR /app

# copy the requirements file used for dependencies
COPY requirements.txt .

# Install any needed packages specified in requirements.txt
RUN pip install -r requirements.txt

# Copy the rest of the working directory contents into the container at /app
COPY . .

# Run app.py when the container launches
ENTRYPOINT ["python", "app.py"]

7. 第 5 步:部署 Web 应用

现在,我们已经创建了应用组件,接下来部署应用。

前往 Cloud Shell 终端,确保当前项目已配置为您的有效项目。如果不是,请使用 gcloud configure 命令设置项目 ID:

gcloud config set project [PROJECT_ID]

然后,按顺序逐一输入以下命令:

cd draw-a-website
gcloud run deploy --source .

系统会提示您输入服务名称,例如“draw-website”。选择与“us-central1”区域对应的数字。当系统询问您是否要允许未经身份验证的调用时,请说“y”。请注意,我们在此处允许未经身份验证的访问,因为这是一个演示应用。建议为企业和生产应用使用适当的身份验证。

部署完成后,您应该会获得类似于以下内容的链接:

**https://draw-website-*****eua-uc.a.run.app/

接下来,测试您的应用:

6ca7b67b7fce97de.png

8. 清理

为避免系统因本 Codelab 中使用的资源向您的 Google Cloud 账号收取费用,请按照以下步骤操作:

  1. 在 Google Cloud 控制台中,前往管理资源页面。
  2. 在项目列表中,选择要删除的项目,然后点击删除
  3. 在对话框中输入项目 ID,然后点击关停以删除项目。
  4. 或者,您也可以在控制台中前往 Cloud Run,选择刚刚部署的服务,然后将其删除。

9. 恭喜

恭喜!您已成功构建了一个基于 Python Flask 且部署在 Cloud Run 上的快速 Web 应用,该应用可将绘画转换为网站。点击此处可查看完整代码库。这款“绘制网站”应用展示了 Gemini 在简化 Web 开发流程方面的变革性力量。借助 AI,我们可以帮助设计师和开发者更快、更准确、更富创意地创建网站。随着生成式 AI 模型的不断发展,我们期待在未来看到更多突破性的应用。