投稿

ラベル(googleappengine)が付いた投稿を表示しています

Google App Engine in Django Hack-a-thon

Django Hack-a-thon Disc.8 に参加してきました。初!Google App Engine Hack-a-thon のチューターを担当させていただくことになったのですが、いい具合に何もしません(できません)でした・・・。どちらかというと参加者として、色々と勉強させていただいたのでお金を払ったほうがよかったような気もしています。とりあえず、勉強させていただいたこととかを書いておきます(笑)。私がやったことは2つ。 HTML を解析し、Web API として利用できるようにするための Python ライブラリーを書く Django on Google App Engine で Twitter の oAuth を使うアプリを書く 午前中書いてた Python ライブラリーは仕事のコードなので(汗)公開できませんが、HTML解析でWebサービスを操作するためのものです。それも全然 valid じゃない html ・・・・。最初は BeautifulSoup でやろうと思っていたのですが、Parse Error となるのであえなく断念。一応フォーマットは決まっているようだったので、正規表現を使うことにしました。 >>> import re >>> import urllib2 as urllib >>> url = 'http://google.com/' # 例だす >>> opener = urllib2.build_opener() >>> html = opener.open(url).read() # [html が出力される] >>> print html # 取得したhtmlが出力される >>> # 適当にhrefタグ内を取り出す >>> p = re.compile(u"href=\"(?P<link>[\w:/?&.-_%]+)\"",re.I) >>> # shift_jis はそのページのエンコード >>> for link in p.findall(unicode(htm...

App EngineでTweet @ GAE Hackathon

昨日、 Google App Engine Hackathon Disc.3 に参加してきました。わたくしはTutorial Aで外部データとの連携をがむばることに。 テーマは、 Python Twitter というライブラリーを使って、GAEからTwitter API(JSON)をコールしてみようというもの。必要なライブラリーは、 Python Twitter と simplejson の2つです。 Python Twitter はデフォルトのままでは動きません。動作するように書き換えたやつを、 ハカソンリポ にコミットしております。だいぶひどい修正です。主な変更点は以下のとおり。 1487行目 のDiff def _GetUsername(self): - return os.getenv('USER') or \ - os.getenv('LOGNAME') or \ - os.getenv('USERNAME') or \ - os.getlogin() or \ - 'nobody' + return 'nobody' 1394行目 のDiff def _FetchUrl(self, url, post_data=None, parameters=None, no_cache=None): - # Build the extra parameters dict - extra_params = {} - if self._default_params: - extra_params.update(self._default_params) - if parameters: - extra_params.update(parameters) - - # Add key/value parameters to the query string of the url - url = self._BuildUrl(url, extra_params=extra_params) - - # Get a url opener that can handle basic auth - ...

The Django Book 2.0 (日本語) の公開について

The Django Book (日本語)サイト Djangoを使い始めて1年もたたないけど、最初に The Django Book と出会えてほんとによかったと思っています。Django 1.0が出て、 The Django Book 2.0 の執筆が開始されました。ということで、翻訳することにした。これを読んで、1人でも多くの方がDjangoを触ってくれると幸せですね。ただし、英語が苦手なので、翻訳がボロボロだと思います。がしがしフィードバックしてください。 先日 app-engine-patchの記事 を書いたついでに、この本もapp-engine-patchを使って公開しています。内部はReSTructuredTextを sphinx でpickle化し、それを表示しているだけです。はい、app-engine-patchの機能(adminインターフェースとか)はまったく使っていま(ry。 ついでに、ソースもBitbucketで 公開 しました。

app-engine-patchを使ってみた

id:voluntas さんに、「 Helper だけじゃなくて patch も使え。むっちゃいい!」とごり押しされたので、app-engine-patchを触ってみることにしました。結論からいうと、AppEngineにデプロイするDjango使いはpatchを使うとかなり幸せになれる。ほぼ、まんまDjangoの機能が使えます。 manage.py で (runserver, test, flush, ...) が使える manage.py updateでGoogleにアップロードできる adminインターフェースが使える authミドルウェアが使える Userモデルがそのまんま使える Generic viewsが使える Content typesが使える(Generic以外) content_type = FakeModelProperty(ContentType, required=True) あと、ragendjaというユーティリティが入っていて、これも便利なAPIをたくさん提供してます。 ragendja.dbutils.get_object_or_404(), get_list_or_404():GAEモデルに対応してる ragendja.dbutils.db_create(), db_add():でBigTableを(安全に)処理 ragendja.dbutils.その他:リレーションに便利なAPIがいっぱい regendja.testutils.*:テストまでできちゃう 他にもたくさんあり(すぎ)ます これは使えるw

PolyModel @ Timeline

先日のGoogle App Engineの SDK1.1.8のリリース で、PolyModelが使えるようになったので、さっそくGAWareで使うことにした。今までは、TimelineとImageはBaseModelで作っていた。そして、書きソース( Pastebin で見る)のように、一度Imageを積み込み、そのkey().id()をTimelineのIntegerPropertyに突っ込んでた。そして取得するときは、 image = Image.get_by_id(timeline.photo) という風に取得していた。 from appengine_django import models from google.appengine.ext import db class Timeline(models.BaseModel): """ Usage:: user = users.get_current_user() message = 'test' timeline = Timeline(author = user, message = message) timeline.save() """ author = db.UserProperty() message = db.StringProperty(_('message'), required=True) photo = db.IntegerProperty() class Image(models.BaseModel): author = db.UserProperty(required=True) # image data = db.BlobProperty(required=True) format = db.StringProperty(required=True) from google.appengine.api import users, images from django.core.files.uploadedfile import SimpleU...

Bitbucketへ移行

GAWare , django-on-gae をbitbucketへ移行しました。動作が軽快だし、あと気軽にforkしていただけるのが魅力的(笑)。git使ってた時に、*.pycまでコミットしちゃってたので、今回は.hgignoreを書いて、色々とコミットするファイルを制限した。 # use glob syntax. syntax: glob *.pyc *.pyo *~ .*.swp *.kpf # switch to regexp syntax. syntax:regexp /\. DS_Store まず、globで拡張子がpyc, pyo, swp, kpfなファイルをコミットしないようにした。swpはvimのスワップファイル。kpfはkomodo edit用のプロジェクトファイル。テンプレート書くときとかはkomodo使っちゃうんだよね。あとregexpでMercurialが使うファイルと、マックの隠しファイルDS_Storeをコミットしないようにした。マカーじゃないんだけどね。

DjangoのModelで複数のフィルターを利用する場合のTips

id:Voluntas が、早速コードレビューしてくださった。6つぐらいるけど、今日はとりあえず、Modelのリファクタリングのアドバイスを実装した。diffは ここ 。 timeline = Timeline.all() timeline = timeline.filter('author =', user) timeline = timeline.filter('group =', group) と今まで書いていたけど、Pythonは長いコードを' \ 'を使って改行できる。それを利用し、Modelで複数のfilterを利用する場合でも以下のように書く。 timeline = Timeline.all() \ .filter('author =', user) \ .filter('group =', group) 他にも色々とアドバイスを頂いているので、コードを見やすくしていくことにする。 Special thanks voluntas.

GAE SDK 1.1.8 リリース

Google App EngineのSDK 1.1.8が リリース されました。 id:Voluntas , Ian がブログで解説してますね。 PolyModel がサポートされました。 UserProperty に auto_current_user / auto_current_user_addが追加 Image API に width/heightが追加 あとはバグフィックスとか PolyModelのドキュメントより、以下のような使い方ができます。 from google.appengine.ext import db from google.appengine.ext.db import polymodel class Contact(polymodel.PolyModel): phone_number = db.PhoneNumberProperty() address = db.PostalAddressProperty() class Person(Contact): first_name = db.StringProperty() last_name = db.StringProperty() mobile_number = db.PhoneNumberProperty() class Company(Contact): name = db.StringProperty() fax_number = db.PhoneNumberProperty() p = Person(phone_number='1-206-555-9234', address='123 First Ave., Seattle, WA, 98101', first_name='Alfred', last_name='Smith', mobile_number='1-206-555-0117') p.put() c = Company(phone_number='1-503-555-9123', address='P....

GAWare 公開

AppSpotで公開している GAWare のソースコードをGPLライセンスで公開し始めました。コメントを入れたやつから公開していきます。コードが長いし、読みにくいですがご容赦ください(汗)。まだスラグ用の正規表現フィールド等はデバッグしてません…。コードレポは迷ったんですが、 Google Code を使っています。そのうち、bitbucketあたりに移行するかもしれません。バグとか、コーディングのアドバイス等色々突っ込んでいただけると喜びます。

GAWare (like twitter) 公開

知識が不足しすぎているので、公開までだいぶ時間がかかったけど、Twitter ライク なアプリを公開した。Django on Google App Engineで動作しています。まだ、荒削りだし、未実装の機能があるけど、メインの機能は動作している。ちなみに、 http://ware.appspot.com/ で公開している。 主な機能は以下。 ユーザ登録、プロフィール設定、アバター設定、メール通知(未実装)設定 グループ作成、グループ設定、アバター設定、メンバー管理 タイムラインの登録、お気に入り登録(未実装)、写真登録、タギング プライベートメッセージ ユーザ、グループそれぞれプロテクト機能 アプリ自体の公開、非公開(Google Appsユーザ用)設定 投稿ファイル制限(マイムタイプ) などなど。後々はGoogle Appsユーザ用にオープンにしたいけど、今のソースはとてもじゃないけど公開できない(笑)。そもそも公開されてもコメントもロギングもしてないし、可読性が低すぎるので、「えっ?」って感じだと思う。今後の目標は、 ローカライズ ロギング ソースの整備 未実装機能の実装 です。あと、いろんなサービスを登録できるようなのも勉強中。 Web APIとか、OpenSocialとか、FriendConnectとか。亀のようなスピードですが・・・。

GAE Hackathon vol.2 & Python忘年会

だいぶ遅くなったけどまとめてBlogする。第2回Google App EngineのHackathonに行ってきました。今回は少人数のチームに分かれて、各チームにテーマが与えられました。私が参加していたチームのテーマはモデル。最近はBigTableにもなれてきましたが、やっぱりRDBMSじゃないし、クエリーが発行できるのも = 、 < 、 > のみ。また、日本語の検索自由度はないに等しい(どうやらGAE HackathonでSearch APIをもうすぐリリースするという情報が!)。そこで、日本の郵便番号住所の情報を検索可能なモデルを作成することにした。分かち書きして、そのリストを保有するという選択肢もあるのだが、今回は前方一致、後方一致検索ができるようなモデルを作成することにした。"東京"、"東京都"、"新宿区"、"西新宿"とかで検索可能にしたい。色々と悩んだ結果、 str を list で分割し、位置も実図連結してStringListPropertyに突っ込むことにした(相当荒業)。ソースは ここ においた。Modelのputをフックし、リファレンスが張ってある別Modelに文字列のリストを保存している。時間は短かったですが、わいわい楽しいコーディングができましたよ! それと、グルーの tmatsuo さんより、前方一致のテクニックを教わった。 db.GqlQuery('SELECT * FROM Test WHERE w >= :1 and w < :2', word, word + u'\uFFFD') というコード。その文字以上かつ、ユニコードの最大文字である '\uFFFD' 以下の文字で比較するというもの。これはありがたく使わせていただきます。special thanks tmatsuo! あと、いつもお世話になっている id:Voluntas さんが幹事の Python忘年会 に参加しました!この会、いつもメンバが濃い。ちょっとびびってた mopemope さんがすごい優しい人で、あまりのギャップにやられました(笑)。っていうかmopemopeさんが忘年会の前に勉強会を開くという話だったので、楽しみに...

BigTableはPUSH型で

BigTableで悩む で書いたけど、Twitterで id:Voluntas さんからアドバイスを頂きました。 PULL型じゃなくてPUSH型で書く timelineに db.ListProperty(db.Key) でメッセージを受信するユーザを保持 ということでPULL型で作っていたのをフルスクラッチしたいと思います。 id:Voluntas さんありがとうございます。最初からちゃんとBigTableのこと調べてから設計すべきwww

BigTableで悩む

GAEでTwitterライクなアプリを作ってるんだけど、BigTableのリレーションで悩んでる。モデルは以下のようにした。ちなみに Zipped Django 1.0 on GAE with Helper をベースにしている。 # models.py class User(BaseModel):   user = db.UserProperty(required=True)   follow = db.ListProperty(db.Key) # User model   send = db.ListProperty(db.Key) # Item model 送信したItem   receive = db.ListProperty(db.Key) #Item model 受信したItem class class Item(BaseModel):   text = db.StringProperty(required=True) # 送信したtxt   published = db.DateTimeProperty(required=True, auto_now_add=True) # 送信したtxt 上記モデルから、"自分がFollowしたUserの全てのItem+自分が受信したItem"、"自分が受信したItem"、"自分が送信したItem"を(Twitterみたいにw)取得したい。そこで以下のように抽出する。 # views.py def received (request): # 自分が受信したItem   user = User.all().filter('user =',users.get_current_user())   items = Item.get(profile.receive) def sent (request): # 自分が送信したItem   user = User.all().filter('user =',users.get_current_user())   items = Item.get(pro...

Zipped Django on GAE with Helper

Zipimortを使ってApp EngineでDjango 1.0を利用する でGAEにZipアーカイブされたDjango 1.0を使う手順を翻訳したけど、ついでに既存のDjangoアプリをそのまんま乗っけちゃうために Google App Engine Helper for Django を使いたい。ということで、テンプレートを作りました。 Github に置いときます。適当にforkして使っちゃって下さい。ここはHelper、Djangoがバージョンアップするつど更新していきたいと思います。今回使ったバージョンは以下のとおりです。 Django 1.0 Google App Engine Helper for Django r66 この テストサイト で動かしています。Django 1.0を使いたい方は djangoproject.jp の皆様がドキュメントを翻訳して下さってますので、 ここ をご参考にしてください。

Zipimortを使ってApp EngineでDjango1.0を利用する

" Using Django 1.0 on App Engine with Zipimport "の日本語訳。訳がおかしいところはコメントください。 はじめに App EngineのアプリケーションでPython Webアプリケーションフレームワークを使うことは、アプリケーションフレームワークで使っているコードを取り込むぐらい簡単です。しかし、アプリケーションがアップロードできるファイルには制限があり、いくつかのフレームワークで制限を超えてしまう場合や、アプリケーションコードを書く余裕がない場合があります。この場合、App Engine リリース 1.1.3からサポートされているPythonの"zipimport" で解決することができます。 この記事では、Google App Engineに"zipimport"を使ってDjango 1.0を使用するための解説をします。 Zipimortの導入 アプリケーションにモジュールをインポートする際、Pythonはいくつかのディレクトリーの中からそのモジュールのコードを探します。PythonコードからPythonチェックするディレクトリーのリストを変えるには sys.path を使用します。App Engineがインクルドするパスは、App Engine APIとアプリケーションのルートディレクトリーです。 sys.path のアイテムでZipフォーマットのアーカイブを指定することで、Pythonはそのアーカイブをディレクトリーとして扱います。アーカイブは1つ以上のモジュールを含む.pyソースコードを含みます。この機能はzipimportという標準ライブラリーのモジュールでサポートされており、このモジュールはデフォルトのインポートプロセスの1つであるため、このモジュールを使うために直接このモジュールをインポートする必要はありません。zipimportに関する詳しい情報に関しては、 zipimportドキュメント を参照してください。 App Engineでモジュールアーカイブを使う方法: バンドルしたいモジュールのZipフォーマットのアーカイブを作る アプリケーションディレクトリーにアーカイブを入れる 必要な場合はハンドルしたスクリプトを sys.path に追加...

Python温泉@熱海

イメージ
Python温泉@熱海 Voluntas さんが主催する Python温泉 に行ってきました。コアな方が集まっていてだいぶ刺激受けました。ちょっと風邪気味で途中熱っぽかったので、部屋にこもってしこしこコード書いてました。温泉は気持ち良かったです。それと、なんと アクセンステクノロジー さんから抽選会(じゃんけん)でPythonのマスコットを頂きました!いつもはじゃんけん弱いのに、もっすご良いとこでじゃんけんに勝てました。我が家のマスコットコレクションが増えて大満足www今回のPython温泉でのテーマは、 GAEでZipped Django1.0を使う GAE+Djangoで画像のアップローダを作る です。目標はなんとかクリアでき。ちょっとずつアプリが出来上がってきました。もう少しで公開したいと思ってます。Python温泉むちゃ勉強になります。さっそく来年も参加申し込みしときました。

Google App EngineがJavaをサポート

この ブログで紹介されていますが、Google Developper Day 2008でGoogleがGAEにJavaをサポートさせたようですね。GAE4JとかJ4GAEとかGoogle Groups内でも賑わっています。同時に、Androidがオープンソースになったそうです。色々と目まぐるしいですが、俺はしばらくPython on GAEに夢中だと思います。