【Python】jsonなどを返すhttpサーバー作成

pyhton

 業務中、外部Rest APIと連携する機能がたまたまあると思いますが、同時開発などの理由で対向システムは必ず完了して、呼び出せる状態ではないこともあります。
 その際、仮のサーバーを自分で用意して、カスタマイズできるjsonレスポンスを返せることができれば、かなり便利です。Pythonで汎用性が高いhttpサーバを簡単に作成できますので、その方法を共有します。

Pythonでhttpサーバを作成する

from http.server import HTTPServer, BaseHTTPRequestHandler
from urllib.parse import parse_qs, urlparse
import sys, json
import os.path
import glob

class Handler(BaseHTTPRequestHandler):

    #POST処理
    def do_POST(self):

        #bodyの内容を出力する
        content_len = int(self.headers.get('Content-Length'))
        post_body = self.rfile.read(content_len).decode('utf8')
        print('\r\n【body】\r\n-----\r\n{}\r\n-----\r\n'.format(post_body))
        self.make_data()
    #GET処理
    def do_GET(self):
        self.make_data()

    def make_data(self):

        #リクエスト情報
        print('path = {}'.format(self.path))

        parsed_path = urlparse(self.path)
        print('parsed: path = {}, query = {}'.format(parsed_path.path, parse_qs(parsed_path.query)))

        #ヘッダー情報を出力する
        print('\r\n【headers】\r\n-----\r\n{}-----'.format(self.headers))
        

        if self.path == "/download":
        #zipファイル処理:Zipファイルをダウンロードする
            self.do_zip_service()
        elif self.path == "/error":
            self.do_error_service()
        else:
        #jsonファイル処理:urlに指定するjsonファイルをレスポンスとして返す
            service_names = []
            files = glob.glob('./*.json')
            for file in files:
                basename = os.path.basename(file)
                service_names.append(os.path.splitext(basename)[0])

            foundFlag = 0

            for name in service_names:
                if self.path == ('/' + name):
                    foundFlag = 1
                    self.do_json_service(name)

            if foundFlag == 0:        
                self.do_notfound()
    
    def do_zip_service(self):
        self.send_response(200)
        self.send_header('Content-type', 'application/zip')
        self.end_headers()
        with open("./test.zip", 'rb') as f:
            self.wfile.write(f.read())

    def do_json_service(self, name):
        f = open(name + ".json", encoding="utf-8")
        result_json = json.load(f)
        f.close()

        self.send_response(200)
        self.send_header('Content-type','application/json')
        self.end_headers()
        self.wfile.write(json.dumps(result_json).encode('UTF-8'))

    #指定する資源がない際の処理
    def do_notfound(self):
        f = open("notfound.json", encoding="utf-8")
        result_json = json.load(f)
        f.close()

        self.send_response(404)
        self.send_header('Content-type','application/json')
        self.end_headers()
        self.wfile.write(json.dumps(result_json).encode('UTF-8'))
        
    def do_error_service(self):
        f = open("error.json", encoding="utf-8")
        result_json = json.load(f)
        f.close()

        self.send_response(401)
        self.send_header('Content-type','application/json')
        self.end_headers()
        print(result_json)
        self.wfile.write(json.dumps(result_json).encode('UTF-8'))

PORT = 3000

httpd = HTTPServer(("", PORT), Handler)
httpd.serve_forever()

httpサーバを実行して見る

 httpサーバを起動する。
 上記のpythonを「httpserver.py」として保存する場合、以下のコマンドでサーバを起動します。

python3 httpserver.py

jsonをレスポンスに返す

 同じフォルダに以下のjsonファイル(ファイル名「test.json」)を保存するなら、
 ブラウザで「http://localhost:3000/test(←ここの部分をJsonファイル名となります)」にアクセスすると、jsonファイルの内容はレスポンスで返すことができます。

[test.json]

{ 
    "key1":"value1",
    "key2":"value2",
    "key3":"value3"
}

zipファイルをダウンロードする

 同じフォルダに以下のzipファイル(ファイル名「test.zip」)を保存するなら、
 ブラウザで「http://localhost:3000/download(←良くないですが、ここの部分をpythonファイルにハードコーディングしている)」にアクセスすると、zipファイルをダウンロードすることができます。

コメント

タイトルとURLをコピーしました