PythonにおけるWSGIに対応したリクエスト処理となります。Python 3系におけるWSGIアプリケーションでは、returnで結果を返す際にencodeでbytesへ変換する必要があります。
※CGIでのリクエストの取得方法は「リクエストの取得 (CGI)」をご覧ください。
GET
GETリクエストの処理方法は下記の通りとなります。
import cgi
from wsgiref.simple_server import make_server
# HTML文字列
html = '''
<!DOCTYPE html>
<html>
  <head>
    <title>WSGI</title>
    <meta charset="UTF-8">
  </head>
  <body>
    {}
    <hr>
    {}
    <hr>
    {}
  </body>
</html>
'''
def parse_query(params):
    name = '未入力'
    email = '未入力'
    for param, value in params:
        if param == 'name':
            name = value
        elif param == 'email':
            email = value
    errors = []
    if name == '未入力':
        errors.append('メールアドレスの入力がありません。')
    if email == '未入力':
        errors.append('お名前の入力がありません。')
    return name, email, errors
def test_app(environ, start_response):
    start_response('200 OK', [('Content-Type','text/html')])
    # フォームから値を取得( GET )
    query = cgi.parse_qsl(environ.get('QUERY_STRING'))
    name, email, errors = parse_query(query)
    result = 'お名前:{}<br />'.format(name)
    result += 'メールアドレス: {}'.format(email)
    # 結果を表示
    return [html.format(
        'リクエストは {} です。'.format(environ.get('REQUEST_METHOD')),
        result, 
        '<br />'.join(errors)
    ).encode('UTF-8')]
# WSGIテストサーバーの作成
with make_server('', 8000, test_app) as httpd:
    # テストサーバーによる待ち受け
    print('Serving HTTP on 0.0.0.0 port 8000 (http://0.0.0.0:8000/) ...')
    httpd.serve_forever()
47行目のcgi.parse_qslの戻り値はリストで、内包される値は各パラメータを保持したタプルとなります。たとえば次のようなURLでアクセスした場合の戻り値は[(‘name’, ‘test_user’), (‘email’, ‘test_user@example.com’)]のような形となります。
POST
POSTリクエストの処理方法は下記の通りとなります。次の例はGETでアクセスしてきたときには入力フォームを、POSTでアクセスしてきたときには入力値を表示する形です。
import cgi
from wsgiref.simple_server import make_server
# 入力HTML文字列
input_html = '''
<!DOCTYPE html>
<html>
  <head>
    <title>CGI</title>
    <meta charset="UTF-8">
  </head>
  <body>
    <form method="POST" action="/">
      <input type="text" name="name">
      <input type="text" name="email">
      <input type="submit">
    </form>
  </body>
</html>
'''
# 結果HTML文字列
result_html = '''
<!DOCTYPE html>
<html>
  <head>
    <title>CGI</title>
    <meta charset="UTF-8">
  </head>
  <body>
    {}
    <hr>
    {}
    <hr>
    {}
  </body>
</html>
'''
def parse_query(query):
    name = '未入力'
    email = '未入力'
    for param, value in query:
        if param == b'name':
            name = value.decode('UTF-8')
        elif param == b'email':
            email = value.decode('UTF-8')
    errors = []
    if name == '未入力':
        errors.append('メールアドレスの入力がありません。')
    if email == '未入力':
        errors.append('お名前の入力がありません。')
    return name, email, errors
def test_app(environ, start_response):
    start_response('200 OK', [('Content-Type','text/html')])
    method = environ.get('REQUEST_METHOD')
    # フォームから値を取得
    if method == 'POST':
        wsgi_input = environ['wsgi.input']
        content_length = int(environ.get('CONTENT_LENGTH', 0))
        query = cgi.parse_qsl(wsgi_input.read(content_length))
        name, email, errors = parse_query(query)
        result = 'お名前:{}<br />'.format(name)
        result += 'メールアドレス: {}'.format(email)
        # 結果を表示
        return [result_html.format(
            'リクエストは {} です。'.format(method),
            result, 
            '<br />'.join(errors)
        ).encode('UTF-8')]
    return [input_html.encode('UTF-8')]
# WSGIテストサーバーの作成
with make_server('', 8000, test_app) as httpd:
    # テストサーバーによる待ち受け
    print('Serving HTTP on 0.0.0.0 port 8000 (http://0.0.0.0:8000/) ...')
    httpd.serve_forever()
cgi.parse_qslを用いるのはGETと変わりませんが、その過程が異なります。先に述べた通りGET/POSTで処理が分岐するため、次のURLへアクセスした時には入力フォームが表示されます。submitボタンを押すとPOSTアクセスとなるため、その入力値を取得・表示します。
またPOSTでは入力値がbytesで取得されます( [(b’name’, b’test_user’), (b’email’, b’test_user@example.com’)] のような形)。47行目、49行目でdecodeしてから値を格納している点に注意してください。
テストサーバーでの動作確認
先の例をmain.pyとして保存し、次のようなディレクトリ階層で配置するものとします。WSGIテストサーバーの処理はすでにソースコード内に記述してあるので、それを起動するだけです。
- c:
 
- python
 
- main.py
 
次のコマンドを入力し、まずはc:/pythonへ移動します。
cd c:/python
次に簡易テストサーバーを起動します。
python main.py
待ち受け状態となったらウェブブラウザを開き次のURLを入力してください。あとに続く画像がPOSTのサンプルプログラムにおけるウェブブラウザでの表示例です。

 
何も入力せずに送信ボタンを押すと、次のような画面となります。入力値を取得できなかったので、お名前やメールアドレスが未入力となっているはずです。

 
最初の入力フォームへ戻り、値を入力してから送信ボタンを押すと次のようになります。POSTで値を取得できたので、その入力値が表示されます。また「〇〇の入力がありません。」というエラーメッセージがなくなっています。

