runserver_plus で「KeyError: ‘werkzeug.server.shutdown’」
Djangoの開発用サーバをHTTPS化する runserver_plus でエラーが発生し、正常に起動しなくなりました。
ことの発端は、パッケージの更新でした。しばらくPythonのパッケージをアップデートしていなかったので、pip list –outdate
で出てきたものをすべて pip install -U <パッケージ>
したのですが、そこに、runserver_plus の django-extensions も含まれていました。
VSCode でデバッグを開始し、ブラウザからアクセスすると、コンソールに、スタックトレースが表示されました。
----------------------------------------
Exception occurred during processing of request from ('127.0.0.1', 51604)
Traceback (most recent call last):
File "/usr/lib/python3.10/socketserver.py", line 683, in process_request_thread
self.finish_request(request, client_address)
File "/usr/lib/python3.10/socketserver.py", line 360, in finish_request
self.RequestHandlerClass(request, client_address, self)
File "/usr/lib/python3.10/socketserver.py", line 747, in __init__
self.handle()
File "/home/test_prj/.venv/lib/python3.10/site-packages/werkzeug/serving.py", line 363, in handle
super().handle()
File "/usr/lib/python3.10/http/server.py", line 425, in handle
self.handle_one_request()
File "/usr/lib/python3.10/http/server.py", line 413, in handle_one_request
method()
File "/home/test_prj/.venv/lib/python3.10/site-packages/werkzeug/serving.py", line 243, in run_wsgi
self.environ = environ = self.make_environ()
File "/home/test_prj/.venv/lib/python3.10/site-packages/django_extensions/management/commands/runserver_plus.py", line 326, in make_environ
del environ['werkzeug.server.shutdown']
KeyError: 'werkzeug.server.shutdown'
----------------------------------------
環境変数 werkzeug.server.shutdown
の削除に失敗しているようです。処理内容を確認するため、runserver_plus.py の行を Ctrl+クリックし、該当箇所をエディタで開きます。
class WSGIRequestHandler(_WSGIRequestHandler):
def make_environ(self):
environ = super().make_environ()
if not options['keep_meta_shutdown_func']:
del environ['werkzeug.server.shutdown']
return environ
環境変数 werkzeug.server.shutdown
は、Werkzeug が WSGI の環境変数として用意していたものですが、Ver. 2.0 で廃止になったようです。
ということで、del environ['werkzeug.server.shutdown']
しないようにすればいいわけですね。
その上の4行目にあるとおり、'keep_meta_shutdown_func'
オプションを設定すれば、del しなくなりそうです。
'keep_meta_shutdown_func'
を探すと、以下のような定義があります。
parser.add_argument('--keep-meta-shutdown', dest='keep_meta_shutdown_func', action='store_true', default=False,
help="Keep request.META['werkzeug.server.shutdown'] function which is automatically removed "
"because Django debug pages tries to call the function and unintentionally shuts down "
"the Werkzeug server.")
ということで、runserver_plus の起動オプションに ‘–keep-meta-shutdown’ を加えると、無事正常起動するようになりました。
そのうち django-extensions が新しい Werkzeug に対応すれば不要になると思いますが、それまでのつなぎとしてつけておくことにします。
VSCode の launch.json にも追加するのを忘れないように。