3.3 mod_python は一体何をやっているのか

仮に、以下のように設定しているとしましょう:

  <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" ディレクティブがあることに気づき、 以下のような処理を行います:

  1. PythonHandler ディレクティブを指定しているディレクトリが sys.path に追加されていなければ追加します。

  2. myscript という名前のモジュールを import しようと試みます。 (myscriptPythonHandler ディレクティブの指定されている ディレクトリのサブディレクトリにある場合、import はうまくいかないので注意 してください。これはサブディレクトリが sys.path に入っていないからです。 "PythonHandler subdir.myscript" のようなパッケージ表記を使えば この問題を回避できます。)

  3. myscript 中に関数handler がないか探します。

  4. リクエスト (request) オブジェクトを渡してhandler を呼び出します (request オブジェクトについては後で詳しく述べます)。

  5. この時点で、処理はスクリプトの中に移ります:

熟慮すべきこと: 注意深く読んでいれば、上のテキストで、 ハンドラコードを実行するために URL で myscript.py を参照する 必要があると書いていないことに気づいたでしょう。必要なのは、.py URL がファイルを参照しているということだけです。 実際、ファイルの名前自体は問題ではなく、URL が指し示しているファイルが実在 しなくてもかまわないのです。 従って、上の設定の下では、"http://myserver/mywebdir/myscript.py" も "http://myserver/mywebdir/montypython.py" も同じ結果になるのです。 ここで理解しておかねばならない要点は、ハンドラは特定のタイプのファイルを処理する 際の動作を指定しているのであって、個々のファイルの動作を個別に指定しているのでは ないということです。

ここまで読み進んだ時点で上の文章が理解できなかった場合は、理解できるまで 戻って何度も読み返してください。