読者です 読者をやめる 読者になる 読者になる

FutureInsight.info

AI、ビッグデータ、ライフサイエンス、テクノロジービッグプレイヤーの動向、これからの働き方などの「未来」に注目して考察するブログです。

web.pyを使って注意が必要なところ

id:nishiohirokazuさんがweb.pyを試してみてるようです。

web.pyはおっしゃるとおり、かなり見よう見まねで使えるアプリなのですが、いろいろ注意して使わないとはまる箇所があります。

特にDBにはまる箇所がたくさんあるので、もう僕はweb.pyのDB機能は使うことをすっぱりあきらめて全てSQLobjectを使うことにしました。SQLObjectはPythonの標準的なO/Rマッパーで、完成度が高いです。SQLiteもPython2.5で標準モジュールとなったsqlite3を直接叩くのではなくSQLObjectから使った方が幸せになれそうです。

そういえば、2週間くらい前SQLObjectの使い方を僕のメモブログの方に保存しておきました。

DBともう一個気になる点が、web.render()を呼ぶときに、filterが指定できないことです。web.pyのソースコードを眺めるとわかるのですが、web.render()はWebSafeというFilterクラスが決め打ちで指定してあって、こいつが基本的にテンプレートに渡された変数をすべてHTML escapeします。この仕様はいただけません。templateの変数にhtmlを生で渡すことができなくなります。場合にもよりますが、

  • 全てのタグをescapeするFilterクラス
  • 'a p br div td th li blockquote pre form hr h1 h2 h3 h4 h5 h6'のタグ以外をescapeするFilterクラス
  • 'comment script style select'タグだけをescapeするFilterクラス
  • なにもしないクラス

くらいは用意して、テンプレートに渡す変数ごとに指定できるべきだと思います。この部分だけは勝手に改造して使ってます。

あと、web.pyはファイルのアップロードを行うときweb.input()を用いてファイルをメモリに読み込むのですが、Windowsで動かしているとだいたい3Mを超えたファイルはWinSockの仕様で扱えなくなります。Linuxだとこの辺りはしっかり動いたので大丈夫ですがちょっと注意が必要です。でかいファイルがきたらweb.input()を呼ぶと、wsgiがファイルをRAM上に展開してしまうので、その前に、以下のような感じで大きな転送ははじいてしまった方がよいです。

  def POST(self):
    contentLength = web.intget(web.ctx.env.get('CONTENT_LENGTH'), 0) 
    if contentLength > 10000000:
      print "data is too large."
      return
    x = web.input()

今まで、web.pyを触ってみて気づいた注意点はそんな感じです。