Google Appengine 1.4.3
水曜日に Google Appengine 1.4.3 がリリースされました! 1.4.1 と 1.4.2 はブログ記事を書くほど 大きくはなかったのですか、 1.4.3 はまたいろいろ入っているので、ご紹介します。
Prospective Search API
以前、 Matcher API のブログ記事 を書きましたが、 Trusted Tester リリースで出ていた Matcher API は 「Prospective Search API」という名前で開発者全員にリリースされています。 まだ、Labs機能で、正式リリースではない様ですけど、 モジュール名が変わっています。
from google.appengine.api import prospective_search
def add_tweet_alert(user, tweet_text):
# クエリーはMapper API のクエリー言語を使う
# 参考: http://code.google.com/p/google-app-engine-samples/wiki/AppEngineMatcherService#Query_Language
query = 'text:"%s"' % tweet_text
# 読者IDはユニーク化しないといけないので、user_id と テキストから作る
subscribe_name = "%s:%s" % (user.user_id(), tweet_text)
# dict もしくは、 db.Entity オブジェクトで登録すると、スキーマが必須です。
# 参考: http://code.google.com/p/google-app-engine-samples/wiki/AppEngineMatcherService#Document_Schema
schema = {
'str': 'text',
}
# dict もしくは、 db.Entity オブジェクトで登録すると、スキーマが必須です。
# topic はデータスキーマの名前という意味がします。
topic='Tweet'
prospective_search.subscribe(dict, query, subscribe_name, schema=schema, topic=topic)
def remove_tweet_alert(user, tweet_text):
query = 'text:"%s"' % tweet_text
subscribe_name = "%s:%s" % (user.user_id(), tweet_text)
topic='Tweet'
prospective_search.unsubscribe(query, subscribe_name, topic=topic)
matcher
というモジュールが、 prospective_search
というモジュール名になった意外は、特に大きいな変更はなさそうですね。
Testbed
Testbed はテストを実行できるために、 Appengine 環境を偽装するものです。 開発サーバーみたいに、 Appengine本番にデプロイせずに、ローカル環境で、Memcached、 Datastore などの Appengineのサービスが テストの中に使えます。
import unittest
from google.appengine.ext import testbed
class TestModel(db.Model):
"""A model class used for testing."""
number = db.IntegerProperty(default=42)
text = db.StringProperty()
class DemoTestCase(unittest.TestCase):
def setUp(self):
# Testbedクラスインスタンスを生成
self.testbed = testbed.Testbed()
# Testbed を活性化させる
self.testbed.activate()
# 使用するサービススタブを設定する。
self.testbed.init_datastore_v3_stub()
self.testbed.init_memcache_stub()
def tearDown(self):
# クリーンアップ
self.testbed.deactivate()
def testInsertEntity(self):
""" モデル格納のテスト """
TestModel().put()
self.assertEqual(1, len(TestModel.all().fetch(2)))
デフォールト環境変数も設定できます。
class DemoTestCase(unittest.TestCase):
def setUp(self):
self.testbed.setup_env(app_id=application-id)
self.testbed.activate()
self.testbed.init_datastore_v3_stub()
# ...
テストを実行するために、テストランナーが必要です。 gaeunit
、もしくは、 nose-gae のテストランナー
を使うことが出来ます。 簡単な例は以下のテストランナー。 unittest2
が必要なので、まずそれをインストールする必要があります。
#!/usr/bin/python
import optparse
import sys
# Install the Python unittest2 package before you run this script.
import unittest2
USAGE = """%prog SDK_PATH TEST_PATH
Run unit tests for App Engine apps.
SDK_PATH Path to the SDK installation
TEST_PATH Path to package containing test modules"""
def main(sdk_path, test_path):
sys.path.insert(0, sdk_path)
import dev_appserver
dev_appserver.fix_sys_path()
suite = unittest2.loader.TestLoader().discover(test_path)
unittest2.TextTestRunner(verbosity=2).run(suite)
if __name__ == '__main__':
parser = optparse.OptionParser(USAGE)
options, args = parser.parse_args()
if len(args) != 2:
print 'Error: Exactly 2 arguments required.'
parser.print_help()
sys.exit(1)
SDK_PATH = args[0]
TEST_PATH = args[1]
main(SDK_PATH, TEST_PATH)
それで、スクリプトを実行すれば、プロジェクトの test*.py
でテストケースを探して来て、テストを実行することができます。
モジュール、もしくは、テストクラスを指定することもできます。
python testrunner.py demo.tests.DemoTestCase
ファイルAPI
ファイルAPI で Appengine の Blobstore にファイル読み込み、書き込みができます。 レポートの生成、データインポートなど、 ファイルシステムに必要なことに使えます。
from __future__ import with_statement
from google.appengine.api import files
# ファイル作成
file_name = files.blobstore.create(mime_type='application/octet-stream')
# ファイルの中身を書き込む
with files.open(file_name, 'a') as f:
f.write('data')
# ファイルデータを格納 (flush)
files.finalize(file_name)
# Blob キーを取得
blob_key = files.blobstore.get_blob_key(file_name)
Cron と Task キューのヴァージョン指定
Cron ジョブを実行するアプリケーションバージョンを指定することができるようになりました。 cron.yaml
の target
プロパティでバージョン名を指定します。
cron:
- description: new daily summary job
url: /tasks/summary
schedule: every 24 hours
target: version-2
キューの定義でも、あるキューのタスクがどのバージョンで実行されるかを queue.yaml
の target
プロパティで指定できます。
queue:
- name: my-queue
rate: 20/s
bucket_size: 40
max_concurrent_requests: 10
target: version-2
まとめ
このリリースも結構大きくて、いろいろ改善されています。 ファイルAPIを 早速触ってみたいところです。