简体   繁体   中英

Is there any way of detecting an automatic reload in flask's debug mode?

I have a flask app where I'd like to execute some code on the first time the app is run, not on the automatic reloads triggered by the debug mode. Is there any way of detecting when a reload is triggered so that I can do this?

To give an example, I might want to open a web browser every time I run the app from sublime text, but not when I subsequently edit the files, like so:

import webbrowser
if __name__ == '__main__':
    webbrowser.open('http://localhost:5000')
    app.run(host='localhost', port=5000, debug=True)

You can set an environment variable.

import os
if 'WERKZEUG_LOADED' in os.environ:
    print 'Reloading...'
else:
    print 'Starting...'
    os.environ['WERKZEUG_LOADED']='TRUE'

I still don't know how to persist a reference that survives the reloading, though.

What about using Flask-Script to kick off a process before you start your server? Something like this (cribbed from their documentation and edited slightly):

# run_devserver.py

import webbrowser
from flask.ext.script import Manager

from myapp import app

manager = Manager(app)

if __name__ == "__main__":
    webbrowser.open('http://localhost:5000')
    manager.run(host='localhost', port=5000, debug=True)

I have a Flask app where it's not really practical to change the DEBUG flag or disable reloading, and the app is spun up in a more complex way than just flask run .

@osa's solution didn't work for me with flask debug on, because it doesn't have enough finesse to pick out the werkzeug watcher process from the worker process that gets reloaded.

I have this code in my main package's __init__.py (the package that defines the flask app). This code is run by another small module which has from <the_package_name> import app followed by app.run(debug=True, host='0.0.0.0', port=5000) . Therefore this code is executed before the app starts.

import ptvsd
import os
my_pid = os.getpid()
if os.environ.get('PPID') == str(os.getppid()):
    logger.debug('Reloading...')
    logger.debug(f"Current process ID: {my_pid}")
    try:
        port = 5678
        ptvsd.enable_attach(address=('0.0.0.0', port))
        logger.debug(f'========================== PTVSD waiting on port {port} ==========================')
        # ptvsd.wait_for_attach()   # Not necessary for my app; YMMV
    except Exception as ex:
        logger.debug(f'PTVSD raised {ex}')
else:
    logger.debug('Starting...')
    os.environ['PPID'] = str(my_pid)
    logger.debug(f"First process ID: {my_pid}")

NB: note the difference between os.getpid() and os.getppid() (the latter gets the parent process's ID).

I can attach at any point and it works great, even if the app has reloaded already before I attach. I can detach and re-attach. The debugger survives a reload.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM