App Engine スタンダード環境で Flask を使ってみる

このガイドでは、Google App Engine スタンダード環境で実行される基本的な Python 2.7 アプリケーションを開発し、デプロイする方法について説明します。このガイドは、Google App Engine や関連サービスの利用経験がないことを前提としています。特に、Python 言語で App Engine を初めて使用する方を対象にしています。このため、各作業についてクイックスタート ガイドよりも詳しく説明しています。

始める前に

アプリケーションを開発する前に、次のことを行ってください。

  1. 新しい GCP Console プロジェクトを作成するか、Google Cloud Platform Console から既存のプロジェクトのプロジェクト ID を取得します。

    プロジェクト ページに移動

  2. Google Cloud SDK をインストールして初期化します。

基本アプリケーションを作成する

このガイドでは、Flask ウェブ アプリケーション フレームワークを使用します。このフレームワークは簡単で使いやすく、拡張性にも優れています。また、使用するフレームワークに同じ原則を適用できます。このガイドでは、次の方法を学習します。

  • 基本的なユーザー コメント フォームを作成し、作成した HTML テンプレート上のフォームからユーザーが送信したコンテンツを表示する。
  • 静的ファイル(CSS、画像など)を提供する基本的なアプリケーションを作成する。

開発環境の設定が完了したら、アプリケーションのコードを作成し、App Engine にデプロイします。

アプリ プロジェクトの基本構造

このガイドで使用する flask-app プロジェクトの構造は次のとおりです。

flask-app プロジェクトの構造

  • app.yaml: App Engine アプリケーションを設定します。
  • main.py: アプリケーションのコンテンツを作成します。
  • static: 静的ファイルを格納するディレクトリ。
    • style.css: テンプレート ファイルの外観を定義する基本的なスタイルシート。
  • templates: すべての HTML テンプレートが存在するディレクトリ。
    • form.html: フォームの表示に使用される HTML テンプレート。
    • submitted_form.html: 送信したフォームのコンテンツを表示する HTML テンプレート。

開発を可能にするライブラリの設定

このチュートリアルでは、Flask ライブラリのコピーをアプリケーションのディレクトリに配置します。App Engine Python 2.7 ランタイム環境には Flask ライブラリがバンドルされていますが、バンドルされているライブラリはこのチュートリアルでは動作しない古いバージョンである可能性があるので注意してください。

必要なライブラリを設定するには:

  1. ルート プロジェクト ディレクトリに appengine_config.py という名前のファイルを作成します。アプリケーションをデプロイする際に、このファイルを使用して、App Engine がサードパーティのライブラリを探す場所を指定できます。

    from google.appengine.ext import vendor
    
    # Add any libraries installed in the "lib" folder.
    vendor.add('lib')

  2. requirements.txt という名前のファイルをルート プロジェクト ディレクトリに作成します。

    Flask==1.0.2
    Werkzeug<0.13.0,>=0.12.0
    

  3. ローカル パソコンでこのアプリを実行するには、Python、pipvirtualenv を含む Python 開発環境を設定する必要があります。詳細については、Google Cloud Platform の Python 開発環境のセットアップをご覧ください。

  4. virtualenv を使用して依存関係をインストールします。

    Mac OS / Linux

    1. プロジェクトの外部のディレクトリに孤立した Python 環境を作成し、それを有効化します。
      virtualenv env
      source env/bin/activate
      チュートリアルの最後に、deactivate と入力して virtualenv を終了できます。
    2. プロジェクト ディレクトリに移動し、依存関係をインストールします。
      cd YOUR_PROJECT
      pip install -t lib -r requirements.txt

    Windows

    Cloud SDK をインストールしている場合は、すでに Python 2.7 がインストールされているはずです。これは通常、C:\python27_x64\ (64 ビットシステムの場合)にインストールされています。Powershell を使用して Python パッケージを実行します。

    1. インストールされた Powershell を探します。
    2. Powershell へのショートカットを右クリックし、管理者として Powershell を起動します。
    3. python コマンドを実行してみます。見つからない場合は、環境の PATH に Python フォルダを追加します。
      $env:Path += ";C:\python27_x64\"
    4. プロジェクトの外部のディレクトリに孤立した Python 環境を作成し、それを有効化します。
      python -m virtualenv env
      env\Scripts\activate
      チュートリアルの最後に、deactivate と入力して virtualenv を終了できます。
    5. プロジェクト ディレクトリに移動し、依存関係をインストールします。
      cd YOUR_PROJECT
      python -m pip install -t lib -r requirements.txt

    -t lib フラグはライブラリを lib フォルダにコピーします。このフォルダはデプロイ時に App Engine にアップロードされます。サードパーティ ライブラリのコピーの詳細については、コピーしたライブラリとともに pip requirements.txt を使用するをご覧ください。

    -r requirements.txt フラグは、requirements.txt ファイルのすべてをインストールするように pip に指示します。

app.yaml ファイルを作成する

app.yaml ファイルを手動で作成して App Engine アプリケーションの構成を行います。また、開発プロジェクトを作成するときに構成することもできます。App Engine は、app.yaml ファイルを参照してアプリケーションの実行方法を確認します。また、URL と静的ファイルや Python モジュールのマッピングも確認します。

app.yaml ファイルを作成するには:

  1. プロジェクトのルート ディレクトリに、app.yaml という名前のファイルを作成します。
  2. このファイルに次の行を追加します。

    runtime: python27
    api_version: 1
    threadsafe: true
    
    handlers:
    - url: /static
      static_dir: static
    - url: /.*
      script: main.app
    

app.yaml ファイルに関するリファレンス情報については、app.yaml のリファレンス ドキュメントをご覧ください。

Flask アプリにリクエスト ハンドラを作成する

App Engine がアプリケーションのウェブ リクエストを受け取ると、アプリケーションの app.yaml 設定ファイルに記載されている URL に対応するハンドラ スクリプトを呼び出します。Python 2.7 ランタイムは WSGI 標準をサポートしています。WSGI の方をおすすめします。WSGI がないと Python 2.7 の一部の機能が動作しません。アプリケーションのスクリプト ハンドラの設定によって、リクエストが WSGI で処理されるかどうかが決まります。

サーバーは、リクエストの URL をアプリの設定ファイル内の URL パターンと比較することにより、呼び出す Python アプリケーション オブジェクトを決定します。その後で、WSGI 標準で規定された引数を使用してアプリケーション オブジェクトを呼び出します。アプリケーション オブジェクトは、リクエストに適切なアクションを実行してから、レスポンスを準備してそれを文字列のリストとして返します。

次のリクエスト ハンドラは、/templates/form.html ファイルのフォームで送信された情報を取得し、この情報を /templates/submitted_form.html テンプレート ファイルに挿入します。

  1. アプリケーションのルート ディレクトリに main.py という新しいファイルを作成します。

  2. Flask フレームワークと使用する Flask インターフェースをインポートします。

    from flask import Flask, render_template, request

  3. この行を追加して、Flask クラスのインスタンスを作成し、app という変数に割り当てます。

    app = Flask(__name__)

  4. form.html テンプレートを使用して、フォームを表示するリクエスト ハンドラを作成します。

    @app.route('/form')
    def form():
        return render_template('form.html')

    ユーザーがアプリケーションで /form/ ディレクトリに移動すると、作成した form.html テンプレートが表示されます。

  5. 送信されたフォームの情報を処理するリクエスト ハンドラを作成します。

    @app.route('/submitted', methods=['POST'])
    def submitted_form():
        name = request.form['name']
        email = request.form['email']
        site = request.form['site_url']
        comments = request.form['comments']
    

    ここで作成した変数にフォーム情報が格納されます。これらの変数を使用すると、作成する submitted_form.html テンプレートにフォームのデータを送信できます。

Flask の簡単な使い方については、Flask のクイックスタート ガイドをご覧ください。

このフォームの機能は簡単に拡張できます。たとえば、Mail APIMailgunMailjetSendGrid を使用して、ユーザーが入力したコメントを自分や他のユーザーに送信できます。

Jinja2 テンプレートの設定

HTML をコードに埋め込むと、メンテナンスが煩雑になる場合があります。この場合、テンプレート システムを使用して HTML を別のファイルに保存し、アプリケーションから返されたデータの表示場所を特別な構文で指定します。好みのテンプレート エンジンをアプリケーション コードにバンドルして使用できます。手軽な方法としては、App Engine に DjangoJinja2 のテンプレート エンジンが搭載されています。

  1. submitted_form() 関数の最後に次の行を追加します。

    return render_template(
        'submitted_form.html',
        name=name,
        email=email,
        site=site,
        comments=comments)

    この行では、送信されたフォーム情報とともに submitted_form.html テンプレートをレンダリングするための render_template() インターフェースを使用しています。

  2. form.htmlsubmitted_form.html テンプレートを作成します。

    1. ルート ディレクトリに templates という名前の新しいフォルダを作成します。

      mkdir templates
      
    2. プロジェクトの templates ディレクトリに form.html を作成します。

      <html>
        <head>
          <title>Submit a form</title>
         <link rel="stylesheet" type="text/css" href="/static/style.css">
        </head>
        <body>
          <div id="container">
            <div class="pagetitle">
              <h1>Submit a form</h1>
            </div>
            <div id="main">
              <form method="post" action="{{ url_for('submitted_form') }}">
                <label for="name">Name:</label>
                <input type="text" name="name"><br />
                <label for="email">Email address:</label>
                <input type="email" name="email"><br />
                <label for="site_url">Website URL:</label>
                <input type="url" name="site_url"><br />
                <label for="comments">Comments:</label>
                <textarea name="comments"></textarea><br />
                <input type="submit">
              </form>
            </div>
          </div>
        </body>
      </html>
      

    3. プロジェクトの templates ディレクトリに submitted_form.html を作成します。

      <html>
       <head>
         <title>Submitted form</title>
         <link rel="stylesheet" type="text/css" href="/static/style.css">
       </head>
       <body>
         <div id="container">
           <div class="pagetitle">
             <h1>Form submitted</h1>
           </div>
           <div id="main">
             <p>Thanks for your submission, {{name}}!</p>
             <p>Here's a review of the information that you sent:</p>
             <p>
                <strong>Name</strong>: {{name}} <br>
                <strong>Email</strong>: {{email}} <br>
                <strong>Website URL</strong>: {{site}} <br>
                <strong>Comments</strong>: {{comments}}
             </p>
           </div>
         </div>
       </body>
      </html>
      

Flask と Jinja2 でテンプレートを使用する方法については、Flask の公式ドキュメントをご覧ください。

静的ファイルの提供

画像、CSS、Flash アニメーションなど、ページのリクエスト時に動的に生成されないコンテンツは静的ファイルで提供するほうが効率的です。

CSS ファイルを作成し、そのファイルにハンドラを作成します。

  1. ルート ディレクトリに static という名前の新しいフォルダを作成します。

    mkdir static
    
  2. style.css ファイルを作成して、先ほど作成したテンプレートの外観を変更します。プロジェクトの static フォルダにファイルを作成して、次のスタイルを追加します。

    .pagetitle {
        color: #800080;
    }
    

  3. 前に作成した app.yaml ファイルでは、静的ファイルを含む static ディレクトリが指定されています。

    handlers:
    - url: /static
      static_dir: static
    - url: /.*
      script: main.app

    handlers セクションでは、URL に対して 2 つのハンドラを定義します。/static で始まる URL のリクエストを App Engine が受け取ると、static ディレクトリのファイルのパスの残りの部分がマッピングされ、該当するファイルが見つかれば、そのファイルの内容がクライアントに返されます。

URL マッピングと app.yaml で指定可能なオプションの詳細については、app.yaml リファレンスをご覧ください。

アプリケーションをテストする

SDK に含まれるローカルの開発用サーバー(dev_appserver.py)を使用して、アプリケーションをテストします。

  1. アプリケーションの app.yaml 構成ファイルがあるルート ディレクトリから、次のコマンドを使用してローカル開発サーバーを起動します。

    dev_appserver.py app.yaml
    

    ローカルの開発用サーバーが起動し、ポート 8080 でリクエストを待機します。

    問題が発生する場合は、ここをクリックしてください。

  2. ウェブブラウザで http://localhost:8080/form にアクセスしてアプリを表示します。

ローカル開発サーバー(dev_appserver.py)の実行

ローカルの開発用サーバーを実行するには、ディレクトリをフルパスで指定して dev_appserver.py を実行するか、PATH 環境変数に dev_appserver.py を追加します。

  • 元の App Engine SDK をインストールした場合、ツールは次の場所に配置されています。

    [PATH_TO_APP_ENGINE_SDK]/dev_appserver.py
    
  • Google Cloud SDK をインストールした場合、ツールは次の場所に配置されています。

    [PATH_TO_CLOUD_SDK]/google-cloud-sdk/bin/dev_appserver.py
    

    ヒント: Google Cloud SDK ツールを PATH 環境変数に追加し、シェルでコマンドの補完を有効にするには、次のコマンドを実行します。

    [PATH_TO_CLOUD_SDK]/google-cloud-sdk/install.sh
    

ポート番号の変更方法など、ローカルの開発用サーバーの実行について詳しくは、ローカルの開発用サーバーのリファレンスをご覧ください。

変更する

アプリケーションの開発中は、開発用サーバーを起動したままにすることができます。開発用サーバーはソースファイル内の変更を監視し、必要に応じてファイルを再読み込みします。

  1. では試してみましょう。開発用サーバーを起動したまま templates/form.html を編集して、<h1> タグ内の Submit a form テキストを別の語句に変更します。
  2. http://localhost:8080/form を再読み込みして結果を確認します。

アプリケーションをデプロイする

アプリをアップロードするには app.yaml ファイルがあるプロジェクトのルート ディレクトリから次のコマンドを実行します。

gcloud app deploy

オプション フラグ:

  • --project フラグを含めて、GCP Console の代替プロジェクト ID を、gcloud ツールでデフォルトとして初期化した ID に指定します。例: --project [YOUR_PROJECT_ID]
  • -v フラグを含めてバージョン ID を指定するか、そうでなければ 1 つ 生成されます。例: -v [YOUR_VERSION_ID]

コマンドラインからアプリをデプロイする方法については Python アプリをデプロイするをご覧ください。

アプリケーションの表示

ブラウザを開いて http://[YOUR_PROJECT_ID].appspot.com/form でアプリを表示します。

サポート

アプリケーションの開発中に問題が発生した場合には、テクニカル サポートとデベロッパー コミュニティでヘルプを利用できます。

次のステップ

このページは役立ちましたか?評価をお願いいたします。

フィードバックを送信...

Python の App Engine スタンダード環境