Waitress とは?
Flask には簡易的なウェブサーバー機能が組み込まれています。app.run() を呼び出すことで起動することができます。デフォルトで Werkzeug によるシンプルなサーバーを使用することができます。
本格的な運用では、Nginx や Apache をリバースプロキシとして利用しながら、Gunicorn などの WSGI サーバーを使う構成が一般的です。
また、Windows では、gunicorn は利用できない為、Windows で開発環境を構築する場合は、ウェブサーバーの候補としては、Waitress が候補に挙がります。Waitress は Python 製の WSGI サーバーです。
Waitress をインストールするには、以下を実行します。
pip install waitress
Waitress で Flask アプリを起動
hello ディレクトリを作成し、その中にvenvで仮想環境を作成します。
venvについては、以下のリンクを参考にしてください。
仮想環境のなかに、Flask と Waitress をインストールします。
hello ディレクトリの中に、hello.pyというファイルを作成します。
ファイルの中を以下のようにします
hello.py
from flask import Flask
app = Flask(__name__)
@app.route('/')
def hello():
name = "Hello World"
return name
@app.route('/good')
def good():
name = "Good"
return name
if __name__ == "__main__":
app.run(debug=True)
Waitress で Flask アプリを起動するには、以下のコマンドを実行します。
waitress-serve --listen=127.0.0.1:8000 hello:app
http://localhost:8000でブラウザから開き、Hello Worldが表示されればgunicornでアプリが起動しています。
waitress-serve --listen=127.0.0.1:8000 hello:appについては、以下の解説を参考にしてください。
waitress-serveは、Waitress の CLI コマンドで、WSGIサーバーを起動。
--listen=127.0.0.1:8000は、ローカルホスト (127.0.0.1) のポート8000 でリクエストを受け付けるように設定
hello:appは、hello.py のファイル内にあるappという Flask アプリを起動する指定です。
helloは、ファイル名でappは、Flask オブジェクト(app = Flask(__name__))を指します。
ログの表示
初期の状態では、Waitress はログの表示がされません。ログを出力するには、いくつかの方法があります。
まず、paste.translogger.TransLoggerを使う方法の場合、リクエストごとのログを Apache のログ形式 で出力できます。
pasteをインストールするには、以下のコマンドを実行します。
hello.py
import logging
from flask import Flask, request
from waitress import serve
from paste.translogger import TransLogger
app = Flask(__name__)
@app.route('/')
def hello():
name = "Hello World"
return name
@app.route('/good')
def good():
name = "Good"
return name
if __name__ == "__main__":
logging.basicConfig(level=logging.INFO)
serve(TransLogger(app), host='127.0.0.1', port=8000)
以下のコマンドを実行し、アプリを起動します。
python hello.py
werkzeug ロガーのログを使って表示するには、以下のようにします。
hello.py
import logging
from flask import Flask, request
from waitress import serve
app = Flask(__name__)
# `werkzeug` のロガーを設定
log = logging.getLogger('werkzeug')
log.setLevel(logging.DEBUG)
log.addHandler(logging.StreamHandler()) # コンソール出力を有効化
# 各リクエストのログを記録
@app.before_request
def log_request():
log.info(f"Request: {request.method} {request.path}")
@app.route('/')
def hello():
name = "Hello World"
return name
@app.route('/good')
def good():
name = "Good"
return name
if __name__ == "__main__":
serve(app, host='127.0.0.1', port=8000, _quiet=False)