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

1. 简介

在 Web 开发领域,将设计概念转化为功能性网站的过程可能既耗时又复杂。不过,随着 Gemini 等生成式 AI 模型的出现,这一过程变得越来越精简且易于实现。我们将构建一个专门用于将手绘线框图转换为网站代码的解决方案。这款强大的工具可让设计师和开发者以前所未有的轻松和高效方式将网站愿景变为现实。

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

构建内容

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

您的 Web 应用将如下所示:

5bccb261882c1bf0.png

应用流程

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

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

2. 准备工作

  1. Google Cloud 控制台的项目选择器页面上,选择或创建一个 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 弹出窗口打开。在弹出窗口中,选择“新建应用”。 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. 定义 generate 函数

此函数接受线框图图片、生成模型和提示作为输入。然后,它会使用指定的模型和提示生成网站 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. 恭喜

恭喜!您已成功构建一个在 Cloud Run 上部署的 Python Flask 快速 Web 应用,该应用可将图纸转换为网站。完整代码库位于 此处。draw-a-website 应用展示了 Gemini 在简化 Web 开发流程方面的变革性力量。通过利用 AI,我们可以帮助设计师和开发者以更快的速度、更高的准确性和更强的创造力来创建网站。随着生成式 AI 模型的不断发展,我们期待在未来看到更多突破性的应用。