A Django site.
7月 28, 2008
» XREAで好きなバージョンのPythonを使う方法

前のエントリーから自作のブログソフトに移行してみたわけだけど、やっぱり自分で作ったものはなんとなく気持ちいいですね。

さて、このブログはXREAでPython2.5で動いているわけですが、もちろん?XREAにPython2.5ははいっていません。ではどうやって動かすか・・・というと答えは簡単。バイナリとして動かしているわけです。

XREAはバイナリCGIが動くのでバイナリにしてしまえばどんなバージョンのPythonでも問題ありません。しかも、たとえばMySQLDBなどの拡張モジュールもきちんとバイナリに含まれるので、多少ファイルサイズは大きいですがアップロードするだけで動くので非常に楽です。

今回はXREAでローカルで作ったPython2.5アプリをバイナリ化して動かすまでを紹介しようかと思います。

バイナリ化ライブラリ:bbfreeze

バイナリ化に使うライブラリですが、俺はbbfreezeを使いました。bbfreezeの特徴は

  • すごく簡単
  • ライブラリの探索に優れる
  • Linux用バイナリが作れる

というところでしょう。

bbfreezeを使う上での注意点

ただ、使う上で色々注意点もあります。書きなぐりなのでちょっと汚いですが、このブログアプリ用のfreezeスクリプトです。

python code
  1. from bbfreeze import Freezer
  2. import sys, os, shutil
  3. from os.path import dirname, abspath, join
  4. root = abspath(dirname(__file__))
  5. sys.path = [join(root, d) for d in ["libs"]] + sys.path
  6. include_lst = []
  7. for r, dirs, files in os.walk(join(root, "libs")): #指定ディレクトリ以下を全部追加
  8.   if "__init__.py" in files:
  9.     include_lst.append(r)
  10.   for file in (f for f in files if f.endswith(".py") and f != "__init__.py"):
  11.     include_lst.append(join(r, file[:-3]))
  12. def replace(f):
  13.   return f[len(join(root, "libs"))+1:].replace("/", ".")
  14. include_lst = map(replace, include_lst)
  15. include_lst.append("_mysql") # MySQLDBの_mysqlが含まれないので手動で追加
  16. shutil.copy(join(root, "index.py"), join(root, "index.cgi.py")) #cgi用にリネーム
  17. f = Freezer("dist", includes=include_lst, excludes=(), )
  18. f.addScript("index.cgi.py", True)
  19.  
  20. f() # starts the freezing process
  21.  
  22. os.remove(join(root, "index.cgi.py"))
  23.  

と、こんな感じです。ほんと汚いな・・・。さてでは注意点を一つ一つ。

  • できる限り自動的に使用しているライブラリを検索してくれるのですが、__import__で動的にインポートする場合はさすがに無理です。なので、そういうモジュールがある場合、自分で追加する必要があります。このブログアプリではPygmentsMarkdownあたりが__import__による動的インポートを行っています。
  • MySQLDBの_mysqlモジュールのように探索されないのもありますので、注意しないといけません。
  • 出力されるバイナリファイル名はメインスクリプトから.pyを除いたものになります。XREAでcgiとして動かす場合はあらかじめindex.cgi.pyみたいにリネームしておくとindex.cgiが吐き出されるので便利です。

また、dirname(__file__)でディレクトリを取得し、テンプレートファイル用ディレクトリなどを設定している場合、注意が必要です。以下のようにします。

python code
  1. root_dir = abspath(dirname(__file__))
  2. if "library.zip" in root_dir:
  3.   root_dir = dirname(root_dir)
  4.  
  5. template_dir = os.path.join(root_dir, "templates")
  6.  

ファイルはlibrary.zipにまとめられますので、実行時は/library.zip/hogehoge.pyのような扱いになります。そのためlibrary.zipがパスに含まれる場合はさらに1個上のディレクトリが求めているディレクトリになります。

アップロード

生成されたファイル群をアップロードするだけです。さすがにサイズは大きいですが。もちろんアップした後index.cgiのパーミッションは設定しましょう。

アクセスしましょう

バッチリ動くはずです。


というわけで、bbfreezeを使えばサクッと任意のバージョンのPythonで作ったアプリがXREAで動かせます。あとは負荷だけが問題です。1日見た限りではweb.pyの場合負荷は大丈夫っぽいです。ぶっちゃけ、Wordpressより速い気がします。web.pyはライトウェイトWEBフレームワークとしてもう少し評価されるべき。Djangoとかだとどうなんですかね。チャレンジャーな方は、ゼヒ。

7月 27, 2008
» 試験的に自作ブログに移行しました

前のエントリーでGAEにおけるトランザクションの問題は一応解決をみた。

その後、GAEで開発を続けた結果、やはりGAEにブログを移行するのは断念した。理由としては

  • os.listdirなどで不審な挙動が見られた
  • スキーマを変更したときが非常に面倒
  • インポート、エクスポートの難しさ

が主なところ。

os.listdirについては、web.pyでテンプレートを検索するときにos.listdirを使っているのだけど、どうも動きが怪しい。正しくファイルリストが帰ってきたり帰ってこなかったりするのだ。何回も本番にアップして試したところ、os.listdir("hoge");os.listdir("hoge")というように同じ内容で2回連続で呼び出すとなぜか確実にファイルリストが帰ってくる、という・・・これはちょっと・・・

スキーマの変更に関しては、まんま。変更したとき、それを本番に反映させるのがめんどくさい。

インポートエクスポートも負荷を考えるとしんどい。現在もWEBはレンタルサーバで運用しているのでわざわざGAEにもっていく旨みもない。

ということでせっかくブログをつくったのに移行をやめたのである。


しかし、せっかく作ったのにもったいない。ということで今度はGAE用につくったブログを普通にMySQLを使うようにポーティングした。今回はそれに試験的に移行してみたのだ。

なぜWordpressからわざわざ独自ブログソフトウェアに移行したのか。理由は前のエントリーにも書いたとおりだけど

  • Wordpressのコードが気に食わない(OSSとしてバランスをとっている、というのはあるんですが)
  • 使用しているテンプレートや、プラグインも含めると出力されるHTMLが汚い。
  • ついている機能の半分以上は使っていない。ブログライトユーザの俺には機能が多すぎる。
    • 自分の使う機能が固まった。それさえあれば俺には十分とわかり始めた。
  • セキュリティ的にもWordpressはターゲットになっていて微妙。

以上のようなところをふまえ

  • 明快なコード。
  • キレイなXHTML。
  • 自分が使う機能だけ実装。
  • 堅牢なコード。

ということを心がけた。またレンタルサーバで動かすということで

  • なるべく静的HTMLとしてキャッシュしてmod_rewriteで飛ばす
  • 見た目や外部連携に関する動的な部分はなるべくクライアントサイドで

ということにも気を配った。

このブログは3年目に入るのだけど、やはりWEBの世界というのは流れが速いもので大分変化があった。その中で、外部連携はほぼJSONPで行えるようになったのでサーバサイドでやらなくても良くなった。今回実装したブログでは各SBMのブクマ数を表示しているけど、これも全てJSONPでクライアントサイドで実現している。それに対し、旧ブログ(Wordpress)ではサーバサイドで定期的に取得していた。

という感じで出来上がったのがこのブログだ。もうひとつ、実はこのブログ、XREAでしかもPython2.5で動かしている。あれ、XREAでPython2.5使えたっけ、というあなた。実は簡単に使えちゃうワザがあるんですよ。それについては、また。


あまりテストもせず試験的に移行してみたのでおかしい部分もあるかと思いますが、そこはおいおい。パーマリンクはそのままになっていると思います。基本的にURLは変更していません。また、CGIで動かしていますので、負荷が高ければ前のに戻す予定です。