將 Python Flask 網頁應用程式部署至 App Engine 彈性環境

摘要

在本程式碼研究室中,您將瞭解如何將 Python Flask 網路應用程式部署至 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 環境」。

課程內容

  • 如何將簡單的網路應用程式部署至 App Engine 彈性環境
  • 如何存取 Vision、Storage 和 Datastore 適用的 Google Cloud 用戶端程式庫
  • 如何使用 Google Cloud 控制台和 Google Cloud SDK 管理各種雲端資源
  • 如何使用 Cloud Shell

軟硬體需求

  • 熟悉 Python
  • 熟悉標準 Linux 文字編輯器,例如 Vim、Emacs 或 Nano

建立專案

如果您還沒有 Google 帳戶 (Gmail 或 Google 應用程式),請先建立帳戶。登入 Google Cloud Platform 主控台 (console.cloud.google.com),然後建立新專案:

請記住專案 ID,這是所有 Google Cloud 專案中不重複的名稱 (上述名稱已遭占用,因此不適用於您,抱歉!)。本程式碼研究室稍後會將其稱為 PROJECT_ID

帳單

接著,您必須在 Cloud 控制台中啟用帳單,才能使用 Google Cloud 資源。

完成這項程式碼研究室的費用不應超過數美元,但如果您決定使用更多資源,或是將資源繼續執行,則可能會增加費用。

Google Cloud Platform 新使用者享有價值 $300 美元的免費試用期

雖然您可以透過筆電遠端操作 Google Cloud,但在本程式碼研究室中,我們將使用 Google Cloud Shell,這是可在雲端執行的指令列環境。這種以 Debian 為基礎的虛擬機器,搭載各種您需要的開發工具 (包括 gcloudpythonvirtualenvpip 等等),而且主目錄提供 5 GB 的永久儲存空間,並在 Google Cloud 上執行,大幅提升網路效能和驗證作業。也就是說,您只需要瀏覽器 (Chromebook 也可以) 就能完成本程式碼研究室。

如要啟用 Google Cloud Shell,只要在開發人員控制台中按一下右上方的按鈕即可 (系統應該只需要幾分鐘就能佈建及連線至環境):

連線至 Cloud Shell 後,您應會發現自己通過驗證,且專案已設為您的「PROJECT_ID」PROJECT_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,或在主控台資訊主頁中查詢:

在 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

開始使用 Vision、Storage 和 Datastore API 之前,請先使用下列指令啟用 API:

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

如要向 Vision、Storage 和 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

輸入新建立的 virtualenv,名稱為 env

source env/bin/activate

使用 piprequirements.txt 檔案安裝專案的依附元件:

pip install -r requirements.txt

requirements.txt 檔案是專案所需的套件依附元件清單。上述指令已將所有列出的套件依附元件下載至 virtualenv

建立 App Engine 應用程式

接著,使用下列指令建立 App Engine 執行個體:

gcloud app create

建立儲存空間 bucket

首先,請將環境變數 CLOUD_STORAGE_BUCKET 設為 PROJECT_ID 的名稱。(一般來說,建議您將值區命名為與 PROJECT_ID 相同,方便使用)。

export CLOUD_STORAGE_BUCKET=${PROJECT_ID}

我們的應用程式會使用 Cloud Storage bucket,您必須使用名為 gsutil 的工具,從 Cloud Shell 建立 bucket。執行下列指令,建立與 PROJECT_ID 同名的值區。

gsutil mb gs://${PROJECT_ID}

執行應用程式

python main.py

應用程式啟動後,按一下 Cloud Shell 工具列中的「網頁預覽」圖示 ,然後選擇「透過以下通訊埠預覽:8080」。

瀏覽器會開啟一個分頁,並連結至您剛剛啟動的伺服器。畫面應如下所示:

Screen Shot 2017-02-23 at 7.22.50 PM.png

請嘗試上傳含有人臉的相片。按一下「選擇檔案」按鈕,從電腦中選擇圖片,然後按一下「提交」

上傳相片後,畫面應如下所示:

Screen Shot 2017-02-23 at 7.32.08 PM.png

程式碼範例版面配置

程式碼範例的配置如下:

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 網頁應用程式。使用者可透過應用程式提交相片 (最好是臉部相片),這些相片會儲存在 Cloud Storage 中,並使用 Cloud Vision API 的臉部偵測功能進行分析。每張相片的相關重要資訊都會儲存在 Google Cloud Platform 的 NoSQL 資料庫 Datastore 中,使用者每次造訪網站時,系統都會存取這些資訊。

這個應用程式會使用 Google Cloud Platform 用戶端程式庫,存取 Storage、Datastore 和 Vision。這些用戶端程式庫可讓您使用偏好的程式設計語言輕鬆存取 Cloud API。

讓我們看看一些重要的程式碼片段。

頂端的匯入部分用於匯入程式碼所需的各種套件。以下是匯入 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/

homepage.html

Flask 網路架構會將 Jinja2 做為範本引擎。這樣我們就能將 main.py 中的變數和運算式傳遞至 homepage.html,並在網頁算繪完成後,以值取代這些變數和運算式。

如要進一步瞭解 Jinja2,請前往 http://jinja.pocoo.org/docs/2.9/templates/

這個 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 bucket 名稱。(如果忘記 Cloud Storage bucket 的名稱,請從 Qwiklabs 複製 GCP 專案 ID,兩者相同)。env_variables 區段會設定應用程式部署後,main.py 中使用的環境變數。

現在可以使用 (Ctrl + x) 鍵,在 nano 中儲存並關閉檔案,系統會顯示以下提示:

Screen Shot 2017-02-17 at 4.47.12 PM.png

輸入字母 y,然後再按一次 ENTER 鍵,確認下列提示的檔案名稱:

Screen Shot 2017-02-24 at 4.18.23 PM.png

使用 gcloud 將應用程式部署到 App Engine:

gcloud app deploy

應用程式部署完成後,您可以在網路瀏覽器中開啟網址 https://< PROJECT_ID >.appspot.com,即可造訪應用程式。

摘要

在這個步驟中,您設定了 Python 網頁應用程式,並將其部署至 App Engine 彈性環境。

您已學會如何編寫及部署第一個 App Engine 彈性網頁應用程式!

清除

如何避免系統向您的 Google Cloud Platform 帳戶收取您在本快速入門導覽課程中所用資源的相關費用:

  • 前往 Cloud Platform 主控台
  • 選取要關閉的專案,然後按一下頂端的「刪除」,系統就會排定刪除專案的時間。

瞭解詳情

授權

這項內容採用的授權為 Creative Commons 姓名標示 2.0 通用授權。