Recent Entries
Recent Comments
OZACC.blog: Python Category Archive

2010年3月28日

Python | PIL のバグ?

Python 2.6 + PIL 1.1.7 の環境で、他のサーバからコピーしてきた画像処理の Python プログラムが Image.split() メソッドを呼んだときに、毎回ではないが以下の例外が発生するようになった。他のサーバでは PIL 1.1.6 だったからか、問題なく動いていたのに。

File "/usr/local/lib/python2.6/site-packages/PIL/Image.py", line 1497, in split
    if self.im.bands == 1:

AttributeError: 'NoneType' object has no attribute 'bands'

原因を検索していたら、似たようなエラーに関する ML 投稿が見つかった。
それによると Image.open() メソッドの後に、Image.load() メソッドを明示的に呼ぶという回避方法が書かれていたので、早速プログラムをそのように修正してみたら、解決できた様子。

Posted by otsuka : 03:51 | Comment (0) | Trackback (0)

2010年1月31日

Python | Django File.save()メソッド

Django | File storage API | Django documentation

Storage.save(name, content)

DjangoのFileクラスに備わっているsave(name, content)メソッドを使ってファイルのコピーを行ったりしてたんだけど、後でコピー元のファイルを削除しようとすると「プロセスはファイルにアクセスできません。別プロセスが使用中です」とエラーになった。

ソースを追ってみると、File.save()メソッドは上記のStorage.save()メソッドを呼び、Storage.save()ではcontent引数のFileオブジェクトはクローズしていないことが分かった。

File.save()メソッドを実行した後は、元ファイルはclose()メソッドを呼んでおかなければいけないということ。

Posted by otsuka : 20:44 | Comment (0) | Trackback (0)

2010年1月27日

Python | if not self

def _require_file(self):
    if not self:
        raise ValueError(...)

Django の FieldFile クラス(django/db/models/fields/files.py)に上のメソッドがあるんだけど、この中に出てくる「if not self」という条件はどういう意味? これインスタンスメソッドだよね?

Python の基礎を理解できてないのか、何かをど忘れしているのか。

Posted by otsuka : 20:27 | Comment (4) | Trackback (0)

2010年1月20日

Python | Google App Engine upload_data

GAE/Pyでbulkloaderを使ってデータをアップロードする - すぎゃーんメモ

appcfg.py upload_data コマンドで実行する一括データアップロード時にエンティティのキーを指定する方法はないか探っていてのだけど、ドキュメントにはその方法は載っておらず、bulkloader.py のソースを追って generate_key() メソッドをオーバーライドすれば良さそうということまで分かって、検索したら上のエントリーが見つかった。

「key_nameを元データに含めて使用する」方法もとても役に立った。

Posted by otsuka : 22:52 | Comment (0) | Trackback (0)

2009年11月 5日

Python | cElementTree でのエラー

IOError: file() constructor not accessible in restricted mode

Django の Web アプリケーションで、cElementTree モジュールの parse() 関数に XML ファイルパスを渡して XML ドキュメントをパースさせていると、時々上記のようなエラーが発生する。再現条件は分からないけど、一度発生すると毎回エラーになる。Python はバージョン 2.5.1。
エラーメッセージの「restricted mode」の意味も分からない。

cElementTree ではなく ElementTree モジュールに変えてみたところ、今のところエラーは起こっていない。謎だ。

Posted by otsuka : 00:53 | Comment (0) | Trackback (0)

2009年10月26日

Python | Jython から Java の protected static メンバーにアクセス

JythonFaq/ProgrammingJython - JythonWiki

先日、Scala から Java の protected static メンバーにはアクセスできないといったエントリーを書いたけど、Jython でも無理らしい。

JRuby でもそうなのかな?

Posted by otsuka : 16:33 | Comment (0) | Trackback (0)

2009年9月 6日

Python | PILで透過GIFをRGBAに

PILでGIF画像を開くと、モードは「P」。つまりパレットモード。透過GIFの場合、パレット内のどのカラーが透明かは分かるけど、透過GIFのImageオブジェクトをさくっとRGBAモードに変換するメソッドがPILには用意されていない。

この変換のやり方がようやく分かった。これでいろいろと合成ができる。
半年近く前にもトライして諦めたんだけど、なんでこんなコードが書けなかったのか不思議なくらい単純な方法でできた。
でも検索しても全然出てこないから、みんな分からないのだと思う。というか、そんなニーズがないのかも知れない。

コードは次の通り。

def convert_trasparent_gif_to_rgba(img):
    rgb_img = img.convert('RGB')
    transparent_color_index = img.info['transparency']
    alphadata = [0 if p == transparent_color_index else 255 for p in img.getdata()]
    alpha_img = Image.new('L', img.size, 0)
    alpha_img.putdata(alphadata)
    
    rgb_img.putalpha(alpha_img)
    return rgb_img

    #上2行の代わりに以下2行でもOK
    #imgs = rgb_img.split()
    #return Image.merge('RGBA', (imgs[0], imgs[1], imgs[2], alpha_img))

img = Image.open('image_with_transparency.gif')
rgba_img = convert_transparent_gif_to_rgba(img)

alphadataを得る部分が、画像サイズが大きくなるとかなり非効率。まあ、透過GIFでそんな巨大な画像は作らないしね。
でももっとオシャレな方法がありそうな気はしてる。

Posted by otsuka : 05:33 | Comment (0) | Trackback (0)

2009年8月23日

Python | PILで透過PNGの合成

PILで、透過PNG画像を、透過を活かしたまま別の画像の上に重ねた合成画像を作ろうと苦戦していたのだけど、やっとやり方が分かった。

Image.split() で R、G、B、A の各チャンネルの画像が抽出できることに気付くまでが長かった。

import Image

img = Image.open('transparent.png')
mask = img.split()[3]
bg = Image.open('bg.png')
bg.paste(img, None, mask)
bg.save('composite.png')
Posted by otsuka : 20:50 | Comment (0) | Trackback (0)

2009年4月21日

Python | Django Hack-a-thon Disc.8

Django Hack-a-thon Disc.8 | Djangoと日本の仲間たち

今週末のDjango勉強会で、Django & Flash というテーマでお話しします。

これまでプレゼンは避けてきましたが、初めての挑戦です。50人くらい参加者がいるとのことなので緊張します。グダグダなプレゼンになっても勘弁してください。

WEB+DB PRESS Vol.49の隔月刊少年Flashの続編に当たる内容にするつもりです。AMFの仕様や、Django AMFについて、ストリッパーズでの制作事例を交えつつお話ししたいと考えてます。

Posted by otsuka : 22:50 | Comment (0) | Trackback (0)

2009年2月14日

Python | Django テストでのメール送信

Djangoアプリケーションのテスト — Django v1.0 documentation

Django は、テストフレームワークを初期化する際、通常の SMTPConnection クラスをダミーの SMTPConnection 実装に切替えます

これを知らなくて、何故メールが送信されないのだろうとしばらく嵌ってた。メール送信部分のソースまで追ったりして。

メール送信のドキュメントページにもこの記載があれば、もっと早く気づけたのに。脱力。。。

Posted by otsuka : 00:53 | Comment (0) | Trackback (0)

2009年2月 3日

Python | Django AMF 機能追加

Django AMFの機能追加。
・_amf_pre_serialize_handler() メソッド
・_amf_extra_return_attrs クラス変数

前者は、PythonクラスのインスタンスがAMFにシリアライズされる直前に、そのクラスに定義された _amf_pre_serialize_handler() メソッドが呼び出されるというもの。
PythonクラスとAS(Flash)クラスをマッピングしている場合で、ちょっとプロパティが違ったりする場合に使う。例えば、ASクラスでは配列プロパティだけど、Pythonクラスではコンマ区切りの文字列でデータを保持しているような場合に、このハンドラメソッドで文字列をリストに変換して対応できる。
まだ post_deserialize ハンドラはない。
最初はDjangoのシグナルで対応しようかと思ったけど、Djangoに依存してしまうのでやめた。

DjangoのモデルインスタンスをFlashに返す場合、モデルクラスでフィールドとして定義している変数しかシリアライズ対象にしかならないため、後から動的に追加する属性もAMFにシリアラズしたい場合に _amf_extra_return_attrs クラス変数にその属性名をセットしておく。

Posted by otsuka : 21:58 | Comment (0) | Trackback (0)

Python | AMFのエラーメッセージを隠す

AMFのサーバソフト、おそらく多くのものはRPCメソッド実行時にエラーが発生すると(例外が送出されると)、スタックトレースやらのエラー情報をAMFメッセージに含めて返しちゃってると思う。
開発時はできるだけ詳細なエラー原因が分かった方がいいのだけど、運用時には運悪くエラーが起こってしまったとしてもこういう情報はユーザに返したくない。隠したい。まあAMFメッセージの中身まで覗くマニアックなユーザはいないと思うけど。

というわけで、Django AMFに AMF_HIDE_ERROR_DETAILS という設定項目を設け、これを有効にした場合はエラーコードとタイプ以外の詳細情報には空文字列を入れたAMFメッセージを返すようにした。

ついでに、エラーとは関係ないけど、RPCメソッドとなるviewの関数内から生クッキーをセットできるようにもした。
実案件で使って問題がないようだったらリリースする。

Posted by otsuka : 18:26 | Comment (0) | Trackback (0)

2008年12月17日

Python | Django AMF 0.8

Django AMF 0.8をリリースしました。

<mx:RemoteObject> を使ってのRPC呼び出しを遂にサポートしました。
今まではFlexからDjango AMFを呼び出す場合、S2Flex2-componentsを使うか、NetConnectionクラスを直接使うかしかありませんでしたが、今後はRemoteObjectクラスを使うことができます。

ただ、RemoteObjectクラスからの認証周りはまだ。これが次の課題。

ドキュメントを書き換えたら、久々にDjangoの本家MLにもポストしてみようと思う。

Posted by otsuka : 20:50 | Comment (0) | Trackback (0)

2008年12月11日

Python | Django AMF 0.7

Django AMF 0.7をリリースしました。

・Python 2.4のサポートをやめた。
・ActionScriptのXML型に対応するPythonの型をminidom.DocumentからElementTreeのElementに変更。
・DjangoモデルクラスのインスタンスをAMFにシリアライズする時に、ForeignKeyで取得したインスタンスも再帰的にシリアライズするように修正。

最後の点は、PyAMFのDjangoアダプターでも実現できていない点なので、Django AMFの優位点です。っていうか、これが今までできてなかったのかよ!!って気もするけど。

相変わらずまだドキュメントを書いてない機能がある。

Posted by otsuka : 23:09 | Comment (0) | Trackback (0)

2008年12月 8日

Python | Django PostgreSQLのテーブルスペース

先日のエントリー関連。

データベースバックエンドは組み込みのもの以外でも利用できるようになっているので、PostgreSQLでテーブルスペースが使えるように拡張したバックエンドモジュールを作成してみました。

ダウンロードはsourceforge.jpから

インストールしたら、

DATABASE_ENGINE = 'strippers.django.db.backends.postgresql_psycopg2'
DEFAULT_TABLESPACE = 'デフォルトで使用するテーブルスペース名'
TEST_TABLESPACE = 'テスト時に使用するテーブルスペース名'
と、Djangoを設定します。TEST_TABLESPACEは独自の設定項目です。
DATABASE_ENGINEの名前が示すように、組み込みのpsycopg2用モジュールを継承した形になってます。

テスト時だけPostgreSQLのデフォルトテーブルスペース(pg_default)以外を使用したい場合は、TEST_TABLESPACEだけ定義すればOK。
DEFAULT_TABLESPACEが定義されている場合、syncdb時にもテスト時にもそのテーブルスペースが使われます。但し、TEST_TABLESPACEがDEFAULT_TABLESPACEより優先されます。

現在のところ、データベース生成時にしか使われません(モデルフィールドのField.db_tablespaceには未対応)。

Posted by otsuka : 21:12 | Comment (0) | Trackback (0)

2008年12月 5日

Python | Django テストの高速化

Djangoのテストフレームワークは便利なんだけど、テスト実行時に毎回行われるDBテーブルの生成・削除プロセスやFixtureデータのインポート処理に決行時間が掛かってて、ストレスの種になっていた。

テスト中にコンソールを眺めていて特に遅いと感じられるのがcreate table文の実行。モデルの数だけこれが実行されるので、アプリケーションの規模が大きくなるにつれテスト時間も増加してしまう。
DBアクセスが高速化されればいいんだけど、今回使用しているDBのPostgreSQLにはメモリテーブルみたいな仕組みがないため、どうしてもディスクアクセスが発生してしまう。が、ローカル環境では開発用途にしか使ってないのでRAMディスク上にテーブルスペースを作って、そこにテスト用のDBが生成されるようにすればDBアクセスが高速化されるはず。と思い立って、次のようにこれを実現してみた。

まず導入したのが前々から欲しいと思ってたソフト、RamPhantom。手元のデスクトップマシンはWindows XP 32bit版で4GBのメモリを積んでいるので、OSに認識されないメモリが700MB近くあった。IOデータのメモリを持っていなかったので有償版を購入。OS管理外メモリをすべてRAMディスクに割り当てた。ログオフ時にはHDDにRAMディスクをバックアップするように設定。

次に、PostgreSQLのテーブルスペースを「ram」という名前でRAMディスク上に作成。このテーブルスペースにDjangoアプリケーションで使用するデータベースを作成。
これでsyncdb時のテーブル生成も「超」が付くほど高速化された。が、テスト実行時にはPostgreSQLのデフォルトのテーブルスペースにテスト用データベースが作成されてしまっていた。意味ないじゃん。

Djangoには元々DEFAULT_TABLESPACEという設定項目があるけど、Oracleでしか使われてない様子。
というわけで、Djangoのソースに手を加えて、これをPostgreSQLでも使えるようにします。対象ファイルは、django/db/backends/postgresql/creation.py 。sql_table_creation_suffixメソッドを以下のように修正。

def sql_table_creation_suffix(self):
    assert settings.TEST_DATABASE_COLLATION is None, "PostgreSQL does not support collation setting at database creation time."
    suffix = ''
    if settings.TEST_DATABASE_CHARSET:
        suffix += "WITH ENCODING '%s'" % settings.TEST_DATABASE_CHARSET
    if settings.DEFAULT_TABLESPACE:
        if suffix:
            suffix += ' '
        suffix += "TABLESPACE %s" % settings.DEFAULT_TABLESPACE
    return suffix
TEST_TABLESPACEといった名前で別の設定項目にするのもアリだと思う。この辺りは今後もう少し考えてみる。

そして、settings.pyに DEFAULT_TABLESPACE='ram' を追加して、テスト実行。ちゃんとRAMディスク上のテーブルスペースにテスト用データベースが作成されるようになりました。そして、超速です。テーブル生成のプロセスはもちろん、テストメソッドの実行も速くなってます。
これでテスト実行のストレスが激減しました。

Posted by otsuka : 22:24 | Comment (0) | Trackback (0)

2008年11月25日

Python | Pythonスクリプトのバイトコンパイル

6. モジュール | 「コンパイル」された Python ファイル

昨日から、あるサイトのバナーが複数出稿され(mixiをログアウトすると見られるかも)、今日の夕方になってアクセスが急増、APサーバの負荷が無茶苦茶上がってダウン寸前といった状態になっていた。

サーバサイドはDjango(mod_ptyhon)。ApacheのプロセスがMAX付近まで立ち上がってるけど、DBへの接続は少ない。そしてCPUのロードアベレージは凄いことになっていた。
そんな負荷が掛かるプログラムはないはずなのに何故?と、サーバ内をさまよっていて、ふと .pyc ファイルが作られていないことに気付いた。Apacheの実行ユーザから .py ファイルがあるディレクトリへの書込権限がなかったのが原因とすぐに分かったので、ちょっとでも負荷が下がるかもと思い、パーミッションを変更して対応。

ところが、この変更だけで、つまり .pyc ファイルが作られただけで、Apacheのプロセスは見る見る減って負荷も通常の状態に戻った。「えっ、これが原因なの!?」と、拍子抜け。

Pythonスクリプトのバイトコンパイルは負荷が掛かるものなんだと学んだ。

Posted by otsuka : 20:51 | Comment (0) | Trackback (0)

2008年9月10日

Python | Djangoのテンプレートシステム

Django | The Django template language | Django Documentation

Djangoのテンプレートシステムが僕にはとても使いにくい。
DjangoでHTMLを出力させることは今まであまりなく、あってもシンプルなものだったので、今日までこのことに気付かなかった。

設計思想は分かるけど、HTMLレベルのデザインもプログラムも両方やる自分にとっては、ifタグで >= などの演算子も指定できなければ、and や or で繋ぐことも出来ないなんて我慢ならない(これを実現するカスタムタグは既に存在するけど)。
ロジックは全部カスタムタグでやれってことなんだろうけど、カスタムタグを作るのもやたらとややこしいコードが必要で、直感的とは言いづらい。JSPのTaglib作る方がシンプル。
しかもタグの出力結果にフィルタを掛けることもできないので、再利用しにくいカスタムタグを作らざるを得ない。尽く柔軟性に欠ける。
何か使い方を間違っているのか?

Pylonsみたいにテンプレートエンジンが選べればいいのだが。他のテンプレートエンジンに詳しいわけではないので、似たり寄ったりなのかも知れないけど。

Posted by otsuka : 22:40 | Comment (0) | Trackback (0)

2008年9月 5日

Python | Django 1.0

Django | Weblog | Django 1.0 released!

ようやく1.0 Finalがリリースされました。露木さんによるリリースノートの翻訳も公開されています。

Django AMFも開発はほとんど進んでいませんが、現行のバージョンは1.0 Finalでも稼働します。
早速本日、Django 1.0 Final + Django AMFを使った、あるメーカーのキャンペーンサイトを公開します。

Posted by otsuka : 14:23 | Comment (0) | Trackback (0)

2008年8月 9日

Python | trac 0.11.ja1のチケットメール

tracのチケットメールをiso-2022-jpで送る方法を書いたエントリーへのアクセスが以前から多かったのだけど、あの時のパッチに変更を加えた方がいい点があります。

body = unicode(body, 'utf-8').replace(u'\uff5e', u'\u301c')
body = body.encode('iso-2022-jp')

こうなってる箇所は

body = unicode(body, 'utf-8', 'replace').replace(u'\uff5e', u'\u301c')
body = body.encode('iso-2022-jp', 'replace')

こうした方がいいです。こうすると、本文に文字コード変換できない文字が含まれるときでもエラーになりません。

Posted by otsuka : 14:18 | Comment (0) | Trackback (0)

2008年8月 8日

Python | 色体系変換

TekTekBlog -- PythonでHSV←→RGB変換 HSVとRGBを変換する機能が、なんと驚くべきことにPython標準モジュールに存在する。

14.7 colorsys -- 色体系間の変換

知らなかった。標準モジュールにそんな機能があるとは、さすがはPython。

Posted by otsuka : 19:47 | Comment (2) | Trackback (0)

2008年5月23日

Python | CronでDjango

"cron jobからDjangoフレームワークを利用する" 再び - nemolog
import MyApp.settings as settings
from django.core import management
management.setup_environ(settings)

from MyApp.foo.bar import buz

x = buz()

なるほど、なるほど。

Posted by otsuka : 00:33 | Comment (0) | Trackback (0)

2008年5月21日

Python | パイ

半年以上ぶりにDjango(Django AMF)を実戦投入。0.96からは大分時間が経っているので今回はSVN版で。

1.0という区切りをなかなか迎えられないせいか、国内のDjangoコミュニティがおとなしくなってきているような気もする。どちらかというと流れはPylonsなのかな?
勉強会があればまた参加したいが。

jythonの本を買った。まだちょっとしか読んでないけど面白い。

Posted by otsuka : 00:39 | Comment (0) | Trackback (0)

2008年1月 3日

Python | Django AMF 0.6 リリース

Django AMF 0.6をリリースしました。
新機能に伴う日本語ドキュメントは半分くらい書いた。英語はまだ全然。
僕としてはドキュメントをちゃんと書いてるつもりなんだけど、外国からの反応はドキュメントがほとんどないだの何だのなかなかシビアです。

まだバグは残ってるし、logging周りも書き直したい。そろそろFlexのRemoteObjectにも対応させたいし、サンプルアプリももうちょっと複雑なものを作りたい。Flash CS3用のコンポーネントもちゃんとまとめてリリースしなければ・・・と、やるべきことが一杯。
また実プロジェクトに投入すれば一気に開発が進むのだけど、当分はなさそう。

Posted by otsuka : 01:13 | Comment (0) | Trackback (0)

2007年12月 1日

Python | powered by Django

HONDA CROSSROAD MESSAGES
STEP WGN ポスターつくろうコンテスト

一ヶ月ほど前に立て続けにリリースしたHONDAのクロスロードとステップワゴンのスペシャルサイト。両方ともサーバサイドではDjangoを採用しました。

ステップワゴンの方はDjango AMF。お陰でFlashとの連携はスムーズに開発できた。自画自賛。

管理用サイトを作るのに初めてnewformsの機能を使用。Django 0.96だったのでまだいろいろとバグが残っていて、SVN trunkのバージョンと比較しながらソースを修正することもあって、使えるようになるまでに結構時間が掛かった。

因みに、tohsakiがこのエントリーで書いている「更新系のユーティリティシステム」もDjangoを採用しました。

これらの小さな規模のシステムに現状のDjangoを実戦投入してみた感想としては、Webフレームワーク使うんならDjangoよりRailsを使った方がいいんじゃないかな、ということ。

そんな僕だが、今携わっているプロジェクトでRailsを提案するもPHPでやってちょーだい的な流れになってしまい、久々にPHPで開発。あと三週間後にはリリースされているはず。

Posted by otsuka : 03:20 | Comment (0) | Trackback (0)

2007年10月30日

Python | Djangoのイベント処理

django.dispatchを使ってイベントを捕捉する - perezvonの日記

Djangoのソースを追ってたら、

receivers = dispatcher.send(signal=signals.got_request_exception)
というイベントを投げているようなコードに出くわした。この行の後に receivers は参照されてないし、何のためのものなんだ?と思って調べてたら、上の記事に辿り着いた。
Djangoにこんなイベント処理の仕組みが備わっていたなんて知らなかった。

Using Django Signals to Ping Sites on An Update
(via Django Dispatcher - UeblogWiki)
こういう使い方ができれば、すこぶる有用だ。

ドキュメントは→ What Are Signals?

Posted by otsuka : 23:42 | Comment (0) | Trackback (0)

Python | Python @deprecated

西尾泰和のブログ @ Cybozu Labs: Pythonで関数名を安全に変更する

これはいいアイデア。

Posted by otsuka : 15:25 | Comment (0) | Trackback (0)

2007年10月28日

Python | PILでサムネイル生成

Python Imaging Library Handbook

PILで画像のサムネイルを生成するときメモ。

image.thumbnail((100, 100), Image.ANTIALIAS)
image.filter(ImageFilter.DETAIL) # または、image.filter(ImageFilter.SHARPEN)
image.save('/path/to/thumbnail.jpg', 'JPEG', quality=95)

サイズにも因るけど縮小しただけではねむい画像になってしまうので、シャープフィルターを掛ける。が、PILのSHARPENフィルターでは度合いを調整できず、ちょっとシャープが掛かり過ぎてる感じ。フィルターをいくつか比べてみたが、DETAILフィルターが妥協できるレベル。

最後に保存する際に、qualityオプションで大きな値を指定しないとこれまた劣化の原因となる。デフォルトの値は75。ドキュメントによると、95より大きな値は指定すべきではないとのこと。

サムネイル生成に丁度いいフィルターを自作したいところ。PILのカスタムフィルターがどこかに公開されてないかな?

Posted by otsuka : 21:28 | Comment (0) | Trackback (0)

2007年10月17日

Linux, Python | 共有ライブラリの認識

共有ライブラリをシステムに認識させるには

Linux上で、PostgreSQL + psycopg2 + Django on Apache with mod_python な環境で次のようなエラーが起こっていたら、Apacheの実行ユーザがPostgreSQLのライブラリを認識できていないということが原因。

Error loading psycopg2 module: libpq.so.5: cannot open shared object file: No such file or directory
/etc/ld.so.conf に /usr/local/pgsql/lib を加えて、ldconfig コマンドを実行してシステムにPostgreSQLのライブラリを認識させればOK。

前もこの問題にはまったのに、記憶力が悪いせいでまたはまってしまったのでメモしておく。

Posted by otsuka : 19:41 | Comment (2) | Trackback (0)

2007年10月12日

Python | Django AMF 数値型の変換

Django AMFでActionScriptのNumber型の数値はPythonのfloat型になる。例えばFlashでRPCメソッドの引数に整数を渡した場合、Python側のint型を必要とするプログラムでは受け取ったfloat型の数値をいちいちint()関数で変換しなくてはならない。AS3でAMF3の場合はint型があるから特に問題はないのだが、int型のないAS2でAMF0の場合の話。

Javaだったら引数の型を指定できint型に変換されるけど、Pythonでは明示的に変換しないといけないから面倒くさい。

個人的には浮動小数点数やそれを含むオブジェクトをサーバに送ることは滅多にないので、ASのNumber型はPythonのint型に変換された方が都合がいいケースが多い。
どうしたものかと考え、次の三つの条件が揃っている場合にASのNumber型をPythonのfloat型として受け取った後、int型に自動変換するようにした。
これもDjango AMF 0.6の新機能。

1. settings.pyに AMF_NUMBER_TO_INT = True という設定がある。
2. AMF0を使っている。
3. 受け取ったfloat型数値が int(float_value) == float_value の条件を満たす。

float型を滅多に使わないのであれば、AMF_NUMBER_TO_INTを有効にしておいて、必要なところでint型の値をfloat型に変換すればいい。

Posted by otsuka : 04:34 | Comment (0) | Trackback (0)

2007年10月11日

Python | Djangoの開発サーバとFlash Player

Django付属の開発サーバを使ってDjango AMFアプリの開発を進めていたが、どうも挙動がおかしい。サーバからレスポンスを返しているにも関わらず、Flash側でそれを受け取れないケースがある。それも特定のRPCメソッドでだけ。
IEやFlash IDEのFlash Playerからだとこの問題が発生して、Firefoxからだと問題はない。IEからでもCharlesを間に挟むとこの問題は発生しなくなる。

Djangoの開発サーバではなく、Apache + mod_pythonで動かすとこの問題はどの環境のFlash Playerからでも問題は起こらない。

今はちゃんと調べる時間がないが、Djangoの開発サーバが返すレスポンスのHTTPヘッダに原因が隠れていそうな気がする。

Posted by otsuka : 19:50 | Comment (0) | Trackback (0)

2007年10月10日

Python | Django AMF 0.6 新機能

Django AMFの実戦投入を控えて、新機能が追加されている。0.6のリリースはまだ先だけど、自分用のメモも兼ねて簡単に内容をまとめておく。

  1. 任意のAMFヘッダをレスポンスのAMFメッセージに設定可能
  2. @amf_cache デコレータ
  3. _amf_no_return_attrs クラス変数
  4. amf.django.flash モジュール
  5. amf.django.test.RemotingService クラス
  6. Python → AMFの型変換で decimal.Decimal クラスに対応

3番目の _amf_no_return_attrs クラス変数には、Modelクラスの属性の中でFlashに返したくないもののリストを指定する。属性名の文字列でも、django.db.models.fields モジュールに含まれるクラスのオブジェクトでもいい。ここで指定された属性は、レスポンスのAMFメッセージには含まれない。
今のところAMF0の場合のみ対応。(追記: AMF3の場合も対応)

amf.django.flash モジュールには、Djangoのリクエストオブジェクトを渡せばFlashの FileReference クラスからアップロードされた画像ファイルを PIL Image オブジェクトに変換して返してくれる関数や、XMLデータを ElementTree オブジェクトにして返してくれる関数などが含まれている。

amf.django.test.RemotingService クラスは、内部でDjangoのテスト用クライアントを 使ったAMFクライアント。なので、ネットワークにリクエストは飛ばない。Djangoで実行するユニットテストの中で使う用。
この導入に当たって、これまでの amf.RemotingService クラスは構造を変更し、amf.client.RemotingService に移動。

追加。

  • レスポンスのHTTPヘッダにContent-Lengthをセット
  • メソッド実行時の例外をキャッチした場合、DEBUG時でなければADMINSにエラーメールを送信
Posted by otsuka : 17:53 | Comment (0) | Trackback (0)

2007年10月 5日

Python | Django カスタムSQLとトランザクション

モデル API リファレンス : Django 0.96 オンラインドキュメント和訳

カスタムSQLの実行

connection や cursor は標準の Python DB-API を使っています.

PostgreSQL + psycopg2 + Djangoの組み合わせで、カスタムSQLで更新処理を行ってもオートコミットされていなかったので、手動でコミットしようとDBAPIで定義されている connection.commit() を実行してみたが、django.db.connectionにcommitなんて属性はないッスとエラーが出た。

カスタムSQLを使っても、トランザクション管理はDjangoで統一して行われるということだね。確かにその方がベターだ。
データベーストランザクションの管理
とりあえずview関数にautocommitデコレータを付けて解決。

一般的なWebアプリの場合はTransactionMiddlewareを入れておけば良さそうだ。

Posted by otsuka : 21:00 | Comment (0) | Trackback (0)

2007年10月 4日

Python | Django エラー通知とsettings.py

Django の設定 : Django 0.96 オンラインドキュメント和訳

電子メールによるエラー通知

サーバのエラー
DEBUG を False にすると,コードが例外を送出し,その例外が捕捉されず,結果的に 500 エラーになった場合に, Django は ADMINS 設定にリストされている全てのユーザにメールを送信します.これは,管理者が何らかのエラーにすぐに気づけるようにするためです.

Djangoで稼働するサイトを運用環境下において初めてこの機能を知った。これは便利。

settings.pyについてperezvonさんが書いていたけど、僕のやり方は環境変数に「DJANGO_RUN_MODE」を指定して、settings.pyの中で環境別に差分のsettings.pyを読み込む形です。ちょっとRailsを意識したんだけど、無駄に複雑な気もする。このsettings.pyの管理方法はまだ模索中。

RUN_MODE = os.getenv('DJANGO_RUN_MODE', 'local').lower()

if RUN_MODE == 'local':
    DEBUG = True
    TEMPLATE_DEBUG = DEBUG
else:
    DEBUG = False

# (省略) 環境に共通の設定

# 環境別のsettings.pyをインポート
if RUN_MODE == 'development': from config.development.settings import *
elif RUN_MODE == 'production': from config.development.settings import *
else: from config.local.settings import *

大元のsettings.pyの設定値は後からインポートした環境別のsettings.pyで定義された同名変数の値で上書きされないことに注意。

Apache + mod_python環境ではSetEnvで環境変数を設定。

<Location />
    SetHandler python-program
    PythonHandler django.core.handlers.modpython
    SetEnv DJANGO_SETTINGS_MODULE project.settings
    ... 省略
    SetEnv DJANGO_RUN_MODE development
</Location>
Posted by otsuka : 23:10 | Comment (0) | Trackback (0)

2007年9月18日

Python | UnboundLocalError

octech - スコープ定義

参考になるのは、p.286の「変数がローカルスコープに属するかどうかはスタティックに決定される」という項目です。
(省略)
また、この参照先の処理はスタティックに処理されるので、以下のコードはエラーになります。

何故この最後の例がエラーになってしまうのか理解できない。

例えば X が 99 じゃなかったら、X=10 にしたい場合はどうすればいいの? 関数の最初に global X を加えればいいんだけど、納得がいかない。

Posted by otsuka : 23:22 | Comment (2) | Trackback (0)

2007年9月 4日

Flash, Python | Django与Flash的結合

DjangoFlash - Woodpecker.org.cn Wiki for CPUG

via 常山日記

Django AMFについて中国語で書かれたページ。

Posted by otsuka : 15:51 | Comment (0) | Trackback (0)

2007年8月31日

Flash, Python | Django AMF 0.5.1でやること

1番目のはもう実装済み。3番目のgettextモジュールは使ったことがないので、これから調べてみないと。

あー、なるほど。Djangoで国際化機能がサポートされているのか。

追記 2007/9/3
全部対応した。しばらく様子を見てリリース。

Posted by otsuka : 16:40 | Comment (0) | Trackback (0)

2007年8月30日

Flash, Python | Django AMF 0.5リリース

先日告知した機能を実装したDjango AMF 0.5をリリースしました。

AMFのRPCサービスメソッドを実行するだけなら、Flash/Flexよりも簡単にできる手段だと思います。S2Flex2AMFPHPWebORBRubyAMF、そして純正Flash Remoting MXと、サーバ側のプロダクトが何であろうと関係はありません。ちゃちゃっとネットワーク越しにサービスメソッドを実行したい場合に便利かも知れませんよと。

まずは日本語ドキュメントは書きました。
Django AMF
amf.RemotingServiceクラス リファレンス

Posted by otsuka : 04:16 | Comment (0) | Trackback (0)

2007年8月21日

Python | BooleanはIntTypeでもある

どうも動作がおかしいと思ったら。知らなかったよ。

>>>from types import *
>>> isinstance(True, IntType)
True
>>> isinstance(False, IntType)
True
>>> isinstance(1, BooleanType)
False
>>> isinstance(0, BooleanType)
False
Posted by otsuka : 18:42 | Comment (0) | Trackback (0)

Python | Django AMF 0.5の新機能

DjangoのUnicodeブランチで動かないというメールをもらったりもしてるんだけど、SVN版を追っかけたりはしないので放置して、Djangoと直接関連しない機能の開発に取り組んでいます。

Django AMFっていうネーミングがアレなんだけど、amfモジュールはDjangoと切り離しても使えるように設計しています。なので、AMFリクエストのPOSTデータをamfモジュールに通せば、Pythonオブジェクトに変換できます。その逆も然りでPythonオブジェクトをAMFリクエストデータに変換することもできます。

で、今開発している新機能がFlash RemotingコンポーネントのPython版。まだAPIを固めてないけど、以下のようなPythonコードでRPCサービスメソッドを実行できます。Flash/Flexからだと非同期での実行になるけど、これは同期呼び出しになります。

import amf
service = amf.RemotingService('http://127.0.0.1/gateway/', 'addressBookService')
results = service.getCards()

AMFの実装と言うとFlashからデータを受け取ってレスポンスを返すものが中心だったけど、リクエストを送るクライアント実装があってもいいんじゃないかと。
AMFサービスのHTTPUnit的なテストコード作る際にも使えるし、プロキシ的にも使えるんじゃないかなと。

0.5は月末辺りにリリース予定。

Posted by otsuka : 00:06 | Comment (0) | Trackback (0)

2007年8月20日

Python | 存在しないメソッドの呼び出し

PHP: オーバーロード - Manual

特別なメソッド __call() を使用すると、存在しないメソッドの呼び出しを捕捉することができます。

PythonでこのPHPの_call()に該当する特殊メソッドはなかったっけ?

PHPマニュアルの「__call を使ったオーバーロードの例」をPythonで書いてみた。サクッと書いた分にはこんなやり方しか思いつかなかったけど、これだとCallerインスタンスのメソッドが呼ばれたのか属性にアクセスしようとしたのか分からない。他に定石なやり方がありそうな気がする。

class Caller(object):
        
    def __getattribute__(self, name):

        def missing_method_call(*args):
            print "Method %s called:" % (name,)
            print args
            return (1, 2, 3)

        return missing_method_call

foo = Caller()
a = foo.test(1, "2", 3.4, True)
print a

追記

ちょっと冗長になるけれど、クロージャを使わずにやる方法も。

class MissingMethodCall(object):

    def __init__(self, name):
        self.name = name

    def __call__(self, *args):
        print "Method %s called:" % (self.name,)
        print args
        return (1, 2, 3)

class Caller(object):
        
    def __getattribute__(self, name):
        return MissingMethodCall(name)

foo = Caller()
a = foo.test(1, "2", 3.4, True)
print a
Posted by otsuka : 01:37 | Comment (2) | Trackback (0)

2007年6月15日

Python | 何語?

Flex 2: Python, Django a Flash Remoting

いよいよ何語かも分からない言語でDjango AMFが紹介されています。
文章の中でストリッパーズサイトやWEB+DB PRESSへのリンクが張られているので、書いている人は日本語が読めるのかも。

調べた結果、この言語はPolish(ポーランド語)だった。いくつかの自動翻訳を使って、何となく書いてあることは分かったような分からないような。

Posted by otsuka : 03:10 | Comment (2) | Trackback (0)

2007年5月 9日

Python | Django AMF 0.4.2

Django AMF

バグ修正版です。

リモートサービスメソッドからの戻り値がDjangoのQuerySet(やそのサブクラス)オブジェクトだった場合、list配列に変換してAMFにシリアライズされます。が、戻り値のオブジェクト(例えばlistやdict)にQuerySetオブジェクトが含まれる場合は、そのQuerySetがlist配列に変換されずAMFにシリアライズするときにエラーが起こっていました。
そんなバグを直しました。

あと、ドキュメントには書いていませんが、Djangoの認証システムと連携する場合に @login_required デコレータが使えるようになっています。

Posted by otsuka : 22:23 | Comment (0) | Trackback (0)

2007年5月 7日

Python | Django amf service, once installed is a beauty to behold

Ben Cooper's Weblog | Django AMF service

Django AMFを紹介してくれてます。S2Flex2-componentsも。

Django amf service, once installed is a beauty to behold
何かかっこいいことを言ってくれてるようなんだけど、うまく日本語に訳せません。


Django AMFの開発は小休止中だけど、ちょこっと追加したい機能があるのでDjango 1.0 Final Release待ちの間にもう一回アップデートするかも。
あとS2Flex2-componentsはFlex2用なので、Flash CS3用のRemotingコンポーネントをもうすぐリリース予定。

Posted by otsuka : 01:20 | Comment (0) | Trackback (0)

2007年4月 4日

Flash, Python | Django AMF 0.4.1

一日でバージョンアップ。認証システムとしてDjangoのユーザ認証機能をそのまま使える関数を追加しました。かなりオシャレな仕上がりになりました。 http://sourceforge.jp/projects/djangoamf/

ActionScript側でDjangoユーザアカウントのユーザ名とパスワードをセットして、パーミッション制限が掛かっているRPCメソッドを呼び出せば、勝手に認証・ログインを行い、そのセッションクッキーをセットしてくれます。ユーザがDjangoのスーパーユーザーならば、存在するすべてのパーミッションに対して有効になります。
自分で認証の処理とか書かなくていいので、この楽チンっぷりはやばいよ。

・ActionScript
var service:RemotingService = new RemotingService();
# アクセスユーザのユーザ名とパスワードを設定します。
service.setCredentials("username", "password");
service.do_something();
・settings.py
# 設定ファイルに次の一行を加える。
AMF_AUTH_FUNC = 'amf.django.authenticate'
・sample/view.py
from amf.django import permission_required

# このview関数を実行するのに必要なパーミッションを
# デコレータの引数に指定します。
@permission_required('add_user')
def do_something(request):
    return 'This function can be invoked by authenticated user.'
ここまでやったら @login_required デコレータもサポートしたいなあ。
Posted by otsuka : 17:10 | Comment (0) | Trackback (0)

2007年4月 3日

Flash, Python | Django AMF 0.4

先月末からいくつかリリースが続いてますが、今度はDjango AMFの新バージョン。ようやく認証システムを実装しました。これで実際のお仕事にも使っていただけると思います。
http://sourceforge.jp/projects/djangoamf/

Djangoのユーザ認証システムをDjango AMFでもそのまま使おうかと思ったのだけど、もっと柔軟にできるような仕組みにしました。したつもりです。
まだドキュメントをWikiにまとめてないのだけど、コードにするとこんな感じ。

・ActionScript
var service:RemotingService = new RemotingService();
# アクセスユーザのユーザ名とパスワードを設定します。
service.setCredentials("username", "password");
service.do_something();
・settings.py
# 設定ファイルにアクセスユーザのパーミッションを取得する
# 関数を指定します。文字列または関数オブジェクト。
AMF_AUTH_FUNC = 'sample.views._get_user_perms'
・sample/view.py
from amf.django import permission_required

# このview関数を実行するのに必要なパーミッションを
# デコレータの引数に指定します。
@permission_required('admin')
def do_something(request):
    return 'This function can be invoked by admin user.'

def _get_user_perms(request, username, password):
    """
    settings.pyで指定した関数。Django AMFが認証時に実行します。
    指定されたusernameとpasswordから、ユーザが所持している
    パーミッション(ロール)の文字列を返します。
    複数パーミッションを所持している場合はリストかタプルで返します。
    """
    if username == 'username' and password == 'password':
        return 'admin'
    return None

認証に失敗するとFlashにはFaultEventが返ります。FaultEvent#typeの値は「AMFAuthenticatinError」、#codeの値は「401」です。

次のバージョンではDjangoの認証システムをそのまま使える便利関数を提供する予定です。

Posted by otsuka : 17:18 | Comment (0) | Trackback (0)

2007年4月 2日

Python | デコレータ

KoshigoeBLOG: Pythonのデコレータ構文について

初めて引数を取るデコレータを書こうとして、幾重にも関数をネストしなければならないことに気付いた。これは言語仕様としてはどうなのよ?と言いたくなる程。

Pythonのクラスのインスタンスメソッド第一引数と、このデコレータは嫌いだ。

Posted by otsuka : 16:13 | Comment (0) | Trackback (0)

2007年3月18日

Python | Django AMFサンプルアプリ

WEB+DB PRESS Vol.37でWebORB for PHPを使って実装したFlex Address BookのDjango AMF版をようやくリリースしました。コンパイルしたSWFも含まれているので、DjangoとFlashPlayer 9がインストールされていれば動かせるはずです。
djangoamf-samples.zip

他人様の環境で動くのか不安なところです。なので、もしこのエントリーを読んでサンプルを動かしてみた方がいれば、ご報告いただけると助かりますデス。

Posted by otsuka : 01:25 | Comment (2) | Trackback (0)

2007年3月16日

Python | Django AMF 0.3.3

[flex / django] communications with djangoamf « galactivision

via 常山

Django AMFのバグが報告されていたので、修正したバージョンをリリースしました。

バイトオーダーとかよく分かってないんですが、バージョン0.1を作っているときに試行錯誤で何とか自分のマシンで動いたのでそれで満足してました。僕とは縁がないCPUで引っかかるだけだろうと思っていたら、PowerPCでもダメだったようです。上記ブログで書かれていたコードは、バイトオーダーをマシンに合わせて自動変換するモジュールの関数を使ってスマートに解決してました。ので、即採用、即リリース。

ByteArrayデータをMEDIA_ROOTディレクトリ配下に一発で保存、削除できるユーティリティメソッドも追加してます。

Posted by otsuka : 21:02 | Comment (0) | Trackback (0)

2007年3月 1日

Python | tempfile.gettempdir()

DjangoアプリをWindows上のDjango Development ServerとApache+mod_pythonでそれぞれ動作確認しててハマった問題。

Django Development Serverの場合、

import tempfile
tempfile.gettempdir()
は起動ユーザのTempディレクトリ、つまり"C:\Documents and Settings\username\Local Settings\Temp"を指す。
一方、Apache+mod_pythonの場合、"C:\WINDOWS\Temp"を指す。

Windowsの場合はややこしい。

Posted by otsuka : 04:30 | Comment (0) | Trackback (0)

2007年2月27日

Python | Django AMFで検索してみた

久しぶりに「Django AMF」でググってみたら、気になる結果がいくつか。
最近は海外からの問い合わせメールがちらほら届くようになったので、ちょっとは広まっているのかも知れない。Web+DB PRESSも発売されたので、サンプルをリリースしなければ。

[Plugin] Django AMF - SkiToo.Org Ce manque n'existe plus ! En effet, j'ai pu tomber par hasard sur le site DjangoAMF qui nous propose donc un middleware Django nous permettant d'utiliser le Flash Remoting. Ce plugin semble tout jeune (version 0.3.2) mais néanmoins actif (dernière mise à jour faite le 19 janvier 2007 ) Il semblerait qu'il soit développé par une équipe japonaise, mais fort heureusement une documentation anglaise est présente sur le site.
読めない。。。 が、Google翻訳使って大体は分かった。「バージョンは0.3.2とまだ低いけれど、活発に開発されている。日本人が作っているけど、幸いなことに英語ドキュメントが用意されている」みたいな。
WebFaction Forum / More Static serving issues... BTW - if you are interested in harnessing the power of Flash for your Django apps, check out Django-amf written by Tomohiro Otsuka, http://djangoamf.sourceforge.jp/index.php?DjangoAMF_en
スパムとか そうそう、PyJUGブースに「Django AMFに非常に興味がある」という方がみえました。地方の方だそうで、Django勉強会には参加できないとのことでしたが、やはり見る人は見ている!と思いました。

スペイン語もあった。大学の時に第二外国語としてスペイン語を履修したのにさっぱり分からない。
Flash, Django y AMF

Posted by otsuka : 03:19 | Comment (2) | Trackback (0)

2007年2月 5日

Python | Pythonで分散バージョン管理

Pythonで分散バージョン管理

via Twisted Mind

「MercurialHG」というツール。初めて知った。チュートリアルも用意されている。

Posted by otsuka : 11:27 | Comment (1) | Trackback (0)

2007年1月11日

Python | Windows用mod_python

mod_python download - The Apache HTTP Server Project

Windows Apache用のmod_python-3.2がない。。。と思っていたら、Other Binariesのリンクを辿ればあった。MEMO。
http://ftp.kddilabs.jp/infosystems/apache/httpd/modpython/win/


Apache+mod_python環境下で、Django AMFが動かないバグを発見。今までDjango付属のテストサーバだけで確認していたけど、今度からは両方で確認しないと。

Posted by otsuka : 16:32 | Comment (0) | Trackback (0)

2007年1月 9日

Python | Django AMF 0.3 リリース

Django AMF

Django AMFの新しいバージョンをリリースしました。今バージョンではAMF3をサポートしました。

PythonによるAMF3のオープンソース実装はおそらく世界初。世界初のバグ報告をお待ちしています。

Posted by otsuka : 20:27 | Comment (0) | Trackback (0)

2006年11月26日

Python | Django AMF 0.2 リリース

SourceForge.jp: Project Info - Django AMF

Django AMFの最初のリリースを行いました。今の段階ではバージョン番号に大した意味はありません。Sourceforge上にプロジェクトホームページも作りました。そこそこユーザマニュアルも書けたんじゃないかなあと思ってます。
http://djangoamf.sourceforge.jp/

まだPythonは始めたばかりでよく分かっていないので、コードにもドキュメントにもいろいろ誤りがあると思います。おかしな点を見つけたらじゃんじゃんご指摘願いますです。

PythonでDjangoでFlashでAMFというかなりニッチなターゲット向けのプロダクトなので、ユーザが増えずなかなかバグがつぶれないかも知れませんが、今後ストリッパーズの実プロジェクトで使えるレベルまで持っていくつもりではいます、今は。

後日サンプルアプリを作って公開する予定です。

Posted by otsuka : 00:29 | Comment (0) | Trackback (0)

2006年11月23日

Python | Django AMFリリースの件

昨日のDjango勉強会までにリリースすると以前のエントリーに書いたのだけど、急な打ち合わせや諸々あってリリースできませんでした。でもDjango勉強会に行く直前にクラスマッピングの仕組みをサポートでき、簡単なサンプルアプリも作れたので、勉強会でプレゼンらしきことができました。MXMLやAS3に馴染みのない方にとっては、下手な説明も相まって、何のことやらさっぱり分からないプレゼンだったと思いますが。

リリースしてもドキュメントやサンプルがないと使い方が分からないと思うので、もうちょっと時間をかけることにします。どこで公開しようか迷ったけど、使い慣れたSourceForge.jpにしようと思います。SVNもサポートしたことだし。


ああ、こたつ暖かい。眠い。。。

Posted by otsuka : 01:57 | Comment (0) | Trackback (0)

2006年11月16日

Python | Django AMF 0.1リリース予定

ほとんど以前の状態のまま開発が停滞気味になっているけど、このままダラダラやっていてもなかなか先に進まないので、リリース目標を決めました。来週のDjango勉強会までにバージョン0.1として中途半端な状態でも一度リリースします。動かないかも知れないけど。

今後のTODOリスト

  • クラスマッピングの仕組み
  • AMF3対応
  • セッション管理
  • Djangoの認証機構に対応
  • XMLの様々なクラスに対応
  • AdminサイトにAMFPHPのサービスブラウザ的なものを
  • ドキュメント

Posted by otsuka : 19:35 | Comment (0) | Trackback (0)

2006年11月 1日

Python | The Django Book

The Django Book

Django本のオンラインバージョン。1章と2章が公開中。

Yahoo UI Libraryを使って構築されたコメントシステムがよく出来ている。

Posted by otsuka : 12:03 | Comment (2) | Trackback (0)

2006年10月29日

Python | ファイルアップロード with Python

MultipartPostHandler.py

pythonのurllib2モジュールではファイルアップロードに対応していなかったので何かないかと調べていたら、Python Recipeのコメントにurllib2のハンドラーとして使えるMultipartPostHandlerクラスについて書かれているのを発見。これで解決。

Posted by otsuka : 17:28 | Comment (0) | Trackback (0)

2006年10月24日

Python | flashticle

Open Source Flash - flashticle

PythonのAMF実装をもうひとつ発見。こちらはTurboGearsと連携するようだ。
僕が書いたコードより断然Python的だし、よく出来ている。MLによるとAMF3をサポートする予定はないそうだが、Django AMFもflashticleを使う形で作り直そうかな。

Posted by otsuka : 17:55 | Comment (0) | Trackback (0)

2006年10月23日

Python | Django AMF

JavaにはOpenAMFS2Flex2、PHPにはamfphpがオープンソースのAMF実装としてあるけど、PythonのAMF実装は2004年のアルファ版で開発が止まったまま。

こうなったら自分で作るしかないと思い立ち、amfphpとS2Flex2を参考にPythonでAMFを扱えるモジュールを書いてます。Djangoと統合して動くようにDjango用のミドルウェア込みで。

実はさっき知ったのだけど、WebORB for RoRというRubyのAMF実装もあっんだね。こっちを参考に作ればよかった。。。

まだAMF0しか扱えないし、やりとりするオブジェクトのクラスマッピングをどうするか決めてない状態だけど、近々公開しようと思います。いずれAMF3もサポートしたい。とか言ってる間にWebORB for Pythonがリリースされそうですが。

で、Django AMFはなんとなく以下のようなコードになります。

・project_name/settings.py
middleware_classes = (
    'django.middleware.common.commonmiddleware',
    'django.contrib.sessions.middleware.sessionmiddleware',
    'django.contrib.auth.middleware.authenticationmiddleware',
    'django.middleware.doc.xviewmiddleware',
    'amf.middleware.amfmiddleware',  # AMF用のミドルウェアを設定
)

REMOTING_GATEWAY_PATH = '/RemotingGateway/'  # ゲートウェイURLのパスを設定
・project_name/urls.py
urlpatterns = patterns('',
    # 「ゲートウェイURLパス/サービス名/メソッド名」がマッピング用のURLとなる。
    (r'RemotingGateway/SampleService/add', 'project_name.app_name.views.add'),

    # メソッド名を()でグループ化し、ビューメソッドとして'amf.django.views'を指定すると、
    # オプションとして指定した'project_name.app_name.views'モジュール中で
    # グループと一致する関数が実行されます。自称「オートマッピング」
    (r'RemotingGateway/SampleService/(.*)', 'amf.django.views', {'views':'project_name.app_name.views'}),
)
・project_name/app_name/views.py
def add(request, a, b):
    return a + b  # Flashに返したい値をそのまま返すだけ

def getNow(request):
    import datetime
    return datetime.datetime.now()  # datetimeオブジェクトは自動的にFlashのDateオブジェクトに変換されます。
・Flash
var sampleService:Service = new Service(
    "http://127.0.0.1:8080/RemotingGateway/", // ゲートウェイURLを指定
    null,
    "SampleService", // サービス名を指定
    null,
    null);

addPc:PendingCall = sampleService.add(1, 2) // リモートメソッドの呼出
addPc.responder = new RelayResponder(this, addResult, handleError);
function addResult(re:ResultEvent) {
    trace(re.result); // '3'が出力される。
}

nowPc:PendingCall = sampleService.getNow(); // オートマッピングにより関数が呼び出される。
nowPc.responder = new RelayResponder(this, getNowResult, handleError);
function getNowResult(re:ResultEvent) {
    trace(re.result): // re.resultはDateオブジェクト。現在の日時が出力される。
}

function handleError(fault:FaultEvent) {
  // エラーを処理
}
Posted by otsuka : 17:10 | Comment (0) | Trackback (0)

2006年9月22日

Python | Django勉強会雑感

昨晩参加させていただきました。チュートリアルをざっとやってみるという内容だったけど、既にチュートリアルをやっていたので、内容的には正直ちょっと物足りなかった。でも露木さんにいろいろと質問して、疑問だった点がクリアになったのでよしとする。次回からは突っ込んでいくとのことなので楽しみ。

懇親会では、Djangoのパフォーマンスの高さの話に興味を惹かれた。簡単に設定できるキャッシュはインパクトが大きいみたい。まだ使ったこと無いけど。Tomcat三台で運用していたサイトをDjangoだと一台でさばけるようになったとかなってないとか。
Djangoでは複数DBやOracleが使えない点が課題とのこと。ワシントンポストのサイトはDB何使ってるんだろう?

今後0.95から1.0 finalまでの間に入る変更が気になるけど、次のプロジェクトあたりで使ってみてもいいかも。AMFがハンドリングできればもっといいんだけどなあ。


「うくく」って言う方とも話がしたかったですが、あいにく席が離れていたため叶いませんでした。
うくく。

Posted by otsuka : 03:49 | Comment (0) | Trackback (0)