15 Oct 2009

Google App EngineやPythonのmemo

最近ちょこちょこGoogle App Engineをいじってます。ただ、pythonのコードは生涯で100行くらいしか書いたことないので、度々つまってしまいます。そこで、覚えたことや今後調べることをメモ。

GAEについて

  • かなり楽にウェブアプリが作れる
    • ローカルのサーバもついてくる
    • ファイルを編集したら、サーバが自動でを変更を再読み込みしてくれるのが便利
    • あと特に何もしてないのに、普通に日本語が扱えてたりする
  • urlをイベントのトリガとして、そのハンドラを書くというアーキテクチャになっている
  • データは全てデータストアという特殊なdbに格納する
    • スタティックなファイルの直接読み書きはできない。データのやり取りは基本的にデータストアとのみ行う
  • とりあえずスタートガイドから始めるとよさそう

画像をデータストアに格納、取り出し

フォームから画像をアップロードするような機能を作る場合、アップロードした画像を直接サーバ上に置くことはできないので、blob形式でデータストアに入れなければなりません。それを取り出すときも、/img のようなurlに画像を返すハンドラスクリプトをバインドしてあげる必要があります。こちらのサイトが参考になります。

Images Python API の使用 - Google App Engine - Google Code

throw Life - Google App Engineのデータストアから気持ちよく画像を取り出すオススメできない方法

PYTHONPATH

Pythonのライブラリのロードパスは環境変数PYTHONPATHに設定します。portとかでライブラリを入れた場合は、設定が必要かもしれません。

export PYTHONPATH=/opt/local/lib/python2.5/site-packages

pythonのforループ

pythonのforループはcなどとは少し考え方がことなり、リストに対するforeachのような書き方をします。

for i in range(1, 5):
    ...

少し考え方の転換が必要でしたが、リストが自在に作れるようになれば問題なさそうです。

djangoのテンプレート

GAEではデフォルトでDjangoフレームワークが使えます。でもまだdjangoについてはひとつもわかってません。スタートガイドに、djangoのテンプレートエンジンが出てきたので、まずはここから始めます。

Django | The Django template language: For template authors | Django Documentation

ドキュメントはこちらで十分だと思います。いろいろ書いてありますが、軽くサイトを作ってみたところ、以下の機能の使い方さえ覚えておけば、だいたい大丈夫だと思いました。

  • 変数の使い方
  • 制御系の使い方
    • blockとextend、あるいはテンプレートの継承
    • include
    • for
    • if

変数は{{ variable }}で使えます。制御系は{% foo %}というプレイスホルダになっており、includeは他のhtmlやテンプレートの読み込み、forやifはフローの制御を行います。

djangoのテンプレートエンジンで面白いなと思ったのが、テンプレートの継承という概念です。例えば、以下のように親テンプレートを記述し、子からオーバーライドしたい部分を{% block foo %} ... {% endblock %}のようにして囲います。これをbase.htmlとします。


    "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
    <link rel="stylesheet" href="style.css" />
    <title>{% block title %}My amazing site{% endblock %}title>
head>

<body>
    <div id="sidebar">
        {% block sidebar %}
        <ul>
            <li><a href="/">Homea>li>
            <li><a href="/blog/">Bloga>li>
        ul>
        {% endblock %}
    div>

    <div id="content">
        {% block content %}{% endblock %}
    div>
body>
html>

子テンプレートはbase.htmlを継承し、各blockをオーバーライドします。そうすると、base.htmlのオーバーライドされた部分は、子のもので上書きされます。オーバーライドを省略した場合は、親の内容をデフォルトとして表示します。例えば、子をこう定義した場合は、

{% extends "base.html" %}

{% block title %}My amazing blog{% endblock %}

{% block content %}
{% for entry in blog_entries %}
    <h2>{{ entry.title }}h2>
    <p>{{ entry.body }}p>
{% endfor %}
{% endblock %}

最終的にこんなhtmlが生成されます。


    "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
    <link rel="stylesheet" href="style.css" />
    <title>My amazing blogtitle>
head>

<body>
    <div id="sidebar">
        <ul>
            <li><a href="/">Homea>li>
            <li><a href="/blog/">Bloga>li>
        ul>
    div>

    <div id="content">
        <h2>Entry oneh2>
        <p>This is my first entry.p>

        <h2>Entry twoh2>
        <p>This is my second entry.p>
    div>
body>
html>

ドキュメントには、"この機能はパワフルだけどmost complexだ"と書いてあったんですが、確かに、プログラマならこの機能はすぐに理解できると思うんですが、デザイナの方にとってはすこし理解が難しいのかもしれませんね。

todo

  • 変数のスペルミスで30分くらいはまってしまった。perlのuse strictのような機能がないか調べる。
  • emacsの設定。便利なpythonモードはありそう。またflymakeの設定もしたい。
  • pythonでコマンドラインからマニュアルをみる方法を調べる。(たしかpydoc)
  • 現在なんとなく日本語を使えちゃっているが、気持ち悪いので、なぜ大丈夫なのか、pythonではふつうマルチバイト文字をどう扱うか、などを調べる。