Pythonで作成したプログラムをWeb上で提供したい場合、小規模なものであればCGIプログラムという形で提供するのがオススメです。
PythonといえばDjangoやflaskなどのフレームワークと思われがちですが、あれらはVPS(バーチャルプライベートサーバー)上である程度の環境構築が必要です。(抜け道はありますが。)
つまり初期投資が大きすぎて、Pythonで作成した小規模なツール的なものを公開するのには向いていません。
CGIなら、そのへんで契約できるレンタルサーバーでも大抵はサポートしているので、あなたの作ったプログラムをかなり手軽に公開できます。
というわけで、今回はPythonで作ったWebプログラムをローカルで実行できる環境構築の手順と知識を、ほどよく解説を入れながら比較的素早く習得できるように情報をまとめました。
あんまり勉強したくないんだけどPythonオンCGIしたい!って方にはオススメな内容となっています。
CGIまわりの基本
CGIは単体で使うことはできず、HTTPサーバー経由で呼び出されます。
図にする以下のような感じです。
アクセスの流れとしては
- WebブラウザからのアクセスをHTTPサーバーが受け取る
- HTTPサーバーはアクセスされたパスによって挙動を変える
a. HTMLとしてそのままファイルの情報を返す
b. CGIファイルとして認識された場合はファイルの内容をPythonまどのプログラムに実行させる
といった感じになります。
以上で簡単な説明おしまい。
理解出来ていなくても次に進みましょう。やっていくうちになんとなく分かってくるはずです。
HTTPServerを作成
まずはサンプルのPythonプログラムを書いてみましょう。
# hello.py
print('ケンヂまるだよ')
続いてHTTPサーバーを立てます。
hello.pyがあるフォルダで次のコマンドを実行しましょう。
(このコマンドを実行すると、ローカルホストのポート8000にHTTPServerが起動します。)
python -m http.server
ノート
コマンドについての詳しい情報や、自分でカスタマイズしたサーバーを作る情報はPython公式ドキュメントのhttp.serverモジュールで確認可能。
さあ、ではブラウザでhttp://localhost:8000/ にアクセスしてみましょう。
結果:
どうでしょうか?
プログラムがそのまま表示されるし、日本語は文字化けしているしで、思っていたのとは違う結果になったのではないでしょうか?
そうです、ただのHTTPサーバーというのは、ファイルの内容をほぼそのまま返すだけ。
Pythonプログラムとして実行するということはしてくれないのです。( ̄▽ ̄)
そこで、先ほどのコマンドのヘルプを見てみましょう。
(-hをつけるとヘルプが見れるのでは?と思ってやってみたら本当に見れましたw)
> python -m http.server -h
usage:
server.py [-h] [--cgi] [--bind ADDRESS] [--directory DIRECTORY] [port]
positional arguments:
port Specify alternate port [default: 8000]
optional arguments:
-h, --help show this help message and exit
--cgi Run as CGI Server
--bind ADDRESS, -b ADDRESS
Specify alternate bind address [default: all interfaces]
--directory DIRECTORY, -d DIRECTORY
Specify alternative directory [default:current directory]
--cgiオプションがありますね。
ということで実行してみます。
python -m http.server --cgi
サーバーは無事動作したようです。
これでようやく先ほどのプログラムが動作するかというと、実はそうでもありません。
先ほどは適当にhello.pyを作成しましたが、実はPythonプログラムとして実行するには、いくつかやらなければいけないことがあります。
やること1つ目:hello.pyをcgi-binフォルダに移動させる
CGIサーバーのデフォルトの仕様として、CGIプログラムはcgi-binフォルダに入れましょうとなっています。(これもcgiモジュールのドキュメントに書いてありました)
というわけで、cgi-binフォルダを作ってhello.pyをcgi-binフォルダの中に移動させましょう。
Windowsの場合:
> mkdir cgi-bin
> move hello.py cgi-bin
Mac・Linuxの場合:
> mkdir cgi-bin
> mv hello.py cgi-bin
やること2つ目:hello.pyにHTTPヘッダーの出力を追加する
実は、先ほどのhello.pyは、普通にHTTPサーバーを立ててブラウザでアクセスしただけでは、プログラムは実行されないですよという説明をするため適当に書いたプログラムでしたw
しかしCGIプログラムは、実はHTTPヘッダーというのを最初に送出しないといけません。
CGIに詳しくなくてわからない人は、最初のうちはおまじないとして覚えておけばオッケーな部分なので、あまり深く考えないようにしましょう。あなたの仕事の納期が間に合わなくなります。
# hello.py
# HTTPの仕様によりコンテンツがtext/htmlだよと示す
print("Content-Type: text/html")
# 上記宣言は終わりだよというマークとして改行のみを表示
print()
print('ケンヂまるだよ')
ブラウザでアクセスしてみよう
では、もう一度ブラウザでアクセスしてみましょう。
今回はhello.pyがcgi-binフォルダの中に入っている状態なので、
http://localhost:8000/cgi-bin/hello.py
としてアクセスします。
結果:
どうでしょう、表示されましたか?
これで、Pythonを実行させて、その結果をWebブラウザから確認することができるようになりました。
つまり、あなたのCGIプログラムをテストできる環境が構築できた!ってことです。
フォームの情報を受け取ろう
さて、Pythonプログラムを実行して、その結果を表示できるとはいっても、プログラムというのは入力があって初めて意味をなしますよね。
ということで、フォームから情報を受け取って(入力)、それに対して結果を表示する(出力)サンプルを作ってみましょう。
ここが理解できれば、論理的にはどんなツール・サービスでも作れることになります。
サンプルのファイル構成はこのようにします。
プロジェクトルート
|-hello.html
|-cgi-bin
|-hello.py
hello.htmlでは、<form>タグを使ってフォームを作成し、決定ボタンが押されたらaction="cgi-bin/hello.py"の部分でhello.pyを呼び出すように指定しています。
<!-- hello.html -->
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<form method="POST" action="cgi-bin/hello.py">
<textarea name="text" cols="20" rows="5">
ここに何か文章を入力して下さい。
</textarea>
<input type="submit" />
</form>
</body>
</html>
hello.pyでは、フォームで入力された情報を受け取って、それを10回繰り返した値を出力します。
# hello.py
# CGI関連の入力や出力をサポートするモジュール
import cgi
print("Content-Type: text/html")
print()
# hello.htmlのフォームを表すインスタンスを取得
form = cgi.FieldStorage()
print("あなたの入力した文を10回繰り返してみました。<br />")
# <textarea name="text">に入力された情報を取得
print(form['text'].value * 10)
ノート
フォームで入力した情報を取得するには、Pythonの標準ライブラリのcgiモジュールを使用します。
詳しくはPython公式ドキュメントのcgiモジュールを参照下さい。
ちなみにこのページで紹介している内容は、http.serverモジュールとcgiモジュールのドキュメントの内容のみからなっています。
準備は整いました。
http://localhost:8000/hello.html にアクセスしましょう。
結果:
なにやら怪しげなフォームが表示されています。
何か文章を入力して、「送信」ボタンを押しましょう。
結果:
Pythonプログラムで加工した情報が見事に表示されました!
一見、複雑に思われるCGIプログラムも、基本はこのようにフォームの入力を加工して、プログラムからprintしているに過ぎません。
ここまでわかればあとは作業するだけですね!