140

By default, when running Flask application using the built-in server (Flask.run), it monitors its Python files and automatically reloads the app if its code changes:

* Detected change in '/home/xion/hello-world/app.py', reloading
* Restarting with reloader

Unfortunately, this seems to work for *.py files only, and I don't seem to find any way to extend this functionality to other files. Most notably, it would be extremely useful to have Flask restart the app when a template changes. I've lost count on how many times I was fiddling with markup in templates and getting confused by not seeing any changes, only to find out that the app was still using the old version of Jinja template.

So, is there a way to have Flask monitor files in templates directory, or does it require diving into the framework's source?

Edit: I'm using Ubuntu 10.10. Haven't tried that on any other platforms really.


After further inquiry, I have discovered that changes in templates indeed are updated in real time, without reloading the app itself. However, this seems to apply only to those templates that are passed to flask.render_template.

But it so happens that in my app, I have quite a lot of reusable, parametrized components which I use in Jinja templates. They are implemented as {% macro %}s, reside in dedicated "modules" and are {% import %}ed into actual pages. All nice and DRY... except that those imported templates are apparently never checked for modifications, as they don't pass through render_template at all.

(Curiously, this doesn't happen for templates invoked through {% extends %}. As for {% include %}, I have no idea as I don't really use them.)

So to wrap up, the roots of this phenomenon seems to lie somewhere between Jinja and Flask or Werkzeug. I guess it may warrant a trip to bug tracker for either of those projects :) Meanwhile, I've accepted the jd.'s answer because that's the solution I actually used - and it works like a charm.

Adam Lear
  • 38,111
  • 12
  • 81
  • 101
Xion
  • 22,400
  • 10
  • 55
  • 79
  • 4
    Make sure the app configured with DEBUG=True, see [the docs](http://flask.pocoo.org/docs/quickstart/#debug-mode). – Alex Morega Mar 01 '12 at 09:02

13 Answers13

210

you can use

TEMPLATES_AUTO_RELOAD = True

From http://flask.pocoo.org/docs/1.0/config/

Whether to check for modifications of the template source and reload it automatically. By default the value is None which means that Flask checks original file only in debug mode.

zedong
  • 393
  • 2
  • 5
  • 15
Loris
  • 2,128
  • 2
  • 9
  • 8
  • 22
    This solution is conventional, supported by documentation, simple to understand, and easy to implement. It should be accepted! – Carolyn Conway Sep 13 '16 at 21:38
  • I tried this answer but only works once, after another refresh it would not work – medev21 Sep 22 '16 at 21:19
  • 9
    Just a note for others: I did `app.config['TEMPLATES_AUTO_RELOAD'] = True`, and for some reason expected to see the server auto-restart when a template changed, like it does in debug mode. It doesn't restart, but it DOES update the template that it renders. – cs01 Dec 01 '16 at 03:49
  • 3
    Any reason why this wouldn't be working for 0.12? or some other setting that would prevent this from properly setting? – user805981 Jan 25 '17 at 02:00
  • @user805981 note that the console running the Flask web server doesn't do the full reboot that you see if a module file is edited and saved. If you just go ahead and refresh the browser you'll see the change take effect. – Federer Mar 01 '17 at 14:12
  • 3
    @Federer It doesn't seem to be working as it used to... Before, it would have detected the changes in the templates directory and the sub directories and it would reload the server.... Is this something new in 0.12 that changed? – user805981 Mar 02 '17 at 18:33
  • Where do I add this line? All I have in my application.py file is app = Flask(__name__) – JackOfAll Mar 14 '19 at 21:26
  • Loris' solution works perfectly with a basic Flask app. After `app = Flask(__name__)` simply add `app.config['TEMPLATES_AUTO_RELOAD'] = True` Next time you run the app, make a change to one of the template htmls, then refresh your browser to see the change! All without needing to restart the Flask app. – Theo F Apr 28 '20 at 11:29
  • It works for me reloading my css files, but be aware of browser caching. I use incognito mode all the time to prevent problems like that. – Michael Dec 27 '20 at 11:17
  • app.templates_auto_reload = True – Kiran Sep 16 '22 at 12:02
84

In my experience, templates don't even need the application to restart to be refreshed, as they should be loaded from disk everytime render_template() is called. Maybe your templates are used differently though.

To reload your application when the templates change (or any other file), you can pass the extra_files argument to Flask().run(), a collection of filenames to watch: any change on those files will trigger the reloader.

Example:

from os import path, walk

extra_dirs = ['directory/to/watch',]
extra_files = extra_dirs[:]
for extra_dir in extra_dirs:
    for dirname, dirs, files in walk(extra_dir):
        for filename in files:
            filename = path.join(dirname, filename)
            if path.isfile(filename):
                extra_files.append(filename)
app.run(extra_files=extra_files)

See here: http://werkzeug.pocoo.org/docs/0.10/serving/?highlight=run_simple#werkzeug.serving.run_simple

Eric Reed
  • 377
  • 1
  • 6
  • 21
jd.
  • 10,678
  • 3
  • 46
  • 55
  • Good stuff! I admit I missed the link in the documentation of `Flask.run` which lead to Werkzeug docs. But this particular option seems useful enough to at least have it mentioned in Flask docs. – Xion Mar 01 '12 at 18:33
  • If anyone encounters an error that says `No such file or directory`, try using the relative path as in : `extra_dirs = ['./directory/to/watch',]` – Kevin Jul 15 '15 at 05:44
  • 4
    If you too are confused about what `path` is, it's `os.path`. thought it was worth mentioning – bjesus Jun 03 '16 at 15:38
  • For auto-reloading after changing static files see [this](http://stackoverflow.com/a/38524695/4675937). – simanacci Jul 22 '16 at 11:10
  • 2
    Any idea how to specify extra files when running `flask run` from the command line? – Michael Scheper Apr 25 '17 at 19:29
  • Please see the other answers below about the Flask `TEMPLATES_AUTO_RELOAD` and `DEBUG` option. Jinja2 already has a template auto reload mechanism, which is activated by Flask There is no need to manually add this to the Flask reload mechanism through `extra_files`. – Sebastian Schrader Sep 20 '17 at 13:41
68

When you are working with jinja templates, you need to set some parameters. In my case with python3, I solved it with the following code:

if __name__ == '__main__':
    app.jinja_env.auto_reload = True
    app.config['TEMPLATES_AUTO_RELOAD'] = True
    app.run(debug=True, host='0.0.0.0')
silgon
  • 6,890
  • 7
  • 46
  • 67
  • This is working for me on flask 1.0.2, but I don't have the host argument. – Enrico Borba Aug 13 '18 at 03:34
  • Yeah @EnricoBorba , you probably wont need it. I usually use it because I debug in local with docker, and sometimes the application needs to be accessed from another container. [Some Reference](https://stackoverflow.com/a/7027113/2237916) – silgon Aug 13 '18 at 08:16
  • @silgon Yea I understand. I was mainly just adding to comment to be clear about what worked on a fresh install of Flask version 1.0.2 – Enrico Borba Aug 13 '18 at 08:18
40

You need to set a TEMPLATES_AUTO_RELOAD property as True in your app config:

from flask import Flask

app = Flask(__name__)
app.config["TEMPLATES_AUTO_RELOAD"] = True

See more on http://flask.pocoo.org/docs/1.0/config/

Nikandr Marhal
  • 1,230
  • 1
  • 12
  • 12
12

Actually for me TEMPLATES_AUTO_RELOAD = True does not work (0.12 version). I use jinja2 and what i have done:

  1. Create function before_request

    def before_request():
        app.jinja_env.cache = {}
    
  2. Register it in application

    app.before_request(before_request)
    
  3. That's it.

dikkini
  • 1,184
  • 1
  • 23
  • 52
7

Updated as of March 2021:

The flask CLI is recommended over app.run() for running a dev server, so if we want to use the CLI then the accepted solution can't be used.

In Flask 1.1 or later, the environment variable FLASK_RUN_EXTRA_FILES or the option --extra-files effectively do the same thing as the accepted answer. See also this github issue.

Example usage:

flask run --extra-files "app/templates/index.html"
# or
export FLASK_RUN_EXTRA_FILES="app/templates/index.html"
flask run

in Linux. To specify multiple extra files, separate file paths with colons., e.g.

export FLASK_RUN_EXTRA_FILES="app/templates/index.html:app/templates/other.html"

Whole directories are also supported:

flask run --extra-files app/templates/
Lucas Werkmeister
  • 2,584
  • 1
  • 17
  • 31
overseas
  • 107
  • 1
  • 8
  • 1
    minor update. link to ' flask CLI' needs update to current version. https://flask.palletsprojects.com/en/1.1.x/cli/ otherwise thanks :) – CodingMatters Jul 04 '20 at 00:16
  • 1
    I updated the link and also added that whole directories can be “watched” as well, I hope that’s an acceptable edit. – Lucas Werkmeister Mar 26 '21 at 21:24
5

What worked for me is just adding this:

@app.before_request
def before_request():
    # When you import jinja2 macros, they get cached which is annoying for local
    # development, so wipe the cache every request.
    if 'localhost' in request.host_url or '0.0.0.0' in request.host_url:
        app.jinja_env.cache = {}

(taken from @dikkini's answer)

Garrett
  • 4,007
  • 2
  • 41
  • 59
5

To reload the application on the server AND in the browser I used the livereload package. Installed through the CLI with

$ pip install livereload

and running the code

from flask import Flask, render_template

app = Flask(__name__)

@app.route("/")
def hello():
    return render_template("index.html")

if __name__ == '__main__':
    from livereload import Server
    server = Server(app.wsgi_app)
    server.serve(host = '0.0.0.0',port=5000)

all answers here using the extra_files argument or TEMPLATES_AUTO_RELOAD config work to reload it on the server but for a smooth development experience without damaging your keyboard's F5 key I'd go with livereload

HyperActive
  • 1,129
  • 12
  • 12
2

See http://flask.pocoo.org/docs/1.0/quickstart/ and use FLASK_ENV=development

Naxos84
  • 1,890
  • 1
  • 22
  • 34
2

I had the same trouble. The solution is really simple though. Instead of this:

if __name__ == '__main__':
    app.jinja_env.auto_reload = True
    app.config["TEMPLATES_AUTO_RELOAD"] = True
    app.run(debug=True)

Put

app.jinja_env.auto_reload = True
app.config["TEMPLATES_AUTO_RELOAD"] = True

above the main function. So final output for example:

from flask import Flask, app,render_template

app= Flask(__name__)
app.jinja_env.auto_reload = True
app.config["TEMPLATES_AUTO_RELOAD"] = True

@app.route('/')
def index():
    return render_template('index.html')

if __name__ == '__main__':    
    app.run(debug=True)
    
Dharman
  • 30,962
  • 25
  • 85
  • 135
2

Using the latest version of Flask on Windows, using the run command and debug set to true; Flask doesn't need to be reset for changes to templates to be brought in to effect. Try Shift+F5 (or Shift plus the reload button) to make sure nothing it being cached.

Drakekin
  • 1,341
  • 1
  • 11
  • 23
0

Templates are reloaded automatically, why not doing ctrl+f5 to refresh the webpage, cause web-browsers usually save cache.

WiperR
  • 198
  • 2
  • 9
  • This does not work for me. It justs loads the old template without the new changes – Carol Jan 20 '21 at 13:48
  • Use ``` app.config['TEMPLATE_AUTO_RELOAD'] = 'true' ``` Then when you press crtl + f5 it should work. – WiperR Jan 21 '21 at 04:50
0

Adding app.config['TEMPLATES_AUTO_RELOAD'] = True after if __name__ == '__main__': doesn't work for me!

What works is adding app.config['TEMPLATES_AUTO_RELOAD'] = True after app = Flask(__name__)

Notice that I am using app.run(debug=True)

J.K
  • 1,178
  • 10
  • 13