Web サーバーで動く Python のアプリについてポイントをまとめておきます。HTMLからPythonを動かします。
必要最小限の知識で済むよう意図しています。
ローカルのパソコンで動かしており、以下の環境で動作確認をしています。
環境: Windows パソコン、Python 3.x (+ Anaconda 3)
※ ここでは Windows のスタンドアロンで Web サーバーを動かす構成例としています。
ローカルネットワーク内の Linux (Raspberry Pi) を Web サーバーとし、Windows からアクセスする構成でも動作確認をしています。関心のある方は、関連リンクも参照してください。
背景 ~ HTMLでPythonを動かしたい
Python の Web アプリケーションのフレームワークとしては、Django や Flask がよく知られています。
ところが、Django を使うまでもないような、ちょっとした Web アプリを手元のローカル PC で作ってPythonのスクリプトを動かしたくなることがあります。
こうしたとき、Google 検索をする限りは、うまくまとまった解説やサンプルがあまり見つからないようです。
Python には標準で Webサーバーの機能があります。複雑なインストールなどをしなくても、サーバーとして動かすことができるはずです。
そこで、もっとも簡単な事例として、ローカル環境のブラウザから、同じくローカル環境の Web サーバーにアクセスし、任意の Python の処理を実行後、処理結果をブラウザに返すスクリプト(電卓アプリ)をまとめ、ポイントを整理しておきます。
作った Python のスクリプトが Webサーバーで動きさえすれば、ブラウザ上で Python を機能させられることになります。Python を実行する際、必ずしもコマンドプロンプトを起動しなくても済むことになります。
また、どのデバイスからであっても、ブラウザ経由で、過去に作成した Python のスクリプトを実行できることになります。スマートフォンなどからローカルネットワークにアクセスして利用すれば、クライアント側のハードウェア要件が緩くなったことと同等となり、プログラムを作ったときの活用の自由度が格段に広がることになります。
加えて、Pythonの特徴である機械学習などの機能とウェブの機能を連携させることも視野に入ります。
なお、ここに挙げたサンプルは、ローカル PC 上で、または、ローカルのネットワーク内で使用することを想定しています。異常処理などは考慮しておりませんので、ご理解ください。
設定手順
ステップ1:ドキュメントルートの設定
① ドキュメントルート(公開フォルダに該当)とするためのフォルダを作成してください。
例: C:\user\html1
② ①のフォルダ内にさらに “cgi-bin” というフォルダを作成してください。
③ ②の “cgi-bin” フォルダ内に “calc1.py” というテキストファイルを作成し、末尾のサンプルコードをコピーペーストして保存してください。単純な足し算をする電卓アプリになっています。
ステップ2:Web サーバーの起動
④ コマンドプロンプト(または、Anaconda Prompt)を起動して、①のフォルダに移動してください。
⑤ 以下のコマンドを実行し、ローカル PC 上で Web サーバーを起動してください。
例:
python -m http.server 8000 --cgi
※ ここで、コマンドプロンプトに ”Serving HTTP on 0.0.0.0 port 8000 (http://0.0.0.0:8000/) …” 等の文字列が表示されたら、Web サーバが起動しています。
※ また、8000 という数値(ポート番号)は、⑤、⑥以降がうまく動かなければ、変えてみてください。
※ Web サーバーを停止する場合は、コマンドプロンプト上で、[ctrl] + c をタイプしてください。
ステップ3:ブラウザでの確認
⑥ ⑤で Web サーバーを稼働させた状態で、Microsoft Edge などのブラウザを起動し、URL 部分に以下を貼りつけて表示させてください。
http://localhost:8000/cgi-bin/calc1.py
※ ここで、8000 という数字は、④で設定した数値と一致させてください。
⑦ ブラウザに冒頭の画像で示した表示がされたら、起動成功です。
入力欄に整数を入れて「calculate」ボタンをクリックしてみてください。
サーバー側(Python 側)で計算を行い、結果を返す動きとなります。
⑧ うまく動いたら、Python のスクリプトを変えて、アレンジしてみてください。
なお、できる限り簡素なサンプルにしているため、異常時の処理などは入れていませんので、ご理解ください。
サンプルコードの説明:Webアプリの動き
Webアプリの動きを時間の流れで説明します。
Webサーバーの初回の動き
① Webサーバーを稼働させた状態で、ユーザーがブラウザから calc1.py のある URL にアクセスします。
② すると、Webサーバー側では、Python スクリプト calc1.py を呼び出して実行し、str0 で定義した HTML を返します。
初回のアクセス時は、元々のHTMLが存在しません。すると、GETメソッドに対応する .getvalue() で値の取得ができず、HTMLのテキストボックスに “0” を差し込んだ HTML を生成します。
Webサーバーは生成したHTMLをクライアントに返します。
HTMLからPythonファイルを実行する
③ HTMLにはボタンが配置してあります。また、<form name=… method =”POST” action=”/cgi-bin/calc1.py”> としたところで、HTMLにPythonを埋め込んであります。HTMLで、別プログラムとしたPythonスクリプトを呼び出す記載としています。
④ ユーザーがブラウザのHTML上で数値を入力し、ボタンをクリックすると、Pythonのスクリプト(cgi-bin/calc1.py)が実行されます。HTMLでPythonを動かすことになります。
⑤ Python が実行されると、Webサーバー側では、Pythonのスクリプトの記載に従って .getvalue() メソッドが実行されます。今度は、クライアント側で HTML が存在していたので、テキストボックスの入力値が取得できます。Webサーバーは、計算を実行し、合計値の結果を挿入した HTML を返します。
⑥ この後、④に戻ります。
★ ④~⑥から、Python の標準機能を使って、HTMLからPythonを実行する動きになっていることがわかると思います。
※ すでに何らかの複雑なプログラムや特殊なアルゴリズムが手元にあるとき、ブラウザや Web サーバーの機能と自由に組み合わせることが可能です。
※ また、パソコンの OS やハードウェア環境に強く縛られずに GUI アプリを開発できることになります。
たとえば、何かのプログラムを作ろうとして、Microsoft などの特定の OS やコンパイラなどに縛られたくないとき、Web アプリで作ってしまえば、Linux 等の他の OS への移植性が確保でき、アプリ作成後の陳腐化リスクを低減できることになります。
まとめ
ローカルの Web サーバー上で動く Python のサンプルについてまとめました。
たかだか30行ほどの Python のプログラミングで、ブラウザ経由で Web サーバーに変数を渡し、任意の Python のスクリプトを実行後、処理結果を返すことができる、ということがわかります。
ブラウザから Python を動かそうとして、ネット検索をすると、Django や Flask のページが多数ヒットします。ところが、ブラウザとサーバがどのように動くかといった観点でプログラムも含めてシンプルにまとめられたものは見つかりませんでした。そこで、ポイントを整理し、公開しておくことにします。
なお、今回は1台のパソコンで Web アプリを動かす構成についてまとめました。
システムの構成を変え、ローカルネットワーク内で Linux (Raspberry Pi) を Web サーバーとし、別の Windows パソコンからブラウザ経由でアクセスしても動作しています。ポイントを下記の関連リンクにまとめています。
もし関心があるようでしたら、参考にしてみてください。Webサービスなど、何でもできそうな気がしてくると思います。
関連リンク
・ Python で Web サーバーを動かす 【Windows 版】
・ Python で掲示板を作ってみる 【Windows 版】
・ Raspberry Pi でローカルWebサーバー 【Python 活用】
・ Webサーバーで動く Python アプリ 【Raspberry Pi 版】
・ レンタルサーバーの比較表
サンプルコード ~ 簡易電卓 calc1.py
#!/usr/bin/python3
# coding: utf-8
import cgi
import sys, io
# python -m http.server 8000 --cgi
# http://localhost:8000/cgi-bin/calc1.py
sys.stdout = io.TextIOWrapper(sys.stdout.buffer, encoding='utf-8')
form1 = cgi.FieldStorage()
str01 = form1.getvalue( 'TextBox1', '0' )
str02 = form1.getvalue( 'TextBox2', '0' )
str03 = str( int( str01 ) + int( str02 ) )
# str03 = str( float( str01 ) + float( str02 ) )
str0 = '''
<html>
<body>
<form name="Form" method="POST" action="/cgi-bin/calc1.py">
<input type="text" size="10" name="TextBox1" value="{str11}"> +
<input type="text" size="10" name="TextBox2" value="{str12}"> =
<input type="text" size="10" name="TextBox3" value="{str13}"><br><br>
<input type="submit" value="calculate" name="button1">
</form>
</body>
</html>
'''.format( str11=str01, str12=str02, str13=str03 )
print("Content-Type: text/html; charset=UTF-8;\n")
print( str0 )