PythonのスクリプトをWebサーバの中で動かす
http.serverモジュールでは、Pythonで書かれたプログラムをWebサーバの中で実行することもできます。その機能を使うと、Webサーバを用意したり設定ファイルを編集することなしに、PythonでWebアプリケーションを作ることができます。Pythonがインストールされたパソコンだけがあればよいので、とても手軽にWebアプリケーションを作って試すことができます。
先ほどスクリプトファイルとHTMLファイルを設置したフォルダに、別のスクリプトファイルを設置してください。
List03 cgiserver.py
:::python
import http.server
server_address = ("", 8000)
handler_class = http.server.CGIHTTPRequestHandler #1 ハンドラを設定
server = http.server.HTTPServer(server_address, handler_class)
server.serve_forever()
先ほどのスクリプトファイルと同じように、このスクリプトファイルを起動します。すると、同じようにWebサーバが立ち上がります。Webブラウザでhttp://127.0.0.1:8000/というURLを開いてください。index.htmlの内容が表示されるはずです。このままサーバを立ち上げておいてください。
Webサーバにプログラムを設置する
先ほどのスクリプトはファイルや画像を扱う機能しか持っていませんでした。しかし、このスプリプトを使うと、サーバ上でPythonのプログラムを動かすことができます。Pythonのプログラムが出力した結果をレスポンスとして返すことができるのです。このスクリプトはハンドラにCGIHTTPRequestHandlerを使っています。(1) ハンドラとは何かの出来事が起きた時にだけ、決まった処理をするもののことです。先ほどのスクリプトのSimpleHTTPRequestハンドラはリクエストを受け取るという出来事が起きると、起動した時のカレントディレクトリにあるファイルを見せ、CGIHTTPRequestハンドラはリクエストを受け取るという出来事が起きると、サーバ上のPythonのプログラムを動かすというわけです。 レスポンスはWebブラウザが受け取って表示します。つまり、PythonのプログラムとWebブラウザの間で通信ができるわけです。クライアントとサーバの間で通信を行うのは、Webアプリケーションの動作原理の最も基本的な部分です。
では、実際にPythonのプログラムを設置して、Webブラウザに結果を表示してみましょう。cgiserver.pyというスクリプトを設置したフォルダに、「cgi-bin」という名前のディレクトリを作ります。新たに作ったディレクトリの中に、以下のようなPythonのファイルを設置してください。
図04 ドキュメントルートにcgi-binフォルダを作り、プログラムを置く
LinuxやMacOS Xを使っている場合は、ファイルを設置したディレクトリ上で、シェルから「chmod 755 test.py」というコマンドを入力してください。Webサーバがファイルをプログラムとして実行できるよう、実行権限を与えます。Windowsの場合は、上記のようなパーミッションの変更は必要ありません。
Webブラウザで先ほど開いたURLの最後に、「cgi-bin/test.py」という文字列を追加してください。つまり、Webブラウザから設置したファイルを呼び出すリクエストを出すわけです。すると、スクリプトが出力した内容が、Webブラウザに伝わって表示されているはずです。
List04 test.py
:::python
#!/usr/bin/env python3
print("Content-type: text/html\n")
print("<html><body>Python is awesome !</body></html>")
簡単にプログラムの内容を解説します。このスクリプトは、print文を使って文字列を表示するというとても単純なプログラムです。print文を使って出力した結果が、Webサーバを経由し、ネットワークを通してWebブラウザにレスポンスとして送り返されていることになります。同じような仕組みを使うと、もっと複雑なHTMLをWebブラウザに送ることができます。Webアプリケーションで実行した処理の結果をWebブラウザ上に表示したり、ユーザインターフェースを表示することもできます。
もう1つ、注意してもらいたい点があります。プログラム側では、3行目にContent-typeから始まる文字列を出力しています。しかし、この文字列はWebブラウザには表示されていません。この部分はヘッダと呼ばれている部分で、Webブラウザに返すレスポンスには必ず要求されます。
このヘッダの詳細については後ほど解説をします。この時点では、Webアプリケーションを作るときに必ず必要な「おまじない」のようなものだ、と思っていてください。
簡単なプログラムを動かす
test.pyを改造して、もう少し複雑なプログラムを作ってみましょう。現在の日時と時刻を計算して、文字列に変換するプログラムを作ります。文字列をレスポンスとして返すことで、Webブラウザ上に日付を表示できます。簡単な日付表示プログラムを作ってみましょう。
先ほどのtest.pyを以下のように書き換えてみましょう。少し長いプログラムです。注意して入力してください。
List05 test.py(改)
:::python
#!/usr/bin/env python3
import datetime
#フォーマット文字列の作成
html_body = """
<html><body>
{0.year:d}/{0.month:d}/{0.day:d} {0.hour:d}:{0.minute:d}:{0.second:d}
</body></html>"""
now=datetime.datetime.now()
print("Content-type: text/html\n")
print(html_body.format(now))
このプログラムでは、datetimeモジュールを使って現在時刻を取得して表示しています。レスポンスとして返すHTMLを組み立てるためには、Pythonの文字列フォーマットという機能を使っています。HTML全体をあらかじめhtml_bodyという変数に定義しておき、最後に現在の日付を埋め込んで出力しています。
プログラムが入力し終わったら、Webブラウザで先ほどと同じURL(http://127.0.0.1:8000/cgi-bin/test.py)にアクセスしてみてください。現在の日付と時刻が表示されたはずです。
プログラムの入力ミスがあると、正しく結果が表示されません。そのようなときは、Webサーバを動かしているシェルを確認してみてください。シェルにエラーの内容が表示されているはずです。
Pythonのエラー表示はトレースパックと呼ばれています。一番最後に、エラーの原因となっている箇所が表示されています。注意してプログラムを直してみてください。
エラー表示の例:コマンドラインで確認
:::python
localhost - - [19/Jun/2007 12:18:04] "GET /cgi-bin/test.py HTTP/1.1" 200 -
File "/Users/ats/dev/python/minpyweb/cgi-bin/test.py"、 line 12 prints "Content-type: text/html¥n"
SyntaxError: invalid syntax
プログラムがちゃんと動いているなら、Webブラウザに現在の日付と時刻が表示されるはずです。
もちろん、動かした時間によって表示の内容は変わります。Webブラウザでリロードをすると、Webサーバにリクエストが送信されて、Pythonのプログラムが動き、そのときの時間をレスポンスとして返すわけです。
ところで、現在の日付と時刻を表示するWebアプリケーションを作ってみたわけですが、時計としてみるとちょっと不便です。Webブラウザでリロードをしないと時刻が更新されません。放っておくと、いつまでも古い情報が表示されています。
Webアプリケーションでは、クライアント(Webブラウザ)のリクエストを受けてレスポンスを返します。そのため、動作が受け身になってしまうのです。このことはWebアプリケーションの大きな特徴です。Webアプリケーションを作るときには、このことをよく覚えておく必要があります。