Google App Engine : Getting Started Guide

まずはインストールしてデモを動かしてみる。

google_appengine.zip をダウンロードして ~/local/opt/ に展開。
python2.4 と python2.5 両方インストールされているので明示的に python2.5 で起動。

% cd ~/local/opt/google_appengine/
% python2.5 ./dev_appserver.py demos/guestbook

http://localhost:8080/ にアクセスするとテキストエリアとボタンだけのページが表示される。
UTF-8 で日本語もちゃんととおる。

demos/guestbook の下には

  • app.yaml アプリケーションの設定
  • guestbook.py ロジック部分
  • index.yaml dev_appserver が自動的に更新するファイル

Getting Started Guide

http://code.google.com/appengine/docs/gettingstarted/introduction.html をなぞっていく。

匿名もしくは Google account で投稿するゲストブックを作成するらしい。

開発環境

次の2つのコマンドがある。

  • dev_appserver.py が開発用 Web サーバ
  • appcfg.py が App Engine に作成したアプリケーションをアップロードする。
Hello, World!

まずはもろに CGI から。
コンフィギュレーションファイルは app.yaml. フォーマットは YAML.
runtime: python とあるあたり他の言語も意識してる。
handlers: で URL とアプリケーションをむすびつける。

実行は dev_appserver.py にディレクトリを渡す。
~/letter/gae $ python2.5 ~/local/opt/google_appengine/dev_appserver.py helloworld/

実行したまま print 'Hello, world! まみむめも♪' と書きかえたら、即反映された。スクリプトだからね。文字コードUTF-8 でソース保存。

the webapp Framework

さっきは CGI だったが、今度はフレームワーク
CGI をしゃべる任意の Python Web フレームワークを使えるらしい。
独自のシンプルなフレームワークもある。それを webapp と呼ぶ。

コード写経したらインデント間違えた。Python.

main でパスとハンドラクラスを結び付ける。
ハンドラクラスは webapp.RequestHandler を継承。
debug=True でブラウザにスタックトレースを表示。

AnotherPage クラスを追加して、main で /another に紐付ける。
http://localhost:8080/another で表示された。

class AnotherPage(webapp.RequestHandler):
    def get(self):
        self.response.headers['Content-Type'] = 'text/plain'
        self.response.out.write('まみむめも♪')

def main():
    application = webapp.WSGIApplication(
        [('/', MainPage),
         ('/another', AnotherPage)],
        debug=True)
    wsgiref.handlers.CGIHandler().run(application)
ユーザサービスを使う

users.get_current_user() で User か None を返す。None か。nil と同義か?
ここで表示されるログイン画面は何なんだろう?
アップロードしていれば Google アカウントのサインイン画面が表示されるのかな?

webapp での Form

get(self) と post(self) はリクエストメソッドの GET と POST に対応している。
cgi.escape(self.request.get('content')) でパラメータを取ってエスケープ。

※ For example, low-level calls to the operating system, networking operations, and some filesystem operations are not allowed

Datastore

モデルは db.Model を継承する。
こういう書き方って Common Lisp でもよくある。メタクラスとマクロでマッピングされてだけど。

multiline=True で改行を含めることができる。
auto_now_add=True で作成時に自動的に現在日時をセット。

put() で永続化。登録、更新の両方に対応。

SQL ではなく GQL. G って何だ。GQL は JPQL の類か。join はできないっぽい。
db.GqlQuery(GQL 文字列)
Greeting.gql なら "select * from Greeting" を省略できる。

GQL は定数を書けない。全てパラメータでバインディングする。
"where foo = :1", value
"where foo = :foo", foo=value

GQL は API で代用が可能。all(), filter("foo", value), order("-foo"). - は desc.

開発サーバでは --clear_datastore を付けて起動するとデータストアをクリアした状態で動きだす。
python2.5 ~/local/opt/google_appengine/dev_appserver.py --clear_datastore helloworld/

テンプレート

やっぱりテンプレートはあるんだ。
テンプレートの中じゃ endfor, endif.
{% %} の中で実行。 {{ }} の中を出力。

Django のテンプレートシンタックスを使っているとのことだが、Django を知らない。

静的コンテンツ(CSS やイメージファイル)の配置

app.yaml の handlers: で static_dir: として静的コンテンツを配置するディレクトリを指定する。
記述順番が重要。/.* は全てにマッチしてしまうので、その下に書いても無意味。

アプリケーションのアップロード

最後にアプリケーションのアップロードだが、アカウント取れなかったのではぶく。


感想

DB 環境の準備とかがいらないのって楽。
エディタでちょこちょこと作って、DB も Web サーバも気にせず即アップロードして運用できるのはいいな。
webapp はシンプル。この上にまたいろいろのってくるのかな。
他の Web フレームワークと組合せたらどんなになるのだろう。
Python ははじめて触るがわりと好き。b

appengine って append^H.