Recargue la aplicación Flask cuando cambie el archivo de plantilla

95

De forma predeterminada, cuando se ejecuta la aplicación Flask usando el servidor integrado ( Flask.run), monitorea sus archivos Python y recarga automáticamente la aplicación si cambia su código:

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

Desafortunadamente, esto parece funcionar solo para archivos * .py , y no parece encontrar ninguna forma de extender esta funcionalidad a otros archivos. En particular, sería extremadamente útil que Flask reiniciara la aplicación cuando cambia una plantilla . Perdí la cuenta de cuántas veces estaba jugando con el marcado en las plantillas y me confundía al no ver ningún cambio, solo para descubrir que la aplicación todavía usaba la versión anterior de la plantilla Jinja.

Entonces, ¿hay alguna manera de hacer que Flask supervise los archivos en el directorio de plantillas o es necesario sumergirse en la fuente del marco?

Editar : estoy usando Ubuntu 10.10. Realmente no lo he probado en ninguna otra plataforma.


Después de investigar más, descubrí que los cambios en las plantillas se actualizan en tiempo real, sin tener que volver a cargar la aplicación. Sin embargo, esto parece aplicarse solo a las plantillas a las que se pasa flask.render_template.

Pero sucede que en mi aplicación, tengo bastantes componentes reutilizables y parametrizados que utilizo en las plantillas de Jinja. Se implementan como {% macro %}s, residen en "módulos" dedicados y se {% import %}editan en páginas reales. Todo agradable y SECO ... excepto que esas plantillas importadas aparentemente nunca se revisan para detectar modificaciones, ya que no pasan render_templateen absoluto.

(Curiosamente, esto no sucede con las plantillas invocadas mediante {% extends %}. En cuanto a {% include %}, no tengo ni idea, ya que realmente no las uso).

Entonces, para terminar, las raíces de este fenómeno parecen estar en algún lugar entre Jinja y Flask o Werkzeug. Supongo que puede justificar un viaje al rastreador de errores para cualquiera de esos proyectos :) Mientras tanto, he aceptado el jd. La respuesta es porque esa es la solución que realmente utilicé, y funciona como un encanto.

Xion
fuente
3
Asegúrese de que la aplicación esté configurada con DEBUG = True, consulte los documentos .
Alex Morega

Respuestas:

65

En mi experiencia, las plantillas ni siquiera necesitan que la aplicación se reinicie para actualizarse, ya que deben cargarse desde el disco cada vez que render_template()se llama. Sin embargo, quizás sus plantillas se usen de manera diferente.

Para recargar su aplicación cuando cambien las plantillas (o cualquier otro archivo), puede pasar el extra_filesargumento a Flask().run()una colección de nombres de archivos para observar: cualquier cambio en esos archivos activará el recargador.

Ejemplo:

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)

Ver aquí: http://werkzeug.pocoo.org/docs/0.10/serving/?highlight=run_simple#werkzeug.serving.run_simple

jd.
fuente
¡Buen material! Admito que me perdí el enlace en la documentación Flask.runque conduce a los documentos de Werkzeug. Pero esta opción en particular parece lo suficientemente útil como para que al menos se la mencione en los documentos de Flask.
Xion
Si alguien encuentra un error que dice No such file or directory, intente usar la ruta relativa como en:extra_dirs = ['./directory/to/watch',]
Kevin
3
Si usted también está confundido acerca de lo que pathes, lo es os.path. pensé que valía la pena mencionarlo
bjesus
Para la recarga automática después de cambiar archivos estáticos, vea esto .
Simanacci
1
¿Alguna idea de cómo especificar archivos adicionales cuando se ejecuta flask rundesde la línea de comandos?
Michael Scheper
143

puedes usar

TEMPLATES_AUTO_RELOAD = True

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

Ya sea para verificar las modificaciones de la fuente de la plantilla y volver a cargarla automáticamente. De forma predeterminada, el valor es Ninguno, lo que significa que Flask comprueba el archivo original solo en modo de depuración.

Loris
fuente
11
Esta solución es convencional, respaldada por documentación, fácil de entender y fácil de implementar. ¡Debería ser aceptado!
Carolyn Conway
Probé
3
Solo una nota para los demás: lo hice app.config['TEMPLATES_AUTO_RELOAD'] = True, y por alguna razón esperaba ver que el servidor se reiniciara automáticamente cuando cambiaba una plantilla, como ocurre en el modo de depuración. No se reinicia, pero SÍ actualiza la plantilla que renderiza.
cs01
3
¿Alguna razón por la que esto no funcionaría para 0.12? o alguna otra configuración que impida que esto se establezca correctamente?
user805981
3
@Federer No parece estar funcionando como solía ... Antes, habría detectado los cambios en el directorio de plantillas y los subdirectorios y volvería a cargar el servidor ... ¿Es esto algo nuevo en 0.12 que cambiado?
user805981
54

Cuando trabaja con jinjaplantillas, necesita establecer algunos parámetros. En mi caso con python3, lo resolví con el siguiente código:

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
fuente
1
Salvaste mi cordura. Gracias.
Nostalg.io
También estaba teniendo dificultades con ese problema. Me alegro de haber podido ayudar;)
silgon
Esto me funciona en el matraz 1.0.2, pero no tengo el argumento de host.
Enrico Borba
Sí @EnricoBorba, probablemente no lo necesites. Normalmente lo uso porque depuro en local con Docker y, a veces, es necesario acceder a la aplicación desde otro contenedor. Alguna referencia
silgon
@silgon Sí, lo entiendo. Principalmente solo estaba agregando un comentario para ser claro sobre lo que funcionó en una nueva instalación de Flask versión 1.0.2
Enrico Borba
16

Para mí funciona muy bien:

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

Más información en http://flask.pocoo.org/docs/1.0/config/

Nikandr Marhal
fuente
10

En realidad para mí TEMPLATES_AUTO_RELOAD = Trueno funciona (versión 0.12). Yo uso jinja2 y lo que he hecho:

  1. Crear función before_request

    def before_request():
        app.jinja_env.cache = {}
  2. Regístrese en la aplicación

    app.before_request(before_request)
  3. Eso es.

dikkini
fuente
3
Garret, no probé sin estas opciones.
dikkini
El paso 3 no es realmente necesario, me funcionó muy bien.
Ricardo Ribeiro
4

Lo que funcionó para mí es simplemente agregar esto:

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

( tomado de la respuesta de @ dikkini )

Garrett
fuente
2

Usando la última versión de Flask en Windows, usando el comando run y debug establecido en true; No es necesario restablecer el frasco para que los cambios en las plantillas surtan efecto. Pruebe Shift + F5 (o Shift más el botón de recarga) para asegurarse de que no se esté almacenando en caché.

Drakekin
fuente
1

Actualizado a junio de 2019:

La CLI del matraz se recomienda sobre app.run () para ejecutar un servidor de desarrollo, por lo que si queremos usar la CLI, no se puede usar la solución aceptada.

El uso de la versión de desarrollo de Flask (1.1) al momento de escribir este artículo nos permite configurar una variable de entorno FLASK_RUN_EXTRA_FILES que efectivamente hace lo mismo que la respuesta aceptada.

Vea este problema de github .

Uso de ejemplo:

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

en Linux. Para especificar varios archivos adicionales, separe las rutas de archivo con dos puntos. , p.ej

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

La CLI también admite un --extra-filesargumento a partir del Flask 1.1.

de ultramar
fuente
actualización menor. El enlace a 'flask CLI' necesita actualizarse a la versión actual. flask.palletsprojects.com/en/1.1.x/cli de lo contrario gracias :)
CodingMatters
1

Las plantillas se recargan automáticamente, por qué no ctrl+f5actualizar la página web, ya que los navegadores web suelen guardar caché.

Jefe Shiv
fuente