Google App Engine StandardのPython3.7をローカルのdev_appserver.pyで動かす

Google App Engine StandardのPython3.7ではローカル開発でのdev_appserver.pyは推奨されておらず、GunicornなどWSGIサーバーを使うことが推奨されている。
しかし、この方法ではローカルでapp.yamlの確認ができない
つまり、URLと静的ファイルを紐づけるhandlersや、エラータイプごとにエラーページを指定するerror_handlersの確認がローカルでできないことになる。
これでは不便なので、Python3.7でローカル開発時にdev_appserver.pyを使う方法を記載する。

app.yamlを用意する

Python3.7で動かすためにruntimepython37として、entrypointgunicornで動くようにする。
静的ファイルはhandlersstatic_dir./publicディレクトリ以下を/staticURL下にマッピングしておく。

app.yaml

runtime: python37
entrypoint: gunicorn -b :$PORT main:app

handlers:
  - url: /static
    static_dir: public

dev_appserver.pyをPython2.7で実行できるよう環境変数を設定する

dev_appserver.py --application=PROJECT_ID app.yamlapp.yamlを読み込んでローカルサーバーを立ち上げる。

$ dev_appserver.py --application=gae-flask-app app.yaml
ERROR: Python 3 and later is not compatible with the Google Cloud SDK. Please use Python version 2.7.x.

If you have a compatible Python interpreter installed, you can use it by setting
the CLOUDSDK_PYTHON environment variable to point to it.

しかし、Google Cloud SDKはPython3と互換性がないと表示されてしまう。
CLOUDSDK_PYTHON変数にPython2.7.xを指定すればよいので、pyenvでPython2.7.16をインストールする。

$ pyenv install 2.7.16
$ pyenv versions
  system
  2.7.16
* 3.7.3 (set by /Users/nancy/.pyenv/version)

それから、CLOUDSDK_PYTHONにインストールしたPython2.7.16を指定する。

$ echo 'export CLOUDSDK_PYTHON=~/.pyenv/versions/2.7.16/bin/python' >> ~/.bash_profile
$ . ~/.bash_profile
$ echo $CLOUDSDK_PYTHON
/Users/nancy/.pyenv/versions/2.7.16/bin/python
$ $CLOUDSDK_PYTHON --version
Python 2.7.16

dev_appserver.pyは仮想環境上で動かすとOSError: [Errno 2] No such file or directoryになる

仮想環境上でdev_appserver.pyを実行すると、OSError: [Errno 2] No such file or directoryというエラーになってしまう。

$ pipenv shell
Launching subshell in virtual environment…
$  . /Users/nancy/.local/share/virtualenvs/gae-flask-r4b-hAq-/bin/activate
(gae-flask) $ dev_appserver.py --application=gae-flask-app ./app.yaml
略
OSError: [Errno 2] No such file or directory

そのため、仮想環境上で実行せず、ローカルのPythonのバージョンを3.7にしておき、dev_appserver.pyを実行する。

ローカルのPythonを3.7にして、dev_appserver.pyを動かす

 $ python --version
Python 3.7.3
 $ dev_appserver.py --application=gae-flask-app app.yaml
INFO     2019-05-13 11:41:48,741 devappserver2.py:278] Skipping SDK update check.
INFO     2019-05-13 11:41:48,938 api_server.py:275] Starting API server at: http://localhost:51038
INFO     2019-05-13 11:41:48,946 instance_factory.py:71] Detected Python 3.7.3
... 略

ローカルサーバーが立ち上がり、handlersで指定していた静的ファイルを表示できることを確認できる。

ローカルで静的ファイルを確認する

・参考
https://stackoverflow.com/questions/52999747/python-3-7-local-development-server-options-for-new-app-engine-apps
https://stackoverflow.com/questions/54640695/running-locally-with-gae-python-second-generation
https://cloud.google.com/appengine/docs/standard/python3/serving-static-files