はじめての Kay Framework 体験記

Google App Engine 専用フレームワークというふれこみの『Kay』を試してみる。
なお環境は Mac OS X 10.6、Python 2.6.2 (自前コンパイル)、GAE SDK 1.3.2。

ダウンロードと解凍

プロジェクトの Web サイトからダウンロードして解凍。

$ cd /tmp
$ wget http://kay-framework.googlecode.com/files/kay-0.8.0.tar.gz
$ tar xzf kay-0.8.0.tar.gz
$ ls -F Kay-0.8.0
.hg_archival.txt        RELEASE_NOTES           kay/
.hgignore               TODO                    manage.py
.hgtags                 app.yaml                settings.py
AUTHORS                 cron.yaml.sample        urls.py
LICENSE                 docs/
README                  favicon.ico

とりあえず行数を数えてみる。

$ find Kay-0.8.0 -type f | xargs wc | tail -1
   89294  382125 7583671 total

8万9千行!! 何かの冗談か?
どのファイルが大きいのか調べてみる。

$ find Kay-0.8.0 -type f | xargs wc | sort -nr | head -11
   89294  382125 7583671 total
    3845   11783  125396 Kay-0.8.0/kay/management/gae_bulkloader.py
    2329    8571   76128 Kay-0.8.0/kay/lib/simplejson/_speedups.c
    2320    8134   75771 Kay-0.8.0/kay/lib/werkzeug/datastructures.py
    2220    6979   65886 Kay-0.8.0/kay/utils/forms/__init__.py
    1549    5135   57546 Kay-0.8.0/kay/lib/jinja2/compiler.py
    1484    6814   63444 Kay-0.8.0/kay/lib/werkzeug/wrappers.py
    1477    2461   33172 Kay-0.8.0/kay/lib/pytz/__init__.py
    1390    5512   53304 Kay-0.8.0/kay/lib/werkzeug/routing.py
    1387   11531  494228 Kay-0.8.0/kay/lib/pytz/zoneinfo.zip
    1201    3660   49756 Kay-0.8.0/kay/lib/babel/messages/frontend.py

うーん、1000行以上のファイルがごろごろしているなあ。どうも lib/ 以下に重量級ライブラリが存在しているようだ。

$ ls  Kay-0.8.0/kay/lib | cat
babel/             # 国際化(i18n)用ライブラリ
debug/             # ?
jinja2/            # テンプレートエンジン
pytz/              # タイムゾーン用ライブラリ
simplejson/        # JSON ライブラリ
werkzeug/          # WSGI 用便利ライブラリ集(?)

simplejson って Python 標準添付じゃなかったっけ。。。と思ったら、標準添付なのは 2.6 からで、GAE が使っている 2.5 では標準添付じゃなかった。

ライブラリ個別に行数を数えてみる。

$  (cd Kay-0.8.0/kay/lib/; for x in *; do printf '%12s' $x; find $x -type f | xargs wc | tail -1; done)
       babel   24627  158907 4127073 total
       debug     166     550    5668 total
      jinja2    9617   32678  731434 total
        pytz    3551   16596  550724 total
  simplejson    4211   15183  141240 total
    werkzeug   16809   63170  667749 total

大きいなあ。どれも有名どころのライブラリなんだろうけど、コンパクトさにはまるで欠ける。
軽快さを求めて Python を使っているのに、これじゃまるで Java だ。

プロジェクトの作成

気を取り直して、チュートリアルをやってみる。
まずはプロジェクトの作成。

## SDK が /usr/local/google_appengine にないとエラーになる
$ python kay-0.8.0/manage.py startproject myproject
The Google App Engine SDK could not be found!
Please visit http://kay-docs.shehas.net/ for installation instructions.
## 仕方ないのでシンボリックリンクを張る
$ sudo ln -s $HOME/tmp/google_appengine /usr/local 

SDK が /usr/local/google_appengine にないとエラーになるようだ。でもこの決めうちは柔軟性に欠ける。$JAVA_HOME にならって、$GAE_HOME を設定してもらうようにしたほうがいいんじゃないだろうか。

## コマンドを再度実行
$ python kay-0.8.0/manage.py startproject myproject
/private/tmp/google_appengine/google/appengine/ext/remote_api/remote_api_stub.py:64: DeprecationWarning: the sha module is deprecated; use the hashlib module instead
  import sha
/private/tmp/google_appengine/google/appengine/tools/dev_appserver_login.py:33: DeprecationWarning: the md5 module is deprecated; use hashlib instead
  import md5
/private/tmp/kay-0.8.0/kay/lib/jinja2/__init__.py:31: UserWarning: Module yaml was already imported from /private/tmp/google_appengine/lib/yaml/lib/yaml/__init__.pyc, but /usr/local/python/2.6.2/lib/python2.6/site-packages/PyYAML-3.09-py2.6-macosx-10.6-i386.egg is being added to sys.path
  __version__ = __import__('pkg_resources') \
/private/tmp/kay-0.8.0/kay/lib/jinja2/__init__.py:31: UserWarning: Module jinja2 was already imported from /private/tmp/kay-0.8.0/kay/lib/jinja2/__init__.py, but /usr/local/python/2.6.2/lib/python2.6/site-packages/Jinja2-2.2.1-py2.6.egg is being added to sys.path
  __version__ = __import__('pkg_resources') \
/private/tmp/kay-0.8.0/kay/lib/jinja2/__init__.py:31: UserWarning: Module werkzeug was already imported from /private/tmp/kay-0.8.0/kay/lib/werkzeug/__init__.py, but /usr/local/python/2.6.2/lib/python2.6/site-packages/Werkzeug-0.6-py2.6.egg is being added to sys.path
  __version__ = __import__('pkg_resources') \
Finished creating new project: myproject.
$ ls -F myproject
app.yaml        kay@            settings.py
favicon.ico     manage.py@      urls.py

なんか警告がでた。最初の 2 つは、Python 2.6 で deprecated になったモジュール (sha と md5) を GAE SDK が使っていることによる警告。あとの 3 つは Kay のライブラリによるもので、システムの中にすでに PyYAML や Jinja2 がインストール済みだと警告がでるようだ (えー?!)。

アプリケーションの作成

気を取り直して、続き。myproject/ の下に、新しくアプリケーション (myapp) を作成する。

$ cd myproject/
$ python manage.py startapp myapp
Running on Kay-0.8.0
...(先ほどと同じように警告がでるので省略)...
$ ls -R
app.yaml        kay@            myapp/          settings.pyc
favicon.ico     manage.py@      settings.py     urls.py

./myapp:
__init__.py     models.py       templates/      urls.py         views.py

./myapp/templates:
index.html

settings.py を編集し、INSTALLED_APPS と APP_MOUNT_POINTS を変更する。

$ vi settings.py
$ cat settings.py
...(snip)...
INSTALLED_APPS = (
    'kay.auth',
    'myapp',
)

APP_MOUNT_POINTS = {
    'myapp': '/',
}
...(snip)...

開発用サーバの起動

開発サーバを起動する。ポート番号の指定方法がわからなかったので、ヘルプで調べている。

$ python manage.py -h | less
$ python manage.py runserver --help | less
$ python manage.py runserver -p 8082
...(snip)...
INFO     2010-04-10 12:22:22,466 dev_appserver_main.py:399] Running application myproject on port 8082: http://localhost:8082

さあ準備はできた。ここまで出来たら、ブラウザで http://localhost:8082/ にアクセスしてみる。
以下がその実行結果だ!

Traceback (most recent call last):
  File "/private/tmp/google_appengine/google/appengine/tools/dev_appserver.py", line 3185, in _HandleRequest
    self._Dispatch(dispatcher, self.rfile, outfile, env_dict)
  File "/private/tmp/google_appengine/google/appengine/tools/dev_appserver.py", line 3128, in _Dispatch
    base_env_dict=env_dict)
  File "/private/tmp/google_appengine/google/appengine/tools/dev_appserver.py", line 515, in Dispatch
    base_env_dict=base_env_dict)
  File "/private/tmp/google_appengine/google/appengine/tools/dev_appserver.py", line 2387, in Dispatch
    self._module_dict)
  File "/private/tmp/google_appengine/google/appengine/tools/dev_appserver.py", line 2297, in ExecuteCGI
    reset_modules = exec_script(handler_path, cgi_path, hook)
  File "/private/tmp/google_appengine/google/appengine/tools/dev_appserver.py", line 2188, in ExecuteOrImportScript
    handler_path, cgi_path, import_hook)
  File "/private/tmp/google_appengine/google/appengine/tools/dev_appserver.py", line 2102, in LoadTargetModule
    module_fullname, import_error_message)
  File "/usr/local/python/2.6.2/lib/python2.6/logging/__init__.py", line 1433, in exception
    error(*((msg,)+args), **{'exc_info': 1})
  File "/usr/local/python/2.6.2/lib/python2.6/logging/__init__.py", line 1426, in error
    root.error(*((msg,)+args), **kwargs)
  File "/usr/local/python/2.6.2/lib/python2.6/logging/__init__.py", line 1056, in error
    self._log(ERROR, msg, args, **kwargs)
....(snip)....
  File "/usr/local/python/2.6.2/lib/python2.6/posixpath.py", line 95, in splitext
    return genericpath._splitext(p, sep, altsep, extsep)
  File "/usr/local/python/2.6.2/lib/python2.6/genericpath.py", line 101, in _splitext
    if p[filenameIndex] != extsep:
RuntimeError: maximum recursion depth exceeded in cmp

・・・再帰がネストしすぎてエラーになってるorz。
原因を自分で追求するほどの気力はないので、はじめての Kay 体験記はここで終了。

まとめ

Google App Engine 専用というふれこみの『Kay』フレームワーク。しかし実際に試してみると、エラーが出て先に進めないという残念な結果になった。作者さんの環境ではうまく動くと思われるので、環境依存の部分が多分にあるのだろう。

気になった点:

  • SDK を /usr/local/google_appengine に置くというのが決めうちなら、ちょっと格好悪い。$GAE_HOME のような環境変数を設定するほうがよさそう。
  • すでに Jinja2 や PyYAML がシステムにインストールされてあると警告がでるのはなんとかしてほしい。
  • Rails では Rake という便利コマンドがあるけど、それに相当するものはなさそう。manage.py は違うっぽいし。
  • ファイル数やファイルサイズが大きすぎる。なるべく import を遅延させるよう工夫したとしても、これだけ大きいと焼け石に水のように思う。
  • 結局、Kay 自体は GAE 専用に作られているんだろうけど、GAE 用には作られてないライブラリを多数抱え込んでいるので、どうしようもない気がする。


今日の結論: やっぱ webapp でいいや。