将 Python Flask Web 应用部署到 App Engine 柔性环境

摘要

在此 Codelab 中,您将学习如何将 Python Flask Web 应用部署到 App Engine 柔性环境。该示例应用允许用户上传人物头像的照片,并了解相应人员满意的可能性。该应用将 Google Cloud API 用于 Vision、Storage 和 Datastore。

关于 App Engine

Google App Engine 应用易于创建、易于维护,并可根据流量和数据存储需求的变化轻松扩缩。使用 App Engine 时,无需维护任何服务器。您只需上传自己的应用,即可开始使用。

App Engine 应用会根据传入的流量自动扩缩。负载平衡、微服务、授权、SQL 和 NoSQL 数据库、流量拆分、日志记录、搜索、版本控制、发布和回滚以及安全扫描都是原生支持的,并且高度可自定义。

App Engine 的柔性环境支持以下所有编程语言:C#、Go、Java、Node.js、PHP、Python 和 Ruby。App Engine 柔性环境在 Google Compute Engine 虚拟机上运行的 Docker 容器中运行您的应用。App Engine 的标准环境是适用于 Python 等特定语言的替代选项。App Engine 标准环境在限制性更强的沙盒环境中运行您的应用。如需了解详情,请参阅选择 App Engine 环境

学习内容

  • 如何将简单的 Web 应用部署到 App Engine 柔性环境
  • 如何访问适用于 Vision、Storage 和 Datastore 的 Google Cloud 客户端库
  • 如何使用 Google Cloud Console 和 Google Cloud SDK 管理各种云资源
  • 如何使用 Cloud Shell

所需条件

  • 熟悉 Python
  • 熟悉标准的 Linux 文本编辑器,例如 Vim、Emacs 或 Nano

创建项目

如果您还没有 Google 帐号(Gmail 或 Google Apps),则必须创建一个。登录 Google Cloud Platform Console (console.cloud.google.com) 并创建一个新项目:

请记住项目 ID,它在所有 Google Cloud 项目中都是唯一的名称(上述名称已被占用,您无法使用,抱歉!)。它稍后将在此 Codelab 中被称为 PROJECT_ID

结算

接下来,您需要在 Cloud Console 中启用结算功能,才能使用 Google Cloud 资源。

在此 Codelab 中运行仅花费几美元,但是如果您决定使用更多资源或继续让它们运行,费用可能更高。

Google Cloud Platform 的新用户有资格获享 $300 免费试用

虽然 Google Cloud 可以从笔记本电脑远程操作,但在此 Codelab 中,我们将使用 Google Cloud Shell,这是一个在云端运行的命令行环境。基于 Debian 的这款虚拟机加载了您需要的所有开发工具(gcloudpythonvirtualenvpip 等),它提供了一个持久的 5GB 主目录,并且在 Google Cloud 上运行,大大增强了网络性能和身份验证。这意味着在本 Codelab 中,您只需要一个浏览器(没错,它适用于 Chromebook)。

要激活 Google Cloud Shell,只需在开发者控制台中点击右上方的按钮(配置和连接到环境应该只需要片刻时间):

在连接到 Cloud Shell 后,您应该会看到自己已通过身份验证,并且相关项目已设置为您的项目 ID:

gcloud auth list
Credentialed accounts:
- <myaccount>@<mydomain>.com (active)
gcloud config list project
[core]
Project = <PROJECT_ID>

如果出于某种原因未设置项目,只需发出以下命令即可:

gcloud config set project <PROJECT_ID>

在查找您的 PROJECT_ID 吗?请查看您在设置步骤中使用的项目 ID,或在控制台信息中心内查找项目 ID:

在 Cloud Shell 的命令行中,运行以下命令以克隆 GitHub 代码库:

git clone https://github.com/GoogleCloudPlatform/python-docs-samples.git

将目录更改为 python-docs-samples/codelabs/flex_and_vision

cd python-docs-samples/codelabs/flex_and_vision

您必须使用以下命令来启用这些 API,然后我们才能开始使用 Vision API、Storage API 和 Datastore API:

gcloud services enable vision.googleapis.com
gcloud services enable storage-component.googleapis.com
gcloud services enable datastore.googleapis.com

要向 Vision API、Storage API 和 Datastore API 发出请求,您需要服务帐号凭据。您可以使用 gcloud 工具从项目中生成服务帐号凭据。

为您的 PROJECT_ID 设置环境变量,将 [YOUR_PROJECT_ID] 替换为您自己的项目 ID:

export PROJECT_ID=[YOUR_PROJECT_ID]

在本地测试时,需要创建用于访问 Google Cloud API 的服务帐号:

gcloud iam service-accounts create codelab \
  --display-name "My Codelab Service Account"

为新创建的服务帐号授予适当的权限:

gcloud projects add-iam-policy-binding ${PROJECT_ID} \
--member serviceAccount:codelab@${PROJECT_ID}.iam.gserviceaccount.com \
--role roles/owner

创建服务帐号后,请创建服务帐号密钥:

gcloud iam service-accounts keys create ~/key.json \
--iam-account codelab@${PROJECT_ID}.iam.gserviceaccount.com

此命令会生成一个服务帐号密钥,该文件存储在主目录中名为 key.json 的 JSON 文件中。

使用生成的密钥的绝对路径,在 Cloud Shell 中为服务帐号密钥设置环境变量:

export GOOGLE_APPLICATION_CREDENTIALS="/home/${USER}/key.json"

您可以详细了解如何对 Vision API 进行身份验证

启动虚拟环境并安装依赖项

使用 virtualenv 创建名为 env 的独立 Python 3 环境:

virtualenv -p python3 env

输入新创建的名为 envvirtualenv

source env/bin/activate

使用 piprequirements.txt 文件中为项目安装依赖项:

pip install -r requirements.txt

requirements.txt 文件是项目所需的软件包依赖项列表。以上命令会将所有这些列出的软件包依赖项下载到 virtualenv

创建 App Engine 应用

接下来,使用以下命令创建 App Engine 实例:

gcloud app create

创建存储分区

首先,将环境变量 CLOUD_STORAGE_BUCKET 设置为等于您的 PROJECT_ID 的名称。(为方便起见,通常建议将您的存储分区命名为 PROJECT_ID。)

export CLOUD_STORAGE_BUCKET=${PROJECT_ID}

我们的应用使用了 Cloud Storage 存储分区,您需要使用名为 gsutil 的工具通过 Cloud Shell 创建该存储分区。运行以下命令,这将创建一个与 PROJECT_ID 同名的存储分区。

gsutil mb gs://${PROJECT_ID}

运行应用

python main.py

应用启动后,点击 Cloud Shell 工具栏中的“网络预览”图标 ,然后选择“在端口 8080 上预览”。

您的浏览器会打开一个标签页,并连接到您刚启动的服务器。您应会看到类似下图的界面:

2017 年 2 月 23 日晚上 7.22.50 的屏幕截图

请尝试上传包含人物面孔的照片。点击选择文件按钮,从计算机中选择图片,然后点击提交

上传照片后,您应该会看到如下内容:

2017 年 2 月 23 日晚上 7.32.08 屏幕截图

示例代码布局

该示例采用以下布局:

templates/
  homepage.html   /* HTML template that uses Jinja2 */
app.yaml          /* App Engine application configuration file */
main.py           /* Python Flask web application */
requirements.txt  /* List of dependencies for the project */

main.py

此 Python 文件是一个 Flask Web 应用。该应用允许用户提交照片(最好是面孔),这些照片存储在 Cloud Storage 中,并使用 Cloud Vision API 的人脸检测功能进行分析。每张照片的关键信息都存储在 Datastore(Google Cloud Platform 的 NoSQL 数据库)中,用户每次访问网站时都会访问数据库中。

此应用使用适用于 Cloud Storage、Datastore 和 Vision 的 Google Cloud Platform 客户端库。借助这些客户端库,您可以轻松地使用自己喜欢的编程语言访问 Cloud API。

我们来看一下代码的一些关键代码段。

顶部的 imports 部分用于导入代码所需的各种软件包。以下是我们导入适用于 Datastore、Storage 和 Vision 的 Google Cloud 客户端库的方式:

from google.cloud import datastore
from google.cloud import storage
from google.cloud import vision

以下代码展示了当用户访问网站的根网址时会发生什么情况。我们创建一个 Datastore 客户端对象,用于访问 Datastore 客户端库。然后,我们在 Datastore 上查询 Faces 种类的实体。最后,我们呈现 HTML 模板,将我们从 Datastore 中提取的 image_entities 作为变量传入。

@app.route('/')
def homepage():
    # Create a Cloud Datastore client.
    datastore_client = datastore.Client()

    # Use the Cloud Datastore client to fetch information from Datastore about
    # each photo.
    query = datastore_client.query(kind='Faces')
    image_entities = list(query.fetch())

    # Return a Jinja2 HTML template and pass in image_entities as a parameter.
    return render_template('homepage.html', image_entities=image_entities)

我们来看看实体如何保存到 Datastore。Datastore 是 Google Cloud 的 NoSQL 数据库解决方案。数据存储在名为“实体”的对象中。系统会为每个实体分配一个唯一的标识,此键可以使用种类键名字符串创建。种类是一种组织存储分区,用于决定实体所属的类型。例如,我们可能希望为照片、人物和动物设置种类

每个实体都可以包含多个开发者定义的属性,这些属性可以具有多种类型的值,包括整数、浮点数、字符串、日期或二进制数据。

    # Create a Cloud Datastore client.
    datastore_client = datastore.Client()

    # Fetch the current date / time.
    current_datetime = datetime.now()

    # The kind for the new entity.
    kind = 'Faces'

    # The name/ID for the new entity.
    name = blob.name

    # Create the Cloud Datastore key for the new entity.
    key = datastore_client.key(kind, name)

    # Construct the new entity using the key. Set dictionary values for entity
    # keys blob_name, storage_public_url, timestamp, and joy.
    entity = datastore.Entity(key)
    entity['blob_name'] = blob.name
    entity['image_public_url'] = blob.public_url
    entity['timestamp'] = current_datetime
    entity['joy'] = face_joy

    # Save the new entity to Datastore.
    datastore_client.put(entity)

您可以通过与 Datastore 类似的方式以编程方式访问 Storage 和 Vision 客户端库。您可以使用 vimemacsnano 自行打开 main.py 文件,以浏览所有示例代码。

如需详细了解 Flask,请访问 http://flask.pocoo.org/

如需详细了解客户端库,请访问 https://googlecloudplatform.github.io/google-cloud-python/

home.html

Flask Web 框架利用 Jinja2 作为模板引擎。这样,我们就可以在网页呈现后将变量和表达式从 main.py 传入 homepage.html 中,并用相应的值替换它们。

如需详细了解 Jinja2,请访问 http://jinja.pocoo.org/docs/2.9/template/

此 Jinja2 HTML 模板显示一个表单,供用户将照片提交到数据库。它还会显示之前提交的每个图片及其文件名、上传日期/时间,以及 Vision API 检测到的人脸的可能性。

homepage.html

<h1>Google Cloud Platform - Face Detection Sample</h1>

<p>This Python Flask application demonstrates App Engine Flexible, Google Cloud
Storage, Datastore, and the Cloud Vision API.</p>

<br>

<html>
  <body>
    <form action="upload_photo" method="POST" enctype="multipart/form-data">
      Upload File: <input type="file" name="file"><br>
      <input type="submit" name="submit" value="Submit">
    </form>
    
  </body>
</html>

App Engine 柔性环境使用名为 app.yaml 的文件来描述应用的部署配置。如果该文件不存在,App Engine 将尝试猜测部署配置。不过,最好提供此文件。

接下来,您可以使用自己选择的 vimnanoemacs 编辑器修改 app.yaml。我们将使用 nano 编辑器:

nano app.yaml

app.yaml

runtime: python
env: flex
entrypoint: gunicorn -b :$PORT main:app

runtime_config:
    python_version: 3

env_variables:
    CLOUD_STORAGE_BUCKET: <your-cloud-storage-bucket>

这是部署 Python 3 App Engine 柔性环境应用所需的基本配置。如需详细了解如何配置 App Engine,请点击此处

打开 app.yaml 后,将 < your-cloud-storage-bucket > 替换为您的 Cloud Storage 存储分区的名称。(如果您忘记了 Cloud Storage 存储分区的名称,请复制 Qwiklabs 中的 GCP 项目 ID,ID 相同)。env_variables 部分用于设置部署应用后在 main.py 中使用的环境变量。

您现在可以使用 Ctrl + x 关闭保存功能并在 nano 中关闭该文件,系统会提示您:

2017 年 2 月 17 日下午 4.47.12 的屏幕截图

输入字母 y,然后再次按 ENTER 键以确认以下提示的文件名:

2017 年 2 月 24 日下午 4.18.23 屏幕截图

使用 gcloud 在 App Engine 上部署应用:

gcloud app deploy

部署应用后,您可以在网络浏览器中打开网址 https://< PROJECT_ID >.appspot.com 来访问该应用。

摘要

在此步骤中,您将设置一个 Python Web 应用并将其部署到 App Engine 柔性环境。

您已了解如何编写和部署您的第一个 App Engine 柔性环境 Web 应用!

清理

为避免系统因本快速入门中使用的资源向您的 Google Cloud Platform 帐号收取费用,请执行以下操作:

  • 访问 Cloud Platform Console
  • 选择要关停的项目,然后点击顶部的“删除”,此操作会将该项目安排删除。

了解详情

许可

此作品已获得 Creative Commons Attribution 2.0 通用许可授权。