CORESERVER で Python の CGI を動かす


概要

  • GMOデジロックのレンタルサーバー「コアサーバー」で Python の CGI を動作させる

今回の環境

  • 料金プラン: ビジネスプラン「CORE-B」 (30日間無料お試しトライアル期間中)
  • サーバー: b1.coreserver.jp
  • Python 3.6.8

設定: CGI 実行ファイルの拡張子を cgi または py にする

.cgi ファイルは最初から CGI として実行できるようになっているので、実行権限をつけて置いておけば良い。

$ ls -l ~/public_html/hello.cgi
-r-xr-xr-x 1 alice hpusers 414 12月 12 20:08 /virtual/alice/public_html/hello.cgi

拡張子を py にしたい場合、 .py ファイルは CGI として実行できるようになっていないので、 CGI として実行されるための設定を記述した .htaccess ファイルを設置する。

$ ls -l ~/public_html/.htaccess 
-rw-r--r-- 1 alice hpusers 27 12月 12 18:09 /virtual/alice/public_html/.htaccess

.htaccess の中身は以下のように記述する。

AddHandler cgi-script .py

Hello World 表示サンプル (hello.cgi)

ソースコードの場所

$ ls -l ~/public_html/hello.cgi
-r-xr-xr-x 1 alice hpusers 414 12月 12 20:08 /virtual/alice/public_html/hello.cgi

ソースコード

#!/usr/local/bin/python3

import io
import sys

# 出力ストリームの文字エンコーディングを指定
sys.stdout = io.TextIOWrapper(sys.stdout.buffer, encoding='utf-8')

# HTTP ヘッダ
print('Content-Type: text/html; charset=utf-8')
print() # blank line, end of headers

# HTML 本文
print('<html><body>')
print('Hello, world.<br>')
print('こんにちは、世界。<br>')
print('</body></html>')

アクセス結果

$ curl http://alice.b1.coreserver.jp/hello.cgi
<html><body>
Hello, world.<br>
こんにちは、世界。<br>
</body></html>

入力値の表示サンプル (message.py)

ソースコードの場所

$ ls -l ~/public_html/message.py 
-r-xr-xr-x 1 alice hpusers 565 12月 12 20:14 /virtual/alice/public_html/message.py

ソースコード

message.py
#!/usr/local/bin/python3

import cgi
import html
import io
import sys

# 出力ストリームの文字エンコーディングを指定
sys.stdout = io.TextIOWrapper(sys.stdout.buffer, encoding='utf-8')

# message パラメータの値を取得
form = cgi.FieldStorage()
message = form.getfirst('message', 'Hello, world.')

# HTTP ヘッダ
print('Content-Type: text/html; charset=utf-8')
print() # blank line, end of headers

# HTML 本文
print('<html><body>')
print(f'message: {html.escape(message)}') # HTMLエスケープして出力
print('</body></html>')

アクセス結果

$ curl http://alice.b1.coreserver.jp/message.py?message=%E7%BD%AA%E3%81%A8%C3%97
<html><body>
message: 罪と×
</body></html>

外部ライブラリ利用サンプル (draw.py)

パッケージをインストール

今回は ~/my-space ディレクトリに NumPy パッケージと Matplotlib パッケージをインストールする。

$ python3 -m pip install numpy matplotlib --target ~/my-space

~/my-space ディレクトリにパッケージが設置される。

$ ls ~/my-space
__pycache__                                 numpy
bin                                         numpy-1.17.4.dist-info
cycler-0.10.0.dist-info                     pkg_resources
cycler.py                                   pylab.py
dateutil                                    pyparsing-2.4.5.dist-info
easy_install.py                             pyparsing.py
kiwisolver-1.1.0.dist-info                  python_dateutil-2.8.1.dist-info
kiwisolver.cpython-36m-x86_64-linux-gnu.so  setuptools
matplotlib                                  setuptools-42.0.2.dist-info
matplotlib-3.1.2-py3.6-nspkg.pth            six-1.13.0.dist-info
matplotlib-3.1.2.dist-info                  six.py
mpl_toolkits

ソースコードの場所

$ ls -l ~/public_html/draw.py 
-r-xr-xr-x 1 alice hpusers 922 12月 15 01:53 /virtual/alice/public_html/draw.py

ソースコード

draw.py
#!/usr/local/bin/python3

import io
import sys

# モジュール検索パスにライブラリのパスを追加
sys.path.append('../my-space')

# NumPy と Matplotlib を読み込む
import numpy as np
import matplotlib
import matplotlib.pyplot as plt

# データの作成
x = np.arange(0, 6, 0.1) # 0から6まで0.1刻みで生成
y1 = np.sin(x)
y2 = np.cos(x)

# グラフの描画
plt.figure(figsize=(4, 3), dpi=160) # 画像サイズ
plt.plot(x, y1, label='sin')
plt.plot(x, y2, linestyle = '--', label='cos') # 破線で描画
plt.xlabel('x') # x軸のラベル
plt.ylabel('y') # y軸のラベル
plt.title('sin & cos') # タイトル
plt.legend() # 凡例

# PNG 画像バイト列を生成
image = io.BytesIO()
plt.savefig(image, format='png')
image.seek(0)

# HTTP ヘッダ
sys.stdout.buffer.write(b'Content-Type: image/png\n\n')

# 画像バイナリデータを出力
sys.stdout.buffer.write(image.read())

アクセス結果

$ curl --dump-header - -s http://alice.b1.coreserver.jp/draw.py --output a.png
HTTP/1.1 200 OK
Date: Sat, 14 Dec 2019 17:05:05 GMT
Server: Apache
Vary: User-Agent
Transfer-Encoding: chunked
Content-Type: image/png

保存した a.png ファイル。

参考資料