先日 Google App Engine を使用して、2ちゃんねるぶろぐ という2chコピペブログを集めただけのwebサイトを作ったのだが、それの作成時のメモ。
最初から何も設定しなくても使える webapp を使ってます。
設定
設定ファイルは以下の3つ。yaml形式で書く。
app.yaml
cron.yaml
index.yaml
app.yaml
Python アプリケーション設定 - Google App Engine - Google CodeどのURLを叩かれた場合にどのような動作を行うかを書く。
基本的には以下のような感じ。
application: 2chblogs
version: 1
runtime: python
api_version: 1
# 静的なファイルを置く場合。
# ディレクトリの中にファイルを置いておけばdeployした時に勝手にアップロードされる。
- url: /image
static_dir: image
# ファビコン
- url: /favicon.ico
static_files: favicon.ico
upload: favicon.ico
# 管理ページ memcacheとかdbとかの中身見れる。
# http://d.hatena.ne.jp/bellbind/20090716/1247757120
# login: admin と書いておけばアクセス時に認証が必要になる。
- url: /admin/.*
script: $PYTHON_LIB/google/appengine/ext/admin
login: admin
# 上記に当てはまらない場合はすべてmain.pyを叩く場合。
# ここで指定するのとmain.py内で指定するのはどう使い分けるべきなんですかね。
handlers:
- url: .*
script: main.py
cron.yaml
Python 用の cron を使用したスケジュール タスク - Google App Engine - Google Codecronで動かすものがある場合に必要。なくてもOK。
以下の例では20分置きに /getFeeds を実行。
schedule の指定は英文っぽい感じで、いわゆる cron とはまた別の形式。
cron:
- description: get feeds
url: /getFeeds
schedule: every 20 minutes
index.haml
しらん。
Python Datastore API
いわゆるリレーショナルデータベースの代わりに、データストアを使用する。
Model クラス - Google App Engine - Google Codeアプリケーションは、Model をサブクラスするクラスを定義することで、データ モデルを定義します。モデルのプロパティは、クラス属性と Property クラス インスタンスを使用して定義されます。次に例を示します。
以下のようにやればSQLでいうテーブルが作成できる。
from google.appengine.ext import db
class Entry(db.Model):
title = db.StringProperty(required=True)
link = db.LinkProperty(required=True)
date = db.DateTimeProperty(required=True)
summary = db.TextProperty()
site_url = db.LinkProperty(required=True)
site_title = db.StringProperty(required=True)
データの型に関しては以下のページにある。
型とプロパティ クラス - Google App Engine - Google Code
# データを挿入する。
_entry = Entry(title=title,
link=link,
summary=summary,
date=_datetime,
site_url=site_url,
site_title=site_title)
_entry.put() # put() した時点でデータが入る。
# データを取得する。
# 全部取る場合。
ret = Entry.all()
# Where句を指定且つ一個だけ取得
ret = Entry.gql('WHERE link = :link', link='http://example.com/').fetch(limit=1)
# 並び替え。fetch は limit と offset を引数に与えれる。
ret = Entry.gql('order by date desc').fetch(20,30)
但し、一度に取得できるエントリ数は最大1000までの制限がある。offset で 1000以上を指定しても無駄とかどっかにあった気がする。
where や order by を行う代わりに、Query のインスタンスメソッドの filter() や order() を使用する事もできる。
詳しくは Query クラス - Google App Engine - Google Code を参照。
データの更新はやってないからパス。
webapp フレームワーク
webapp フレームワーク - Google App Engine - Google Codewebapp フレームワークはシンプルな Web アプリケーション フレームワークで、App Engine 向けの Python Web アプリケーション開発に使用できます。
だそうです。
kay とか Django とか使うのも良いのだけど、とりあえず最初なので webapp を使ってみた。
class get(webapp.RequestHandler):
def get(self, num):
hoge = self.request.get('hoge')
# 途中省略
self.response.out.write(contents)
# http://code.google.com/intl/ja/appengine/docs/python/tools/webapp/running.html
def main():
application = webapp.WSGIApplication(
[('/([0-9]*)', get),
('/getFeeds', getFeeds),
], debug=True)
util.run_wsgi_app(application)
if __name__ == '__main__':
main()
webapp.WSGIApplicationの一つ目の引数の書式は (URL, 実行するクラス) の形のタプル。
URL には正規表現を使用する事ができる。
get() にある num には webapp.WSGIApplication でグループに一致した値が入る。
もしくは、 self.request.get('hoge') で与えられたデータを取得できる。
データの取得方法については以下のページ
リクエスト データ - Google App Engine - Google Codeリクエストハンドラに使用できるメソッドは以下の7つ
get()
post()
head()
options()
put()
delete()
trace()
self.response.out.write(contents)
と書くと contents の中身を表示する。
今回は使ってないけど、リダイレクトとかヘッダーとかステータスコードを使用する場合は以下のページ
リダイレクト、ヘッダー、ステータス コード - Google App Engine - Google Codeテンプレート
webapp で使用できるテンプレートエンジンは Django のそれと同じ。
基本的なとこ
from google.appengine.ext.webapp import template
TEMPLATEDIR = os.path.dirname(__file__) + '/template/'
class hoge(webapp.RequestHandler):
def get(self):
template_values = {
'message' : 'hoge'
}
path = TEMPLATEDIR +'hoge.html'
contents = template.render(path, template_values)
self.response.out.write(contents)
/template/hoge.html
<p>{{ message }}</p>
if と for
{% if countRanking %}
<div>
<ul>
{% for item in itemlist %}
<li><a href="{{ item.url }}">{{ item.name }}</a></li>
{% endfor %}
</ul>
</div>
{% endif %}
block と 継承
hoge.html
<h1>{% block h1 %}ここにh1{% endblock %}</h1>
fuga.html
{% extends 'hoge.html' %}
{% block h1 %}ここの値が h1 に入る。{% endblock %}
Filter
一番下はカスタムフィルター。ちょっと前にブログに書いた。
GAE のテンプレートで Unicode 文字列を URLencode する。 - jkl.lomo.jp
{{ item.date|date:"M j, Y H:i:s" }}
{{ item.summary|striptags|slice:"128" }}
{{ item.title|unicode_urlencode }}
詳しくは Django のドキュメントを参考に。
Python プログラマのための Django テンプレート言語ガイド — Django v1.0 documentation
Django テンプレート言語 — Django v1.0 documentation
サービス
memcache と urlfetch しか使ってないのでそこだけメモ
memcache
from google.appengine.api import memcache
# 値をセットする。既に値が保存されていても上書きする。
memcache.set('hoge', hoge, time=3600)
# 値をセットする。既に値が保存されていたら上書きしない。
memcache.add('hoge', hoge, time=3600)
# 値を取得する。値が無ければ None を返す。
hoge = memcache.get('hoge')
ほかにもメソッドあるけど以下略
Memcache Python API - Google App Engine - Google Codeurlfetch
google app engine では外部と通信する場合は http もしくは https しか使えない様です。
from google.appengine.api import urlfetch
result = urlfetch.fetch(url)
if result.status_code is 200:
hoge(result.content)
URL Fetch Python API - Google App Engine - Google Code
とりあえず自分のメモはこれで終了。
Google App Engine は結構簡単にwebアプリケーションが作れるのでおぬぬめ。