PythonでCGIを用いたWebアプリケーションを作る

初投稿です。
プログラミング初心者なのでいろいろ至らない点があると思います。
改善点などがあればコメントで教えていただけるとありがたいです。

####本投稿の目的
　大学のレポート課題でCGIを用いたWebアプリケーションをPythonで作ることになったので、その備忘録としてでここに載せておきます。

####CGIとは何か
　そもそもCGIとは何かというと、ブラウザでの要求に対してサーバーがプログラムを起動する仕組みのことです。例えば、下の画像ではブラウザで２つの値を入力し、送信ボタンを押すと、サーバーが入力値の積を表示するcgiプログラムを起動するようになっています。
（参考　http://e-words.jp/w/CGI.html）
<img width="587" alt="report5_form1.PNG" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/511494/9d76f12e-6c5a-379b-4342-a9a7bd9964e1.png">
<img width="380" alt="report5_formtest1.PNG" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/511494/336d2ba3-b8bb-4a61-813b-3667ec3fba46.png">
　今回は上の画像のように、２つの値を入力するとその積を返すアプリケーションを作ります。このアプリケーションを作るにあたって、値を入力させるためのページをhtmlで、入力された値をサーバが受け取り、値を返すプログラムをPythonで記述します。

####入力画面のhtmlソースコード
```form1.html
<!DOCTYPE html>
<html>
<head><meta charset="utf-8" /></head>
<body bgcolor="lightyellow">
<h1>入力値の積を表示します</h1>
    <form action="/cgi-bin/formtest1.py" method="POST">
        値１を入力してください
        <input type="text" name="value1">
        値２を入力してください
        <input type="text" name="value2">
        <input type="submit" name="submit" value="送信">
    </form>
</body>
</html>
```
####ソースコードの解説
・formタグのaction=のうしろには**送信されたときに起動するプログラム**を指定します。
今回は入力値の積を返して表示するformtest1.pyというプログラムを指定します。後でも述べますが、cgi-binという名前のディレクトリにそのプログラムを入れてください。
・formタグのmethodmethod=のうしろには使用するHTTPプロトコルのコマンドを書きます。今回はサーバに要求を送るために'POST'とします。
・inputタグは入力フォームを作成するときに使います。
・type="text"でテキストを入力できるようになります。ちなみに、入力された値はAny型で、string型というわけではないようです。
・type="submit"で送信ボタンを作れます。
・name=でサーバ側で値を受け取る時に使用する名前(属性名) を決めます。
・value=で表示されるものを決めます。

####CGIプログラムのソースコード
```formtest1.py
#!/usr/bin/python
# -*- coding: utf-8 -*-
import cgi
form = cgi.FieldStorage() # cgiオブジェクト作成
v1 = form.getfirst('value1') # nameがvalue1の値を取得
v2 = form.getfirst('value2') # nameがvalue2の値を取得
#入力値が数字ならその積を返す関数
def times(a, b):
    try:
        a=int(a)
        b=int(b)
        return str(a*b)
    except ValueError:
        return('数値じゃないので計算できません(>_<)')
    
# ブラウザに戻すHTMLのデータ
print("Content-Type: text/html")
print()
htmlText = '''
<!DOCTYPE html>
<html>
    <head><meta charset="shift-jis" /></head>
<body bgcolor="lightyellow">
    <h1>こんにちは</h1>
    <p>入力値の積は&nbsp; %s<br/></p>
    <hr/>
    <a href="../form1.html">戻る</a>　
</body>
</html>
'''%(times(v1,v2)) # 入力値の積を%sの箇所に埋める
print( htmlText.encode("cp932", 'ignore').decode('cp932') )
```
####ソースコードの解説
・このプログラムは先ほどのhtmlのコードがあるディレクトリの中に"cgi-bin"という名前のディレクトリにいれてください。
・import cgiでCGIパッケージを使えるようにし、cgi.FieldStorage()でフォームから送信された値を得ています。
・入力された値はint()でint型に直せるかでわからないので、try,except構文で例外処理をしています。
・&nbsp;は空白のエスケープ文字です。%s でstring型で受け取った関数の返り値を埋め込んでいす。
・＜a href="../form1.html"＞戻る＜/a＞で入力画面に戻ることができます。
・例外処理が起きたときは「数値じゃないので計算できません(>_<)」という文字列を表示するのでわざわざ数値もstring型に戻して%Sで埋め込んでいます。
・一番最後の行ではencodeとdecodeを行っていますがlinux,MacOSでは不要です。

####アプリケーションを実際に使ってみよう
　さて、いよいよアプリケーションを使ってみます。
　まず、コマンドプロンプトなどの端末アプリを起動し、**cd form1.htmlがあるディレクトリ**でカレントディレクトリを変更してください。
　次に**python –m http.server 8001 --cgi**と入力してください。すると、CGIを使うWebサーバーが立ち上がり、次のような画面が表示されます。
<img width="880" alt="qiitacgi1.PNG" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/511494/6f434d7a-71e8-0c46-dcca-1cfbbb56a1ec.png">
　serving HTTP on...の部分が表示されたらサーバーが待機している状態です。
　そして、ブラウザでhttp://127.0.0.1:8001/form1.html にアクセスしましょう。127.0.0.1は自分自身のPC内にTCP/IPで通信するには特別なIPアドレスです。またプロキシ設定で127.0.0.1 をプロキシサーバの使用から除外する設定を行っておかないとアクセスできない可能性があります。
　アクセスできたら値を入力してうまく動作するか確かめてみてください。
　うまくいっていたらコマンドプロンプトでctrl + cと入力しWebサーバーを強制終了してください。
####入力画面
<img width="587" alt="report5_form1.PNG" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/511494/e378bf50-f98d-f5f8-0b9e-4bbc2d068c05.png">
####結果画面
<img width="380" alt="report5_formtest1.PNG" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/511494/b7b5e190-1e9f-a771-384b-008d8b86314a.png">
####入力画面（値が数値ではないとき）
<img width="622" alt="report5_form1_notint.PNG" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/511494/2e8f6f06-6a72-7b07-3951-14b8ed4126ae.png">
####結果画面（値が数値ではないとき）
<img width="374" alt="report5_formtest1_notint.PNG" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/511494/85d19bbb-bb62-164f-1943-347a48a1b1b2.png">


おつかれさまでした。