rayphe - 軽量Python web framework

  • 2010-2-10: v0.3.0リリースしました。またプロジェクト名を変更しています。

ちょっと前にRubyでSinatraが取り上げられて、結構注目されたように思います。ということはRailsだと大げさすぎるなあ、と思うような場合に対する需要というのはやっぱりそれなりにあるんですよね。

Pythonで軽量、というとweb.pyが一番有名ですよね。他にはJunoBottleなんかがあります。

このブログで使っているのはweb.pyです。結構昔から使っています。が、不満もおおくweb.pyを拡張するようなライブラリを作っていて、それがそこそこの量あったりします。

そこで、これくらい量があるなら自分でフレームワーク作っても大してかわんなくね?と思い始めました。あれ、そういえば俺、テンプレートエンジンもつくっちゃってるじゃん、簡易O/Rマッパも自分用につくってあるじゃん、と次々に気づき始め、それらをまとめて作っちゃいました。軽量フレームワーク。

rayphe

「rayphe」はPython用軽量ウェブフレームワークです。ルーティング、テンプレート、O/Rマッパなどが1ファイルにまとめられていて、依存するライブラリもありません。

また、共通の処理をまとめる「フィルタ」があったり、やアプリケーションの各フェーズをフックできたりと柔軟です。

raypheはGitHubにおいてあります。それなりにドキュメントも書いていて、テストもしてあります。詳しくは以下をどうぞ。

たとえば、サンプルアプリのコードの一部はこんな感じです。

python code
  1. with app.filter([context_setup_filter, {"except":["static_file"]}]):
  2.   @app.get("static/(unicode:.*)")
  3.   def static_file(c, path):
  4.     c.res.send_file(os.path.join(app.static_path, path.replace("..", "")))
  5.  
  6.   @app.get("")
  7.   def index(c):
  8.     c.res.redirect(app.url.show_pages())
  9.  
  10.   @app.get("page/(int:\d+)")
  11.   def show_page(c, page_id):
  12.     c.page = app.db.select_one_by_id(Page, page_id)
  13.     c.title += c.page.title
  14.     c.comments = app.db.select([Comment],
  15.       cond="page_id=? order by created_at asc",
  16.       values=[page_id])
  17.     c.comment = getattr(c, "comment", Comment(name="", body=""))
  18.     return app.renderer.show_page({"c":c})
  19.  

という感じでわかりやすくかけます。また、「単純化しすぎない」ということにも気を使っていたりします。selfと書くのが好きなPythonistaらしく、status 404とかじゃなくc.res.notfound()です。

というわけで

Pythonで小さなウェブアプリをつくるときは是非。

03.02.10/04am

Python版Yahooテキスト解析 APIライブラリをキーフレーズ抽出に対応させました

しました。

ダウンロード

yahooapi

使い方

python code
  1. import yahooapi.jlp
  2. client = yahooapi.jlp.KeyphraseServiceAPI("apikey")
  3. result_obj = client.extract(sentence=u"東京ミッドタウンから青山一丁目駅まで歩いて15分かかります")
  4. for result in result_obj.Result:
  5. print result.Keyphrase
  6.  
  7. # => 東京ミッドタウン
  8. # => 青山一丁目駅
  9. # => 15分
  10.  

うむ。

01.06.10/12am

Python: 勉強がてらDHT(Kademliaっぽいもの)を実装しました

前々から一度じっくり勉強しないとなぁと思っていたDHTまわりの勉強がてらKademliaっぽいものをPythonで実装してみました。

Kademliaはいろいろ実装があるので、ソースを読んじゃうと答えみちゃった感じになるかなーと思って、元論文と首藤様の資料くらいしか見ずに実装してみました。ので、いろいろ間違ってるかも知れませんが・・・。

本家Kademliaとの主な違いは

  • UDPではなくTCPを使っている
    • ローカル環境しかもっていないので、UDPパケットがロスしやすい場合(WAN)を想定して実装するのがめんどくさい。
    • よってRPC-IDをつけていない。
    • パケットの分割や再送もTCPにおまかせ。
  • original publisherから一定時間publishを受けなくてもインデックス情報をexpireしていない
    • 実装するのは簡単です。
  • ノードがネットワークに参加したとき、Index情報を移動させていません
    • これも実装は簡単です。

ダウンロード

適当なのですが、置いておけば誰かの役に立つこともなきにしもあらず、かもしれないので置いておきます。jsonつかっているので2.6以上で動きます。

実装について

以前Chordもちょっと実装したことがあるのですが、やっぱりいろんなソフトで採用されているだけあって、Kademliaはかなり実装が楽ですね。論文読んで素直に実装すれば動きます。

えーと、内部についてはmultiprocessing使えよとか、TCPサーバを自前で書くって標準ライブラリにあるだろ、とか、twisted,eventlet使えよとか、スレッド周り適当じゃね?とかまぁいろいろあるんですが分かりやすさ重視ということで。

通信にはjsonを使いました。

基本的な動かし方

python code
  1. import kademlia_tcp
  2. kademlia_tcp.DEBUG = True
  3. n = kademlia_tcp.KademliaNode("ip address", port)
  4. n.join(n)
  5. remote = kademlia_tcp.ContactNode("ip address", port)
  6. n.join(remote)
  7.  

という感じでネットワークを作れます。DEBUGをセットすると、通信情報など、様々な情報が出力されます。あとは

python code
  1. key = n.hash("key")
  2. n.publish(key, "value")
  3. n.find_value(key)
  4. n.ping(other_node)
  5. n.store(other_node, key, value)
  6. n.find_node(other_node)
  7.  

というようなメソッドが使えます。

動かしてみて

ローカル環境でですが、100ノードほどで動かしてみました。元論文以外には特にchurnの対策はしてないのですが、そこそこ耐性があるんですね。3スレッド、0.1秒間隔で参加と脱退を繰り返したのですがちゃんとpublishしたものが取得できました。もうちょっとchurn対策をすればかなり使えそうだな、と感じました。

ルート探索は今回はTCPなのですが、そもそもKademliaは反復的探索なのでこの部分はやはりUDPにしてしかるべき、だなとも思いました。現実的にはルート探索などではUDPを使って、FIND_VALUE(値の取得)ではTCPにするなどの併用が一番現実的っぽいかなあ、とも感じました。

というわけで

P2P実装楽しいですね。実際のマシンで実験できる環境があればもっと楽しいんでしょうけど。

01.06.10/12am

About

Author:yuin(http://inforno.net/)

文学部文化学科卒という生粋の文系趣味プログラマ。

主にRuby、Javascript、PHP、JAVA,Python,C,Scala,Schemeなどを使っています。今はPythonな感じかもしれない。今後作曲活動なども復活するかもしれない。

Pages