Webサーバーで動くPythonアプリ 【Windows】

Python

Web サーバーで動く Python のアプリについてポイントをまとめておきます。HTMLからPythonを動かします。
必要最小限の知識で済むよう意図しています。

ローカルのパソコンで動かしており、以下の環境で動作確認をしています。
環境: Windows 10 PC、Python 3.x (+ Anaconda 3)
※ また、Python のスクリプトを Linux に移植してクライアントとサーバーの構成としても同様に動きました。

背景 ~ HTMLでPythonを動かしたい

Python には標準で Webサーバーの機能があります。
Python の Web アプリケーションのフレームワークとしては、Django がよく知られています。
ところが、Django を使うまでもないような、ちょっとした Web アプリを手元のローカル PC で作ってPythonのスクリプトを動かそうとしたとき、Google 検索をする限りは、うまくまとまった解説やサンプルがあまり見つからないようです。

そこで、もっとも簡単な事例として、ローカル環境のブラウザから、同じくローカル環境の Web サーバーにアクセスし、任意の Python の処理を実行後、処理結果をブラウザに返すスクリプト(電卓アプリ)をまとめ、ポイントを整理しておきます。

作った Python のスクリプトが Webサーバーで動きさえすれば、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 パソコンからブラウザ経由でアクセスしても動作しています。ポイントを下記の関連リンクにまとめています。
もし関心があるようでしたら、参考にしてみてください。何でもできそうな気がしてくると思います。

関連リンク
・ Raspberry Pi でローカルWebサーバー 【Python 活用】
・ Python で Web サーバーを動かす 【Windows】
・ ローカル環境で django をインストールする 【Anaconda & Windows】

サンプルコード

#!/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 ) 
タイトルとURLをコピーしました