PythonでさくっとWebサーバー!HTTPServerの便利な使い方

Pythonで簡易的なWebサーバーをたてられる HTTPServer の使い方・プログラミングを解説していきます(Python 3.9.4で動かします)。

【Python】簡易サーバーをたてるHTTPServerの使い方

Webサーバーを作る最小限のプログラム

from http.server import HTTPServer, SimpleHTTPRequestHandler

ip = "0.0.0.0"
port = 8887

httpd = HTTPServer(('', port), SimpleHTTPRequestHandler)
httpd.serve_forever()

はい、とてもカンタンですね。

http://0.0.0.0:8887 へブラウザからアクセスできます。

ですが、このままだと httpd.serve_forever() で止まってしまい、それ移行のプログラムは実行されません。そこでPythonのスレッドをつかってサーバーを実行してみます。

PythonでHTTPサーバーをスレッドで動かす

こんな感じです。

import threading
from http.server import HTTPServer, SimpleHTTPRequestHandler


html_root = "../html" # HTMLが格納されているディレクトリ

class Handler(SimpleHTTPRequestHandler):
    def __init__(self, *args, **kwargs):
        super().__init__(*args, directory=html_root, **kwargs)

    def log_message(self, format, *args):
        pass # ログ出力を無視

def begin_dummy_server():
    ip = "0.0.0.0"
    port = 8887

    httpd = HTTPServer(('', port), Handler)
    print('HTTPServer began -> http://{}:{}'.format(ip, port))
#    httpd.serve_forever()
    server_thread = threading.Thread(target=httpd.serve_forever) # スレッドで動かす
#    server_thread.daemon = True
    server_thread.start()

if __name__ == "__main__":

    begin_dummy_server()
    print("hoge")

次の部分でスレッド登録させています。

server_thread = threading.Thread(target=httpd.serve_forever)
server_thread.start()

threadingをインポートして、対象となる関数を target に登録&スタートさせればOKです。

HTMLディレクトリを指定したい

SimpleHTTPRequestHandlerを継承したハンドラーを使うことでHTMLファイルが格納されているディレクトリを指定できます。SimpleHTTPRequestHandlerのコンストラクターで、directory=引数にディレクトリを指定します。

ログを非表示にしたい

サーバーへアクセスするとターミナルにいちいちログが出力されますが、ログを出力したくない場合は上のプログラムのとおり、 log_message をオーバーライドして pass させます。

自分のLAN IPアドレスを取得する

HTTPServer とは直接関係ありませんが、LAN内の端末からWebサーバーへアクセスしたい場合にIPアドレスを表示できると便利です。macOS上で実行するPythonでは、次のようにするとLAN内の自分のIPアドレスを取得できます。

import socket

host_list = socket.gethostbyname_ex(socket.gethostname())
lan_address = host_list[2][1]

ただし、PCにファイアーウォールがかかってるとアクセスできませんのでご注意ください。

リクエストされたヘッダーを表示したい

リクエストヘッダーを詳細に見たい場合があると思います。do_GET をオーバライドして、 logging で標準出力させています。POSTデータの場合は do_POST も同様に追加してください。

from http.server import HTTPServer, SimpleHTTPRequestHandler
import socket
import logging

logging.basicConfig(level=logging.INFO)
logger = logging.getLogger(__name__)


host_list = socket.gethostbyname_ex(socket.gethostname())
lan_address = host_list[2][1]

ip = "0.0.0.0"
port = 8887

class Handler(SimpleHTTPRequestHandler):

    def do_GET(self):
        logger.info(self.headers)
        SimpleHTTPRequestHandler.do_GET(self)

httpd = HTTPServer(('', port), Handler)
print('HTTPServer began -> http://{}:{}'.format(lan_address, port))
httpd.serve_forever()
記事に関するご質問などがあれば、
Twitter または お問い合わせ までご連絡ください。
Python学習にオススメの本をご紹介!
Pandasでデータサイエンスはじめよう!
関連記事