ラベル Google App Engine の投稿を表示しています。 すべての投稿を表示
ラベル Google App Engine の投稿を表示しています。 すべての投稿を表示

2015年2月19日木曜日

Google App Engine : ndb のデータを JSON 化する + json.dumps を date 対応させる


このエントリーをはてなブックマークに追加
MyModel.query().fetch() などで ndb.Model を取得した後、ndb.Model の to_dict() 関数を使用して json 化します。

to_dict() には key が含まれないので、key が必要な場合には明示的に追加します。


fetched_list = MyModel.query().fetch()
json_without_keyid = json.dumps([c.to_dict() for c in fetched_list ])
json_with_keyid = json.dumps([dict(c.to_dict(), **dict(id=c.key.id())) for c in fetched_list ])


追記

数字や文字列のみの場合上記のコードで問題なかったのですが、
DateProperty を使用していた Model は

File "C:\Python27\lib\json\encoder.py", line 184, in default
raise TypeError(repr(o) + " is not JSON serializable")
TypeError: datetime.date(2015, 2, 20) is not JSON serializable

というエラーで json 化に失敗してしまいました。
そこで、以下のように、date オブジェクトの場合の処理を追加した JSONEncoder を作成し、対応を加えました。datetime の場合なども同じような方法で対応できるはずです。


from datetime import date

class JSONDateEncoder(json.JSONEncoder):
    def default(self, obj):
        if isinstance(obj, date):
            return obj.isoformat()
        return json.JSONEncoder.default(self, obj)


fetched_list = MyModel.query().fetch()
json_without_keyid = json.dumps([c.to_dict() for c in fetched_list ], cls=JSONDateEncoder)
json_with_keyid = json.dumps([dict(c.to_dict(), **dict(id=c.key.id())) for c in fetched_list ], cls=JSONDateEncoder)


参考:AppEngine Making ndb models json serializableHow to overcome “datetime.datetime not JSON serializable” in python?

2013年8月13日火曜日

Google App Engine - That user can undo the transaction with "appcfg rollback"


このエントリーをはてなブックマークに追加
Deploy 中に Google App Launcher を閉じてしまったところ、タイトルのようなメッセージが出て Deploy に失敗するようになりました。プロジェクトのフォルダでコマンドプロンプトを開いて、以下のコマンドを実行して解決。
appcfg.py rollback ./
解決方法を提示してくれてる時点で大分ありがたいけどもう一声、
実行もワンボタンでできるようになってればいいのになー。

2013年8月7日水曜日

GAE - DataStore でデータが重複して登録されるのを防ぐ


このエントリーをはてなブックマークに追加
重複を防ぎたい内容を id に指定してデータを作成すると、同じ id の物は上書きになるので複数登録されなくなります。

2013年8月3日土曜日

Python + Google App Engine で Twitter から呟く


このエントリーをはてなブックマークに追加
リマインダーや Tips を呟く自分専用の BOT を作ろうと思ってやってみました。
python-twitter を使います。
ライブラリの設定などで躓いたところをメモしておきます。

ライブラリの設定


python-twitter は simplejson, oath2, httplib2 が必要なので、これらのライブラリを Google App Engine(GAE) 上のプロジェクトで実行できるようにします。ライブラリのコードをプロジェクトに入れることで解決しました。

  • プロジェクトのルートディレクトリに python-twitter ライブラリの build/lib から持ってきた tiwtter.py を置きます。
  • oath2 ライブラリの build/lib 以下にある oath2 ディレクトリをルートディレクトリに置きます。
  • httplib2 ライブラリの build/lib 以下にある httplib2 ディレクトリを oath2 ディレクトリの下に置きます。
  • simplejson ライブラリの build/lib 以下にある simplejson ディレクトリをルートディレクトリに置きます。

最終的なディレクトリ構成は以下のとおりになりました。
│  app.yaml
│  cron.yaml
│  favicon.ico
│  index.yaml
│  main.py
│  twitter.py
│
├─oauth2
│  │  _version.py
│  │  _version.pyc
│  │  __init__.py
│  │  __init__.pyc
│  │
│  ├─clients
│  │      imap.py
│  │      smtp.py
│  │      __init__.py
│  │
│  └─httplib2
│          cacerts.txt
│          iri2uri.py
│          iri2uri.pyc
│          socks.py
│          socks.pyc
│          __init__.py
│          __init__.pyc
│
└─simplejson
    │  compat.py
    │  decoder.py
    │  encoder.py
    │  ordered_dict.py
    │  scanner.py
    │  tool.py
    │  _speedups.c
    │  __init__.py

python は __init__.py があるフォルダをライブラリのフォルダとして認識するので、これで twitter.api からは oath2 と simplejson が見えるようになり、oath2 からは httplib2 が見える…という寸法です。

twitter.Api のキャッシュの無効化


Google App EngineでTwitter(OAuth対応)を使うためのメモ

参考サイトから引用すると
Google App Engineでは、スタティックなファイルを作成等はできない。python-twitterはキャッシュとして、ファイルを作るために、そのままでは動作しない。APIオブジェクトを作成する際にcache=Noneをキーワードとしてつけておくこと。
です。なので、twitter.Api オブジェクトを作成するときは
api = twitter.Api(consumerKey, consumerSecret, accessToken, accessSecret, cache=None)
のようにして cache を無効化してオブジェクトを作成します。

アカウントの登録


BOT 用のアカウントを登録します。
PythonでTwitter BOTを作る を参考にしました。

ソースコード


GAE の URL にアクセスしたときに呟きます。これを cron の JOB に登録すれば、一定時間毎に呟く事が可能になります。
cron.yaml は以下の様な感じ。頻度は適当に。
cron:
- description: job
  url: /
  schedule: every 2 hours
あとは呟く内容を変える仕組みを作れば、自分専用の BOT としては形になりそうです。