Pythonで作成したWebアプリをエックスサーバー上で稼働させる

##概要
Pythonで簡単なWebアプリを作成しました。手順としては、まずパソコン上のローカルホスト (localhost)でテストし、最後にエックスサーバーにアップロードしました。画面表示が英数字だけであれば簡単ですが、漢字を表示させるために少し苦労したのでその手順をまとめておきます。
ちなみに作成したプログラム（cgitest.py）は次のとおり、フォームで数字を入力し足し算をした結果を表示する簡単なものです。

```python3:cgitest.py 
#!/usr/bin/env python3.4
# -*- coding: utf-8 -*-

# 足し算を行うプログラム

import cgi
import datetime as dt
import sys
import io

# 注1 エックスサーバーで漢字を表示するために必要
sys.stdout = io.TextIOWrapper(sys.stdout.buffer, encoding='utf-8')
# ヘッダの出力
print("Content-type: text/html; charset=UTF-8")
print("")

# 送信されたフォームデータを取得する
form = cgi.FieldStorage()

# フォームに入力があるか?
if (not 'x' in form) or (not 'y' in form):
    # 入力フォーム
    print("""
        <form>
        <input type="text" name="x"> +
        <input type="text" name="y">
        <input type="submit" value="計算">
        </form>
    """)
else:
    # 結果を表示
    x = form.getvalue("x", "0")
    y = form.getvalue("y", "0")
    add = int(x) + int(y)
    print("答えは", add, "です")

```

また、実験用のフォルダをc:\Pythonとしましたが、ローカルホストで動かすためには、そのc:\Pythonの下に” cgi-bin”という名前のサブフォルダを作成し、プログラムは、その中に保存する必要があります。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/258643/19a5b942-fa83-f232-e668-10736c1a6428.png)


##ローカルホストでプログラムを動かす
###ローカルホストを立ち上げる
コマンドプロンプトから、cdコマンドで、カレントフォルダをcgi-binが入っているフォルダ（ここでは”c:\Python”に移動します。ここで、次のコマンドを入力します。

|    python -m http.server --cgi 8080                     |
|:--------------------------------------|

http.serverは、webサーバーを実装するためのクラスを提供するためのモジュールです。本来はWebのプログラムなので、もう1台サーバーマシンを用意してテストしなければなりませんが、それは大変なので同じマシンの中に仮想的なサーバーを用意することができるというありがたい機能です。また、cgiはCommon Gateway Interface略で、サーバー上でプログラムを動作させるための仕組みのことです。”8080”はポート番号と呼ばれ、サーバーマシンでhttp というプロトコルを使った情報の受け口を意味します。要するに、pythonで作ったwebプログラムを同じマシンの中で実験するためのおまじないと考えればよいと思います。結果として、コマンドプロンプト上で、次のとおり表示されれば準備完了です。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/258643/26f9bd2d-174b-ed27-d71d-ed7fe5cd44d2.png)
###ブラウザからプログラムを稼働させる
ブラウザ（ここではChromeを使っています）からアドレスバーに次のとおり入力すると、プログラムが稼働しフォームが表示されます。ローカルホストはc:\Pythonから立ち上げたので、その中のcgi-binフォルダにあるプログラム：cgitest.pyを呼び出しています。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/258643/b7f26881-d191-0ffb-3439-749c4047f0e7.png)
ここで、フォームに数字を入力し、計算のボタンをクリックします。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/258643/8c75a9d2-913c-a775-8f0e-b1a10d34ef5d.png)
すると、次の結果が表示されます。ここで注目したいのがアドレスバーの表示です。プログラムの変数、xに1、yに2の数字が代入されたことが確認できます。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/258643/60a23b85-e262-8923-1621-46ef2682eb51.png)
以上で、ローカルホストを使ってpythonで作成したプログラムを動かすことができました。


##エックスサーバー上で稼働させる
テストが上手く行ったので、作成したプログラムをエックスサーバー上にアップロードすればよいのですが、実際には少し苦労しました。特に、漢字を表示するためには少し工夫が必要です。そこで、試したことをまとめます。
###プログラム上のポイント

- エックスサーバーで稼働するpythonはバージョン3.4なので、1行目は次のとおりとしました。

|    #!/usr/bin/env python3.4                     |
|:--------------------------------------|


- 文字コードはutf-8を使用するため、2行目に次のコードを記述します。

|# -*- coding: utf-8 -*-                     |
|:--------------------------------------|



-　同様に、次のような記述も必要です。sys.stdoutはprint文の出力先を意味し、ここでもutf8を指定します。漢字を使う場合にはこの文がないと、ブラウザ上で画面が真っ白になってしまいます。

 
|sys.stdout = io.TextIOWrapper(sys.stdout.buffer, encoding='utf-8') |
|:--------------------------------------|

- さらに”Content-type”にもcharset=UTF-8を入れました。

|    print("Content-type: text/html; charset=UTF-8")            |
|:--------------------------------------|

- このように文字コードはutf-8を使うので、テキストエディタ（例えばクレッセントイブ）でプログラムを保存するときには、文字コードを”UTF-8”とし、改行はCR+LFにします。

- ![image.png](https://qiita-image-store.s3.amazonaws.com/0/258643/34118a8f-ab28-5c7d-8acb-3ed71922205a.png)

###エックスサーバー上のポイント

- アップロードするときには、アスキーモード、文字コードはUTF-8にします。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/258643/1941a225-91b4-dc4c-a89f-ab0bd1b31a83.png)

- エックスサーバーではpythonのcgiのパーミッションは、”705”または”755”なので、アップロード後、いずれかに変更します。パーミッションとはファイルの閲覧権限設定のことで、契約しているレンタルサーバーやプログラムによって数値が異なります。

- 最後にここが大切ですが、プログラムの拡張子：pyをcgiに変更します。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/258643/d2982b49-f43b-6b3d-59f2-1d05a152e50c.png)

以上、いろいろ書きました。これらがすべて必須ではないかもしれませんが、エックスサーバーにアップロードした後、漢字がうまく表示されなかったので、いろいろ試行錯誤した結果をまとめてみました。参考にしていただけると幸いです。