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 にも追加するのを忘れないように。

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です