python3にてJSONを受け取ってJSONを返す簡単なサーバを立てる

# やりたいこと
python3で標準モジュールだけでPOSTしたら、JSONで結果を返すようにする
なにかモックで作成するときとかはさくっとできるので便利かなと思います。
Flaskとかもあるけど、ぱっと試したいときには便利かもです。

# 環境
- OS: Ubuntu 14.04
- Python : python 3.4.7

# コード
```py3
#!/usr/bin/env python
# -*- coding:utf-8 -*-

__author__ = "omori"
__version__ = "1.0.0"

import argparse
import json
from http.server import BaseHTTPRequestHandler, HTTPServer

class MyHandler(BaseHTTPRequestHandler):
    """
    Received the request as json, send the response as json
    please you edit the your processing
    """
    def do_POST(self):
        try:
            content_len=int(self.headers.get('content-length'))
            requestBody = json.loads(self.rfile.read(content_len).decode('utf-8'))

            response = { 'status' : 200,
                         'result' : { 'hoge' : 100,
                                      'bar' : 'bar' }
                        }
            self.send_response(200)
            self.send_header('Content-type', 'application/json')
            self.end_headers()
            responseBody = json.dumps(response)

            self.wfile.write(responseBody.encode('utf-8'))
        except Exception as e:
            print("An error occured")
            print("The information of error is as following")
            print(type(e))
            print(e.args)
            print(e)
            response = { 'status' : 500,
                         'msg' : 'An error occured' }

            self.send_response(200)
            self.send_header('Content-type', 'application/json')
            self.end_headers()
            responseBody = json.dumps(response)

            self.wfile.write(responseBody.encode('utf-8'))

def importargs():
    parser = argparse.ArgumentParser("This is the simple server")

    parser.add_argument('--host', '-H', required=False, default='localhost')
    parser.add_argument('--port', '-P', required=False, type=int, default=8080)

    args = parser.parse_args()

    return args.host, args.port

def run(server_class=HTTPServer, handler_class=MyHandler, server_name='localhost', port=8080):

    server = server_class((server_name, port), handler_class)
    server.serve_forever()

def main():
    host, port = importargs()
    run(server_name=host, port=port)

if __name__ == '__main__':
    main()
```

たった、こんだけ！楽ですね～。
python3系では、HTTPのサーバ関連は、http.serverに集約されたとのこと。
BaseHTTPRequestHandlerの中の'do_POST'をオーバライドすることで、
リクエストに応じて、結果を返すようにできる

`json.loads(self.rfile.read(content_len).decode('utf-8'))` で、リクエストのボディを読み込んだ後、
`json.loads`にて、jsonをパースしてます。

`self.send_response'と`self.send_header` で、HTTPのレスポンスコードと、ヘッダ部を書いてます。
そして、`response`に結果を格納したうえで、jsonにdumpして、`self.wfile.write`にて結果を返してます。


# 確認
上記のコードを`test_server.py`などとして、

`python test_server.py` を実行
そして、別ターミナルで下記のようにリクエストしてみてください。

## リクエスト例
 `curl -XPOST -d '{ "hoge" : 1, "bar" : "bar" }' http://localhost:8080`


~~サーバ側で`bar`というキーをprintしているので、上記のコードのままだと`bar`がなければエラーになりますので、ご注意を。~~

## レスポンス
{"bar": "bar", "hoge": 100}
(responseで定義した辞書型がjsonになって出力される）


## サーバ側の出力例
```
127.0.0.1 - - [05/Oct/2017 23:18:36] "POST / HTTP/1.1" 200 -
```
~~barが出力されるのは、サーバ側で、`print(requestBody['bar'])`をしているためです。~~




# 参考
- pythonの公式ドキュメント
    https://docs.python.jp/3/library/http.server.html

- PythonでJSONを受けて処理をする
    http://d.hatena.ne.jp/matasaburou/20151003/1443882557

- BaseHTTPServer – web サーバを実装するベースクラス
    http://ja.pymotw.com/2/BaseHTTPServer/

# その他
(モックだけなら手を抜いてもよいですが）入力チェックとエラー処理もちゃんとする方がよいです。

一応、エラー処理を追加しました。

コードをgithubにもおいています。

https://github.com/komorin0521/python_sandbox/blob/master/python3/server.py