摘要
在本程式碼研究室中,您將瞭解如何將 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 Standard 在更嚴格的沙箱環境中執行應用程式。詳情請參閱選擇 App Engine 環境。
您將會瞭解的內容
- 如何將簡易網路應用程式部署至 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.cloud.google.com),然後建立新專案:
提醒您,專案編號是所有 Google Cloud 專案的不重複名稱 (使用上述名稱後就無法使用,敬請見諒!)此程式碼研究室稍後將稱為 PROJECT_ID。
計費
接著,您必須在 Cloud Console 中啟用計費功能,才能使用 Google Cloud 資源。
完成這個程式碼研究室的成本應該不會超過新臺幣 $300 元,但如果您決定用到更多資源,或讓資源繼續運作,則可能需花費更多費用。
新加入 Google Cloud Platform 的使用者可免費試用$300 美元。
雖然 Google Cloud 可透過筆記型電腦進行遠端作業,但在這個程式碼研究室中,我們會使用 Google Cloud Shell,這是一個在 Cloud 中執行的指令列環境。這款以 Debian 為基礎的虛擬機器會載入您需要的所有開發工具 (gcloud、python、Virtualenv、pip 等),並提供永久的 5GB 主目錄,可以在 Google Cloud 中運作,大幅提升網路效能和驗證能力。也就是說,這個程式碼研究室只需使用瀏覽器 (是,您可以在 Chromebook 上使用)。
如要啟用 Google Cloud Shell,只要在開發人員控制台中,按一下右上角的按鈕 (只需幾分鐘即可佈建並連線至環境):
連線至 Cloud Shell 之後,您應該會看到您已經通過驗證,且專案已設為您的 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,或是在主控台資訊主頁中查看專案 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、Storage 和 Datastore 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
使用 pip 從 requirements.txt 檔案中安裝專案的依附元件:
pip install -r requirements.txt
requirements.txt 檔案會列出您的專案所需的套件依附元件。上述指令會將這些列出的所有套件下載至 virtualenv。
建立 App Engine 應用程式
接下來,使用下列方法建立 App Engine 執行個體:
gcloud app create
建立 Storage 值區
首先,將環境變數 CLOUD_STORAGE_BUCKET 設為與 PROJECT_ID 的名稱相同。(通常會以 PROJECT_ID 為值區命名,以便使用)。
export CLOUD_STORAGE_BUCKET=${PROJECT_ID}
我們的應用程式使用了 Cloud Storage 值區,您必須在 Cloud Shell 中利用名為 gsutil 的工具建立這類值區。執行下列指令,以建立與您的 PROJECT_ID 同名的值區。
gsutil mb gs://${PROJECT_ID}
執行應用程式
python main.py
應用程式啟動後,請按一下 Cloud Shell 工具列中的 [Web Preview] 圖示 ,然後選擇 [透過通訊埠 8080 預覽]。
在瀏覽器中開啟一個分頁,並連結至您剛啟動的伺服器。如下所示:
請嘗試上傳含有人臉的相片。按一下 [選擇檔案] 按鈕,從您的電腦中選擇圖片,然後按一下 [提交]。
上傳相片後,您會看到如下內容:
程式碼範例版面配置
範例的版面配置如下:
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 的臉部偵測功能進行分析。每張相片的重要資訊都儲存在 Datastore,也就是 Google Cloud Platform 的 NoSQL 資料庫,每當使用者造訪網站時,系統就會將資料儲存在該資料庫中。
這個應用程式使用 Google Cloud Platform 用戶端程式庫來儲存儲存空間、Datastore 和 Vision。這些用戶端程式庫可讓您以自己慣用的程式設計語言輕鬆存取 Cloud API。
讓我們來看看程式碼片段的部分重點摘要。
頂端的匯入部分是匯入程式碼所需的各種套件。以下說明 Google Cloud 用戶端程式庫如何匯入 Datastore、Storage 和 Vision 資料:
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)
Storage 和 Vision 用戶端程式庫可以透過類似資料儲存庫的方式存取。您可以使用 vim、emacs 或 nano 自行開啟 main.py 檔案,以探索所有程式碼範例。
如要進一步瞭解 Flask,請前往 http://flask.pocoo.org/。
如要進一步瞭解用戶端程式庫,請前往 https://googlecloudplatform.github.io/google-cloud-python/。
首頁.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 會嘗試猜測部署設定。但是,建議你提供這個檔案。
接下來,請使用您選擇的 vim、nano 或 emacs 的編輯器修改 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 Flex 應用程式所需的基本設定。如要進一步瞭解設定 App Engine,請參閱這篇文章。
開啟 app.yaml 後,請將 < your-cloud-storage-bucket > 替換為您的 Cloud Storage 值區名稱。(如果您忘記 Cloud Storage 值區的名稱,請從 Qwiklabs 複製 GCP 專案 ID,這是相同的)。env_variables 部分會設定環境變數,以便在部署應用程式後用於 main.py。
您現已使用 (Ctrl + x) 關閉 nano 儲存功能,
輸入字母 y,然後再次按下 ENTER 鍵,確認以下提示的檔案名稱:
使用 gcloud 在 App Engine 上部署應用程式:
gcloud app deploy
部署應用程式後,請在網路瀏覽器中開啟 https://< PROJECT_ID >.appspot.com 網址來造訪該應用程式。
摘要
在這個步驟中,您會設定 Python 網路應用程式並將其部署至 App Engine 彈性環境。
您已經瞭解如何編寫及部署第一個 App Engine 彈性環境網頁應用程式!
清除
如何避免系統向您的 Google Cloud Platform 帳戶收取您在本快速入門導覽課程中所用資源的相關費用:
- 前往 Cloud Platform 主控台。
- 選取您要關閉的專案,然後按一下 [刪除] 來排定刪除專案的時間。
瞭解詳情
- Google Cloud Platform 上的 Python:https://cloud.google.com/python/
- Python 適用的 App Engine 彈性說明文件:https://cloud.google.com/appengine/docs/flex/python/
- Python 用戶端程式庫說明文件:Datastore、Storage 與 Vision
- 其他 Python 程式碼範例:https://cloud.google.com/python/samples
授權
本作品採用創用 CC 姓名標示 2.0 一般授權。