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 の下には
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.
{% %} の中で実行。 {{ }} の中を出力。
静的コンテンツ(CSS やイメージファイル)の配置
app.yaml の handlers: で static_dir: として静的コンテンツを配置するディレクトリを指定する。
記述順番が重要。/.* は全てにマッチしてしまうので、その下に書いても無意味。
アプリケーションのアップロード
最後にアプリケーションのアップロードだが、アカウント取れなかったのではぶく。