App Engine フレキシブル環境に Python Flask ウェブ アプリケーションをデプロイする

概要

この Codelab では、Python Flask ウェブ アプリケーションを App Engine フレキシブル環境にデプロイする方法を学習します。デプロイするアプリケーションはサンプル アプリケーションです。人の顔の写真をアップロードして、その人が楽しい気分である可能性を調べることができます。このアプリケーションは、Vision、Storage、Datastore の Google Cloud API を使用しています。

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 Console と Google Cloud SDK を使用して、さまざまなクラウド リソースを管理する方法
  • Cloud Shell を使用する方法

必要なもの

  • Python の基本知識
  • Linux の標準的なテキスト エディタ(vim、emacs、nano など)を使い慣れていること

プロジェクトの作成

Google アカウント(Gmail または Google Apps)をまだお持ちでない場合は、アカウントを作成する必要があります。Google Cloud Platform Console(console.cloud.google.com)にログインして、新しいプロジェクトを作成します。

プロジェクト ID を忘れないようにしてください。プロジェクト ID はすべての Google Cloud プロジェクトを通じて一意の名前にする必要があります(上記の名前はすでに使用されているので使用できません)。以降、この Codelab で PROJECT_ID と呼びます。

お支払い

次に、Google Cloud リソースを使用するために、Cloud Console で課金を有効にする必要があります。

この Codelab を実施した場合、費用は数ドルを超えることはありませんが、より多くのリソースを使用する場合や、実行を継続する場合は、さらにコストがかかる可能性があります。

Google Cloud Platform の新規ユーザーは 300 ドル分の無料トライアルをご利用いただけます。

Google Cloud はノートパソコンからリモートで操作できますが、この Codelab では Cloud 上で動作するコマンドライン環境である Google Cloud Shell を使用します。この Debian ベースの仮想マシンは、必要な開発ツール(gcloudpythonvirtualenvpip など)をすべて搭載し、永続的な 5 GB のホーム ディレクトリを提供します。また、Google Cloud 上で動作することで、ネットワークのパフォーマンスと認証が大幅に強化されます。この Codelab に必要なのはブラウザだけです(はい、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 を確認するか、コンソール ダッシュボードで確認します。

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 API、Storage API、Datastore API を使用する前に、次のコマンドを使用して 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 の認証を行うをご覧ください。

仮想環境の起動と依存関係のインストール

virtualenvenv という名前の分離された Python 3 環境を作成します。

virtualenv -p python3 env

新しく作成した virtualenvenv という名前で入力します。

source env/bin/activate

pip を使用して、プロジェクトの依存関係を requirements.txt ファイルからインストールします。

pip install -r requirements.txt

requirements.txt ファイルは、このプロジェクトに必要なパッケージ依存関係のリストです。上のコマンドを実行すると、リストのすべてのパッケージ依存関係がこの virtualenv にダウンロードされます。

App Engine アプリを作成する

次に、下のコマンドを使用して App Engine インスタンスを作成します。

gcloud app create

ストレージ バケットを作成する

まず、環境変数 CLOUD_STORAGE_BUCKETPROJECT_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-02-23 7.22.50 PM.png

人間の顔が写っている写真をアップロードしてください。[Choose File] ボタンをクリックし、パソコンから画像を選択して [Submit] をクリックします。

写真をアップロードすると、次のように表示されます。

スクリーンショット 2017-02-23 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 の顔検出機能を使用して分析されます。また、写真の主な情報が Datastore(Google Cloud Platform の NoSQL データベース)に保存されて、ユーザーがウェブサイトを訪れるたびに参照されます。

このアプリケーションは、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

次のコードは、ユーザーがウェブサイトのルート URL にアクセスしたときに実行される処理を表しています。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 のクライアント ライブラリにプログラムでアクセスする方法も Datastore と同様です。vimemacsnano を使用して 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 はデプロイ構成の推定を試みますが、このファイルを指定することをおすすめします。

次に、任意のエディタ(vimnano、または 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>

これは、App Engine フレキシブル環境の Python 3 アプリケーションをデプロイするために必要な基本構成です。App Engine の構成の詳細については、こちらをご覧ください。

app.yaml を開いたら、< your-cloud-storage-bucket > を Cloud Storage バケットの名前に置き換えます。(Cloud Storage バケットの名前を忘れた場合は、Qwiklabs の GCP プロジェクト ID をコピーします。これは同じ ID です)。env_variables セクションでは、アプリケーションのデプロイ後に main.py で使用される環境変数を設定します。

完了したらファイルを保存して閉じます。nano の場合は Ctrl+X キーを押します。次のようなプロンプトが表示されます。

スクリーンショット 2017-02-17 4.47.12 PM.png

文字 y を入力し、もう一度 Enter キーを押して、次のプロンプトのファイル名を確認します。

スクリーンショット 2017-02-24 16:18.23.png

gcloud を使用してアプリを App Engine にデプロイします。

gcloud app deploy

アプリケーションがデプロイされたら、ウェブブラウザで URL https://< PROJECT_ID >.appspot.com にアクセスしてアプリケーションにアクセスできます。

概要

このステップでは、Python ウェブ アプリケーションを設定し、App Engine フレキシブル環境にデプロイしました。

ここでは、初めての App Engine フレキシブル ウェブ アプリケーションを作成してデプロイする方法を学びました。

クリーンアップ

このクイックスタートで使用するリソースに対して Google Cloud Platform アカウントに課金されないようにするには:

  • Cloud Platform Console に移動します。
  • シャットダウンするプロジェクトを選択し、上部にある [削除] をクリックします。これにより、プロジェクトの削除がスケジュールされます。

詳細

ライセンス

この作業はクリエイティブ・コモンズの表示 2.0 汎用ライセンスにより使用許諾されています。