仮に、以下のように設定しているとしましょう:
<Directory /mywebdir>
AddHandler mod_python .py
PythonHandler myscript
PythonDebug On
</Directory>
注意: /mywebdir は物理的な絶対パスです。
さらに、以下のような内容の Python プログラムが /mywebdir/myscript.py にあるとします (Windows ユーザは、ファイル名のスラッシュをバックスラッシュに 置き換えてください):
from mod_python import apache
def handler(req):
req.content_type = "text/plain"
req.write("Hello World!")
return apache.OK
すると,こんな処理が行われます: まずAddHandler ディレクティブが
Apache に/mywebdir またはそれ以下のディレクトリにある
.py で終わる全てのファイルに対する全てのリクエストを mod_python
で処理するよう教えます。"PythonHandler myscript" ディレクティブは、
mod_python が generic ハンドラでの処理をmyscript スクリプトで
行うように指示します。"PythonDebug On" でぃれくてぃぶは、
Python のエラーが発生した場合にエラー出力を (ログへの記録に加えて)
クライアントに送信するよう mod_python に指示します。開発中には、
この機能はとても便利です。
さて、リクエストが送られてくると、Apache は mod_python のハンドラを 呼び出してリクエスト処理フェイズを開始します。mod_python ハンドラは 設定中にリクエストの内容に該当するハンドラを指定しているディレクティブがないか 探します(mod_python はディスパッチャのように働くことを思い出してください)。 ここで示した例題では、mod_python に generic ハンドラ以外のハンドラに ついて何もしていません。 generic ハンドラの番になると、mod_python は "PythonHandler myscript" ディレクティブがあることに気づき、 以下のような処理を行います:
PythonHandler ディレクティブを指定しているディレクトリが
sys.path に追加されていなければ追加します。
myscript という名前のモジュールを import しようと試みます。
(myscript がPythonHandler ディレクティブの指定されている
ディレクトリのサブディレクトリにある場合、import はうまくいかないので注意
してください。これはサブディレクトリが sys.path に入っていないからです。
"PythonHandler subdir.myscript" のようなパッケージ表記を使えば
この問題を回避できます。)
myscript 中に関数handler がないか探します。
handler を呼び出します
(request オブジェクトについては後で詳しく述べます)。
from mod_python import apache
def handler(req):
ハンドラ (handler) 関数の宣言です。mod_python は ディレクティブ名を小文字表記にして先頭の "python" を取り除いた名前を ハンドラ名に使うため、この関数は "handler" という名前になるのです。 ハンドラ関数に別の任意の名前を使って、"::" でディレクティブに明示的に 指定しても構いません。例えば、ハンドラが"spam" という関数だったなら、 ディレクティブは"PythonHandler myscript::spam" になったでしょう。
ハンドラは引数を一つ - request オブジェクト - を取らねばなりません。 request オブジェクトとは、例えばクライアントの IP アドレス、ヘッダ、 URI といった、あるリクエストに関する全ての情報の入ったオブジェクトです。 クライアントへの返信も request オブジェクトを介して行います。従って、 「応答オブジェクト (response object)」はありません。
req.content_type = "text/plain"
この行では、コンテントタイプを "text/plain"に設定しています。 通常、デフォルトでは"text/html"を使いますが、ここで定義するハンドラ が生成するのはHTMLではないので"text/plain"の方が適切です。
req.write("Hello World!")
文字列"Hello World!" をクライアントに書きます(説明するまでもありませんね?)
return apache.OK
全ての処理がうまくいき、リクエストが処理されたことをApacheに教えます。 処理がうまく行かなかった場合には、この行で apache.HTTP_INTERNAL_SERVER_ERROR や apache.HTTP_FORBIDDEN を返すことになります。 処理がうまく行かなかった場合、 Apache はエラーをログに記録して、 クライアント向けのエラーメッセージを生成します。
熟慮すべきこと: 注意深く読んでいれば、上のテキストで、 ハンドラコードを実行するために URL で myscript.py を参照する 必要があると書いていないことに気づいたでしょう。必要なのは、.py URL がファイルを参照しているということだけです。 実際、ファイルの名前自体は問題ではなく、URL が指し示しているファイルが実在 しなくてもかまわないのです。 従って、上の設定の下では、"http://myserver/mywebdir/myscript.py" も "http://myserver/mywebdir/montypython.py" も同じ結果になるのです。 ここで理解しておかねばならない要点は、ハンドラは特定のタイプのファイルを処理する 際の動作を指定しているのであって、個々のファイルの動作を個別に指定しているのでは ないということです。
ここまで読み進んだ時点で上の文章が理解できなかった場合は、理解できるまで 戻って何度も読み返してください。