fixtureをGoogleAppEngineのDataStoreテストで使う。json編
参考 Using Fixture To Test A Google App Engine Site
DataSetsをjson化するのにfixture.dataset.converterでdataset_to_jsonが提供されていたりもする。ただdate_created(auto_now_add=True)のようなフィールドはDataSetsで前もって値を指定できないので、ここでjson化したデータを、実際(date_createdの付いた)のjsonのレスポンスと比較しても同じにはならない。
.zshrc
gaedir=/usr/local/google_appengine |
if [ -d $gaedir ] ; then ; |
export PATH=${PATH}:$gaedir |
export PYTHONPATH=${PYTHONPATH}:${gaedir}:${gaedir}/lib/antlr3:\ |
${gaedir}/lib/cacerts:${gaedir}/lib/django:${gaedir}/lib/ipaddr:\ |
${gaedir}/lib/webob:${gaedir}/lib/yaml/lib |
app.yaml
application: sampleblog # _ はapplicationの識別子として使えないので注意 |
blog.py
from google.appengine.ext import webapp |
from google.appengine.ext.webapp.util import run_wsgi_app |
from google.appengine.ext import db |
from django.utils import simplejson |
title = db.StringProperty() |
date_created = db.DateTimeProperty(auto_now_add = True ) |
entry = db.ReferenceProperty(Entry) |
comment = db.TextProperty() |
date_created = db.DateTimeProperty(auto_now_add = True ) |
class EntriesHandler(webapp.RequestHandler): |
self .response.headers[ 'Content-Type' ] = 'application/json;charset=utf-8' |
for entry in Entry. all (): |
for comment in Comment. all (). filter ( "entry =" , entry): |
dict (comment = comment.comment, |
date_created = comment.date_created.isoformat()) |
comments.append(comment_dict) |
entry_dict = dict (title = entry.title, |
date_created = entry.date_created.isoformat(), |
entries.append(entry_dict) |
json = simplejson.dumps(entries, indent = True ) |
self .response.out.write(json) |
routing = [( '/entries' , EntriesHandler)] |
application = webapp.WSGIApplication( |
run_wsgi_app(application) |
if __name__ = = '__main__' : |
tests/datasets.py (http://fixture.googlecode.com/hg/fixture/examples/google_appengine_example/tests/datasets.py)
from fixture import DataSet |
class EntryData(DataSet): |
title = "Monday Was Great" |
class CommentData(DataSet): |
entry = EntryData.great_monday |
entry = EntryData.great_monday |
load_data_locally.py
(http://fixture.googlecode.com/hg/fixture/examples/google_appengine_example/load_data_locally.py)一部修正
from fixture import GoogleDatastoreFixture |
from fixture.style import NamedDataStyle |
p = optparse.OptionParser(usage = "%prog [options]" ) |
default = "/tmp/dev_appserver.datastore" |
p.add_option( "--datastore_path" , default = default, help = ( |
"Path to datastore file. This must match the value used for " |
"the same option when running dev_appserver.py if you want to view the data. " |
"Default: %s" % default)) |
default = "/tmp/dev_appserver.datastore.history" |
p.add_option( "--history_path" , default = default, help = ( |
"Path to datastore history file. This doesn't need to match the one you use for " |
"dev_appserver.py. Default: %s" % default)) |
default = "/usr/local/google_appengine" |
p.add_option( "--google_path" , default = default, help = ( |
"Path to google module directory. Default: %s" % default)) |
(options, args) = p.parse_args() |
if not os.path.exists(options.google_path): |
p.error( "Could not find google module path at %s. You'll need to specify the path" % options.google_path) |
groot = options.google_path |
sys.path.append(os.path.join(groot, "lib/django" )) |
sys.path.append(os.path.join(groot, "lib/webob" )) |
sys.path.append(os.path.join(groot, "lib/yaml/lib" )) |
from google.appengine.tools import dev_appserver |
from tests import datasets |
config, explicit_matcher = dev_appserver.\ |
LoadAppConfig(os.path.dirname(__file__), {}) |
dev_appserver.SetupStubs( |
datastore_path = options.datastore_path, |
history_path = options.history_path, |
datafixture = GoogleDatastoreFixture(env = { 'EntryData' : blog.Entry, |
'CommentData' : blog.Comment}) |
data = datafixture.data(datasets.CommentData, datasets.EntryData) |
print "Data loaded into datastore %s" % \ |
(options.datastore_path or "[default]" ) |
if __name__ = = '__main__' : |
tests/test_entries.py
from fixture import GoogleDatastoreFixture |
from webtest import TestApp |
from datasets import CommentData, EntryData |
from django.utils import simplejson |
datafixture = GoogleDatastoreFixture(env = { 'EntryData' : blog.Entry, |
'CommentData' : blog.Comment}) |
class TestListEntries(unittest.TestCase): |
self .app = TestApp(blog.application) |
self .data = datafixture.data(CommentData, EntryData) |
response = self .app.get( "/entries" ) |
assert simplejson.dumps(EntryData.great_monday.title) in response |
assert simplejson.dumps(EntryData.great_monday.body) in response |
assert simplejson.dumps(CommentData.monday_liked_it.comment) \ |
assert simplejson.dumps(CommentData.monday_sucked.comment) \ |
Create custom datasets.
$ ./load_data_locally.py --datastore_path=./my.datastore |
Run server with custom data.
$ dev_appserver.py . --datastore_path=./my.datastore |
Run tests.
$ nosetests -v --with-gae |
test_entries (tests.test_entries.TestListEntries) ... ok |
---------------------------------------------------------------------- |
Posted: May 26th, 2010 | Author: yamakk | Filed under: 技術 | Tags: database, fixture, gae, googleappengine, json, python | No Comments »
Google App EngineでTwitter OAuthを使う。
自分のタイムラインを取得してtweetできるまでのサンプル。
参考
tweepyでtwitterの3-legged OAuth認証を試してみた(GoogleAppEngine)
コードのなかで使用しているsimple_cookieは
Google Cookbook – Google App Engine A simple Cookie class のもの。
注意する点は
Twitter application settingでcallback URLを正しく設定すること。

callback URLに127.0.0.1を指定しているからかもしれないけど、なにも入力しないと
TweepError: HTTP Error 401: Unauthorized になる。
tweepy
はapp engineのディレクトリにモジュールのディレクトリをコピーして使った。
以下サンプルコードと実行
Read the rest of this entry »
Posted: May 23rd, 2010 | Author: yamakk | Filed under: 技術 | Tags: gae, google, oauth, tweepy, twitter | No Comments »