Django restarted (trigger file change) on every request when using runserver_plus

Django always detect file changes on every request on development mode. it was restarting even though i didn’t make any change at all on the code.

for a simple view this is not causing a problem. the process of rendering one page done before restart triggered. but if i have more complex logic in view, django restarted before the process of rendering a page completed.

is any body know is this an expected behaviour? and why this is happened? how can i solve my problem? render a complex logic before django restarted.

Is there are a way to disable that false positive trigger of file change?

This definitely is not expected behavior. In fact, I’ve never seen anything like this before.
What’s really strange to me is that this is being triggered based on changes in your Python environment and not just your code.

What operating system and environment are you running this in? (Is there anything out-of-the-ordinary about your filesystem?)

What parameters are you using on your runserver_plus command line?

Also see the configuration options for Werkzeug in the runserver_plus docs. RunServerPlus — django-extensions 3.2.1 documentation
You may want to install the Watchdog package as suggested, or try increasing the poller interval.

What operating system and environment are you running this in? (Is there anything out-of-the-ordinary about your filesystem?)

we are using cookiecutter-django to generate our project. we setup our project with docker environment. So our host mechine is using mac. and our container using linux (Debian).

What parameters are you using on your runserver_plus command line?

we are using host:port parameter, cookiecutter-django run development code with no async support

i will test the code on my fresh generated project first. if it still happened maybe it because bugs on that cookie cutter template. i will raise an issue to their repo.
if the issue not appearing anymore maybe it was because webpack and nodejs things that we use in our project to support tailwindcss.

if you find any other possibilities kindly tell me. i am so curious why this thing happened in my project.

I would think the first thing to check would be to see if the timestamps on the files are being updated. Then it would be an issue to see what is updating those timestamps.

Look through the docs of whatever tooling you are using to see if anything is using touch (or any utility that works the same way) to update those timestamps.

It defintely would not be caused by anything created by cookiecutter. That doesn’t create anything that runs continuously. It would be some process being run that would be doing this.

i just check the timestamp of a file that trigger django restart. unfortunately the timestamp not change when change detected from console.

stat /app/student_portal/schedule/backends.py

FYI, this issue not happening when i change runserver_plus with regular runserver

Do you have any processes running in that container other than Werkzeug?

yes i have.

node → handle postcss when class change in template
celeryworker, flower and celerybeat → handle our scheduling task (basicly hit ekternal api)
postgres and redis → database
docs → i have a little bit knowledge what is this doing. but i guess it used to generate documentation

Seeing the same thing here! I am also running Django inside of Docker, and had done a recent Docker upgrade. Docker on Mac is a strange, buggy piece of software so I am suspicious there. I’m also doing this in the VSCode remote environment (where it runs VSCode inside of the container), and I’m running it under the VSCode debugger. I’ve also done a recent VSCode upgrade. There’s a lot of moving parts here.

Taking a look at the changelog for watchdog, I see that the recent 2.3.0 added a FileOpenedEvent. That sounded promising - maybe the runserver_plus wasn’t aware of the new event type and thought all these opened files were edited? Well, downgrading to watchdog 2.2.1 did not help.

One thing I’ve done is run it as runserver_plus 0.0.0.0:8001 --noreload --nothreading in hopes of shortcutting the whole reload thing as I don’t necessarily need it anyway. However, I then get a stack trace like so, when the app starts:

Traceback (most recent call last):
  File "/usr/local/lib/python3.10/runpy.py", line 196, in _run_module_as_main
    return _run_code(code, main_globals, None,
  File "/usr/local/lib/python3.10/runpy.py", line 86, in _run_code
    exec(code, run_globals)
  File "/home/vscode/.vscode-server/extensions/ms-python.python-2023.4.1/pythonFiles/lib/python/debugpy/adapter/../../debugpy/launcher/../../debugpy/__main__.py", line 39, in <module>
    cli.main()
  File "/home/vscode/.vscode-server/extensions/ms-python.python-2023.4.1/pythonFiles/lib/python/debugpy/adapter/../../debugpy/launcher/../../debugpy/../debugpy/server/cli.py", line 430, in main
    run()
  File "/home/vscode/.vscode-server/extensions/ms-python.python-2023.4.1/pythonFiles/lib/python/debugpy/adapter/../../debugpy/launcher/../../debugpy/../debugpy/server/cli.py", line 284, in run_file
    runpy.run_path(target, run_name="__main__")
  File "/home/vscode/.vscode-server/extensions/ms-python.python-2023.4.1/pythonFiles/lib/python/debugpy/_vendored/pydevd/_pydevd_bundle/pydevd_runpy.py", line 321, in run_path
    return _run_module_code(code, init_globals, run_name,
  File "/home/vscode/.vscode-server/extensions/ms-python.python-2023.4.1/pythonFiles/lib/python/debugpy/_vendored/pydevd/_pydevd_bundle/pydevd_runpy.py", line 135, in _run_module_code
    _run_code(code, mod_globals, init_globals,
  File "/home/vscode/.vscode-server/extensions/ms-python.python-2023.4.1/pythonFiles/lib/python/debugpy/_vendored/pydevd/_pydevd_bundle/pydevd_runpy.py", line 124, in _run_code
    exec(code, run_globals)
  File "/workspace/manage.py", line 23, in <module>
    execute_from_command_line(sys.argv)
  File "/usr/local/lib/python3.10/site-packages/django/core/management/__init__.py", line 446, in execute_from_command_line
    utility.execute()
  File "/usr/local/lib/python3.10/site-packages/django/core/management/__init__.py", line 440, in execute
    self.fetch_command(subcommand).run_from_argv(self.argv)
  File "/usr/local/lib/python3.10/site-packages/django/core/management/base.py", line 402, in run_from_argv
    self.execute(*args, **cmd_options)
  File "/usr/local/lib/python3.10/site-packages/django/core/management/base.py", line 448, in execute
    output = self.handle(*args, **options)
  File "/usr/local/lib/python3.10/site-packages/django_extensions/management/utils.py", line 62, in inner
    ret = func(self, *args, **kwargs)
  File "/usr/local/lib/python3.10/site-packages/django_extensions/management/commands/runserver_plus.py", line 296, in handle
    self.inner_run(options)
  File "/usr/local/lib/python3.10/site-packages/django_extensions/management/commands/runserver_plus.py", line 414, in inner_run
    run_simple(
  File "/home/vscode/.local/lib/python3.10/site-packages/werkzeug/serving.py", line 1035, in run_simple
    fd = int(os.environ["WERKZEUG_SERVER_FD"])
  File "/usr/local/lib/python3.10/os.py", line 680, in __getitem__
    raise KeyError(key) from None
KeyError: 'WERKZEUG_SERVER_FD'

So maybe this is the interaction of runserver_plus and the VSCode debugger extension?

The issue is also being tracked in django-extensions: runserver_plus: watchdog >=2.3.* causes unwanted behavior · Issue #1805 · django-extensions/django-extensions · GitHub

They say it’s an upstream issue with Werkzeug: WatchdogReloaderLoop reloading on every http request due to change in watchdog · Issue #2603 · pallets/werkzeug · GitHub

Installing the latest werkzeug from their master branch has fixed the issue for me.

1 Like

Thanks @dgilmanAID. worked for me too!

I installed using:

pip install --upgrade git+https://github.com/pallets/werkzeug