みなさん、GoogleAppEngine (GAE) で開発をしてますか?
僕も最近 Python をよく使うようになったので、GAE 用のアプリをいくつか作っています。
Python の開発環境を作る際は buildout を使うと非常に便利です。
必要なeggパッケージのインストールや svn からのチェックアウト、Apache/MySQL のセットアップなどの作業を
設定に基づいて自動的に行ってくれます。
しかし、この設定では私の環境ではそのままでは動かなくてハマってしまいました。
この設定で利用している appfy.recipe.gae:app_lib というレシピは、
指定したライブラリをGAEで利用しやすいようZIP ファイルにまとめる仕組みを提供しているのですが、
この「指定したライブラリ」が開発環境に既にインストールされていると ZIP ファイルには含まれなくなります。
そのため、ローカル環境で動作確認すると正しく動くのですが GAE 上ではライブラリが足りずにちゃんと動作しません。
これを防ぐために allowed-eggs-from-site-packages というオプションを用います。
allowed-eggs-from-site-packages は名前の通り、ローカルの site-packages の中から利用して良いパッケージを指定するものです。
このオプションを使って、ZIP ファイルに必要な全てのパッケージを含めるようにします。
※ appfy.recipe.gae のドキュメントには載っていないオプションですが、
ベースにしている zc.recipe.egg.Scripts (がベースにしている z3c.recipe.scripts) が提供している機能です。
最終的に設定を加えた buildout.cfg はこうなります。
※ flask 用の初期設定も含めるようにしました。
[buildout]
parts = prepare debug app_lib gae_sdk gae_tools test
[prepare]
recipe = iw.recipe.cmd:py
on_install = true
cmds =
>>> buildout_dir = buildout.get(‘directory’, ‘.’)
>>> path = os.path.join(buildout_dir, ‘app’)
>>> if not os.path.exists(path):
… os.makedirs(os.path.join(buildout_dir, ‘app’))
… open(os.path.join(path, ‘app.yaml’), ‘at’).write(
… ‘application: appname\n’
… ‘version: 1\n’
… ‘runtime: python\n’
… ‘api_version: 1\n’
… ‘handlers:\n’
… ‘- url: /remote_api\n’
… ‘ script: $PYTHON_LIB/google/appengine/ext/remote_api/handler.py\n’
… ‘ login: admin\n’
… ‘- url: .*\n’
… ‘ script: main.py\n’
… )
… open(os.path.join(path, ‘main.py’), ‘at’).write(
… “””# -*- coding: utf-8 -*-\n”””
… “””\n”””
… “””import sys; sys.path.insert(0, ‘./distlib.zip’)\n”””
… “””from google.appengine.ext.webapp.util import run_wsgi_app\n”””
… “””import werkzeug\n”””
… “””from flask import Flask\n”””
… “””app = Flask(__name__)\n”””
… “””\n”””
… “””@app.route(‘/’)\n”””
… “””def index():\n”””
… “”” return ‘hello world’\n”””
… “””\n”””
… “””if __name__ == ‘__main__’:\n”””
… “”” run_wsgi_app(app)\n”””
… )
[debug]
recipe = zc.recipe.egg:script
eggs = ipython
extra-paths =
${gae_tools:extra-paths}
${gae_tools:sdk-directory}/lib/django
${gae_tools:sdk-directory}/lib/webob
${gae_tools:sdk-directory}/lib/yaml/lib
${buildout:directory}/app
interpreter = py
[app_lib]
recipe = appfy.recipe.gae:app_lib
lib-directory = app/distlib
use-zipimport = true
allowed-eggs-from-site-packages =
.
eggs =
flask
ignore-globs =
*.c
*.pyc
*.pyo
*/test
*/tests
*/testsuite
*/django
*/sqlalchemy
simplejson/_speedups.py
ignore-packages =
distribute
setuptools
easy_install
site
pkg_resources
[gae_sdk]
recipe = appfy.recipe.gae:sdk
url = http://googleappengine.googlecode.com/files/google_appengine_1.4.0.zip
clear-destination = true
[gae_tools]
recipe = appfy.recipe.gae:tools
sdk-directory = ${gae_sdk:destination}/google_appengine
extra-paths =
app/lib
app/distlib.zip
app
[test]
recipe = pbp.recipe.noserunner
eggs =
${app_lib:eggs}
nose
nosegae
extra-paths = ${debug:extra-paths}
environment = nose-environment
defaults = –gae-application=${buildout:directory}/app
[nose-environment]
NOSE_WITH_GAE = true
NOSE_WHERE = ${buildout:directory}/app