Recharger l'application Flask lorsque le fichier de modèle change

95

Par défaut, lors de l'exécution de l'application Flask à l'aide du serveur intégré ( Flask.run), il surveille ses fichiers Python et recharge automatiquement l'application si son code change:

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

Malheureusement, cela semble fonctionner uniquement pour les fichiers * .py , et je ne semble pas trouver de moyen d'étendre cette fonctionnalité à d'autres fichiers. Plus particulièrement, il serait extrêmement utile que Flask redémarre l'application lorsqu'un modèle change. J'ai perdu le compte du nombre de fois où j'ai joué avec le balisage dans les modèles et que je me suis trompé de ne voir aucun changement, pour découvrir que l'application utilisait toujours l'ancienne version du modèle Jinja.

Alors, y a-t-il un moyen d'avoir les fichiers de surveillance Flask dans le répertoire des modèles , ou faut-il plonger dans la source du framework?

Edit : J'utilise Ubuntu 10.10. Je n'ai vraiment essayé cela sur aucune autre plate-forme.


Après une enquête plus approfondie, j'ai découvert que les modifications apportées aux modèles sont effectivement mises à jour en temps réel, sans recharger l'application elle-même. Cependant, cela semble s'appliquer uniquement aux modèles passés à flask.render_template.

Mais il se trouve que dans mon application, j'ai pas mal de composants réutilisables et paramétrés que j'utilise dans les modèles Jinja. Ils sont implémentés en tant que {% macro %}s, résident dans des "modules" dédiés et sont {% import %}édités dans des pages réelles. Tout est agréable et SEC ... sauf que ces modèles importés ne sont apparemment jamais vérifiés pour les modifications, car ils ne passent pas render_templatedu tout.

(Curieusement, cela ne se produit pas pour les modèles appelés via {% extends %}. Quant à {% include %}moi, je n'en ai aucune idée car je ne les utilise pas vraiment.)

Donc, pour conclure, les racines de ce phénomène semblent se situer quelque part entre Jinja et Flask ou Werkzeug. Je suppose que cela peut justifier un voyage au bug tracker pour l'un ou l'autre de ces projets :) En attendant, j'ai accepté le jd. La réponse parce que c'est la solution que j'ai réellement utilisée - et cela fonctionne comme un charme.

Xion
la source
3
Assurez-vous que l'application configurée avec DEBUG = True, consultez la documentation .
Alex Morega

Réponses:

65

D'après mon expérience, les modèles n'ont même pas besoin de redémarrer l'application pour être actualisés, car ils doivent être chargés à partir du disque à chaque render_template()appel. Peut-être que vos modèles sont utilisés différemment.

Pour recharger votre application lorsque les modèles changent (ou tout autre fichier), vous pouvez passer l' extra_filesargument à Flask().run(), une collection de noms de fichiers à surveiller: toute modification sur ces fichiers déclenchera le rechargement.

Exemple:

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)

Voir ici: http://werkzeug.pocoo.org/docs/0.10/serving/?highlight=run_simple#werkzeug.serving.run_simple

jd.
la source
Bon produit! J'avoue que j'ai manqué le lien dans la documentation Flask.runqui mène à la documentation Werkzeug. Mais cette option particulière semble suffisamment utile pour au moins l'avoir mentionnée dans la documentation Flask.
Xion
Si quelqu'un rencontre une erreur qui dit No such file or directory, essayez d'utiliser le chemin relatif comme dans:extra_dirs = ['./directory/to/watch',]
Kevin
3
Si vous aussi vous ne savez pas ce que pathc'est, c'est os.path. pensait que cela valait la peine d'être mentionné
bjesus
Pour le rechargement automatique après la modification des fichiers statiques, voyez ceci .
simanacci
1
Une idée comment spécifier des fichiers supplémentaires lors de l'exécution à flask runpartir de la ligne de commande?
Michael Scheper
143

vous pouvez utiliser

TEMPLATES_AUTO_RELOAD = True

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

S'il faut vérifier les modifications de la source du modèle et le recharger automatiquement. Par défaut, la valeur est None, ce qui signifie que Flask vérifie le fichier d'origine uniquement en mode débogage.

Loris
la source
11
Cette solution est classique, soutenue par de la documentation, simple à comprendre et facile à mettre en œuvre. Cela devrait être accepté!
Carolyn Conway
J'ai essayé cette réponse mais ne fonctionne qu'une fois, après un autre rafraîchissement, cela ne fonctionnerait pas
medev21
3
Juste une note pour les autres: je l'ai fait app.config['TEMPLATES_AUTO_RELOAD'] = True , et pour une raison quelconque, m'attendais à voir le serveur redémarrer automatiquement lorsqu'un modèle changeait, comme il le fait en mode débogage. Il ne redémarre pas, mais il met à jour le modèle qu'il rend.
cs01
3
Une raison pour laquelle cela ne fonctionnerait pas pour 0,12? ou un autre paramètre qui empêcherait cela de définir correctement?
user805981
3
@Federer Cela ne semble plus fonctionner comme avant ... Avant, il aurait détecté les changements dans le répertoire des modèles et les sous-répertoires et il rechargerait le serveur ... Est-ce quelque chose de nouveau dans la version 0.12 qui modifié?
user805981
54

Lorsque vous travaillez avec des jinjamodèles, vous devez définir certains paramètres. Dans mon cas avec python3, je l'ai résolu avec le code suivant:

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
la source
1
Vous avez sauvé ma raison. Je vous remercie.
Nostalg.io
J'avais également du mal avec ce problème. Je suis content de pouvoir aider;)
silgon
Cela fonctionne pour moi sur le flask 1.0.2, mais je n'ai pas l'argument hôte.
Enrico Borba
Ouais @EnricoBorba, vous n'en aurez probablement pas besoin. Je l'utilise généralement car je débogue en local avec docker, et parfois l'application doit être accessible à partir d'un autre conteneur. Some Reference
silgon
@silgon Oui, je comprends. J'étais principalement en train d'ajouter un commentaire pour être clair sur ce qui fonctionnait sur une nouvelle installation de Flask version 1.0.2
Enrico Borba
16

Pour moi fonctionne très bien:

 from flask import Flask, render_template, request, url_for, redirect
 app = Flask(__name__)
 app.config["TEMPLATES_AUTO_RELOAD"] = True

En savoir plus sur http://flask.pocoo.org/docs/1.0/config/

Nikandr Marhal
la source
10

En fait pour moi TEMPLATES_AUTO_RELOAD = Truene fonctionne pas (version 0.12). J'utilise jinja2 et ce que j'ai fait:

  1. Créer une fonction before_request

    def before_request():
        app.jinja_env.cache = {}
  2. Enregistrez-le dans l'application

    app.before_request(before_request)
  3. C'est tout.

dikkini
la source
3
Garret, je n'ai pas testé sans ces options.
dikkini
L'étape 3 n'est pas vraiment nécessaire, cela a très bien fonctionné pour moi.
Ricardo Ribeiro le
4

Ce qui a fonctionné pour moi, c'est simplement d'ajouter ceci:

@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 = {}

( tiré de la réponse de @ dikkini )

Garrett
la source
2

Utilisation de la dernière version de Flask sur Windows, en utilisant la commande run et le débogage défini sur true; Flask n'a pas besoin d'être réinitialisé pour que les modifications apportées aux modèles prennent effet. Essayez Shift + F5 (ou Shift plus le bouton de rechargement) pour vous assurer que rien n'est mis en cache.

Drakekin
la source
1

Mis à jour en juin 2019:

La CLI flask est recommandée sur app.run () pour exécuter un serveur de développement, donc si nous voulons utiliser la CLI, la solution acceptée ne peut pas être utilisée.

L'utilisation de la version de développement de Flask (1.1) à ce jour nous permet de définir une variable d'environnement FLASK_RUN_EXTRA_FILES qui fait effectivement la même chose que la réponse acceptée.

Voir ce problème github .

Exemple d'utilisation:

export FLASK_RUN_EXTRA_FILES="app/templates/index.html"
flask run

sous Linux. Pour spécifier plusieurs fichiers supplémentaires, séparez les chemins de fichiers par des deux points. , par exemple

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

La CLI prend également en charge un --extra-filesargument à partir de Flask 1.1.

étranger
la source
mise à jour mineure. le lien vers 'flask CLI' doit être mis à jour vers la version actuelle. flask.palletsprojects.com/en/1.1.x/cli sinon merci :)
CodingMatters
1

Les modèles sont rechargés automatiquement, pourquoi ne ctrl+f5pas actualiser la page Web, car les navigateurs Web enregistrent généralement le cache.

Chef Shiv
la source