flask勉強記録① – BaseHTTPRequestHandlerについて –

Python

こんにちは!ウメハラ(plumfield56)です。

下記の本で写経をしているのですが、本だけでは理解しきれない部分で調べた内容を記載しています。

この記事では下記のライブラリについて解説しています。

from urllib.parse import urlparse
from http.server import BaseHTTPRequestHandler, HTTPServer

まずコードの紹介

html.indexファイル

<!DOCTYPE html>
<html lang="ja">
<head>
    <meta charset="UTF-8">
    <title>{title}</title>
</head>
<body>
    <h1>{title}</h1>
    <p>{message}</p>
</body>
</html>

app.pyファイル

from urllib.parse import urlparse
from http.server import BaseHTTPRequestHandler, HTTPServer

# load html file
with open('index.html', mode='r') as f:
    index = f.read()


routes = []
def route(path, method):
    routes.append((path, method))

# add routes setting.
route('/', 'index')
route('/index', 'index')


class HelloServerHandler(BaseHTTPRequestHandler):
    def do_GET(self):
        global routes
        _url = urlparse(self.path)

        for r in routes:
            if (r[0] == _url.path):
                eval('self.' + r[1] + '()')
                break
        else:
            self.error()
        return

        
    # index action
    def index(self):
        self.send_response(200)
        self.end_headers()
        html = index.format(
            title = 'This is title',
            message = 'message'
        )
        self.wfile.write(html.encode('utf-8'))
        return

    # error action
    def error(self):
        self.send_error(404, 'cannot accsess')
        return

server = HTTPServer(('', 8000), HelloServerHandler)
server.serve_forever()

この上記2つのファイルを同じフォルダに用意してください。
その後コマンドプロンプトを開きます。
「Ctrl + R」クリック後に「cmd」入力で開けます。

先ほど作成したフォルダのディレクトリを下記コマンドで開きます。

cd ディレクトリ

ディレクトリはフォルダの上部にある箇所をコピーすればOKです。

ディレクトリの移動ができたら下記コマンドを実行します。

app.py

実行後にブラウザで http://localhost:8000 にアクセスして下記画面が表示されれば実行できています。

コードを変更して再度反映させる場合はコマンドプロンプトで「Ctrl + C」で実行を止めて再度アプリを立ち上げる必要があります。

コード解説(一部)

BaseHTTPRequestHandler

こちら公式サイトからの引用です。

このクラスはサーバに到着したリクエストを処理します。 このメソッド自体では、実際のリクエストに応答することはできません。
(GET や POST のような) 各リクエストメソッドを処理するためにはサブクラス化しなければなりません。
BaseHTTPRequestHandler では、サブクラスで使うためのクラスやインスタンス変数、メソッド群を数多く提供しています。

https://docs.python.org/ja/3/library/http.server.html#http.server.BaseHTTPRequestHandler

つまり「BaseHTTPRequestHandler」というクラスを継承(サブクラス化)して使用してくださいということと、GETした後であればメソッドやインスタンス(プロパティ)を使って処理ができますよということみたいです。
そのために下記のようにクラスを継承してGETで使用するコードが記載されています。

class HelloServerHandler(BaseHTTPRequestHandler):
    def do_GET(self):
        # 処理

使用できるメソッドやインスタンス一覧はこちらに乗っています。

http.server --- HTTP サーバ — Python 3.10.0b2 ドキュメント

上記処理の中ではpathでURLを取得してURL事に呼び出す関数を分けて処理を行っています。

urlparse

urlparseはURLを解析してくれるメソッドです。

urllib.parse --- URL を解析して構成要素にする — Python 3.10.0b2 ドキュメント

例えば、「http://localhost:8000/next?id=123&pass=hoge&params=xyz」を解析すると下記のようになります。

from urllib.parse import urlparse
_url = urlparse('http://localhost:8000/next?id=123&pass=hoge&params=xyz')
print(_url)
# ParseResult(scheme='http', netloc='localhost:8000', path='/next', params='', query='id=123&pass=hoge&params=xyz', fragment='')

これを使用することによって、下記のように分けてくれます。

urlpathquery
http://localhost:8000
http://localhost:8000/next/next
http://localhost:8000/next?id=123&pass=hoge&params=xyz/nextid=123&pass=hoge&params=xyz

辞書型になっているので、上記で_url[‘path’]とすることでpathを取得することが可能です。
queryに関してはurlにパラメータがついているときに使用することが可能です。

コメント

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