Ricarica l'app Flask quando il file modello cambia


95

Per impostazione predefinita, quando si esegue l'applicazione Flask utilizzando il server integrato ( Flask.run), monitora i suoi file Python e ricarica automaticamente l'app se il suo codice cambia:

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

Sfortunatamente, questo sembra funzionare solo per i file * .py e non mi sembra di trovare alcun modo per estendere questa funzionalità ad altri file. In particolare, sarebbe estremamente utile che Flask riavvii l'app quando un modello cambia. Ho perso il conto di quante volte stavo giocherellando con il markup nei modelli e mi sono confuso non vedendo alcuna modifica, solo per scoprire che l'app utilizzava ancora la vecchia versione del modello Jinja.

Quindi, c'è un modo per avere i file di monitoraggio di Flask nella directory dei modelli o è necessario immergersi nella fonte del framework?

Modifica : sto usando Ubuntu 10.10. Non l'ho mai provato su altre piattaforme.


Dopo ulteriori indagini, ho scoperto che le modifiche ai modelli vengono effettivamente aggiornate in tempo reale, senza dover ricaricare l'app stessa. Tuttavia, questo sembra applicarsi solo a quei modelli a cui vengono passati flask.render_template.

Ma succede che nella mia app ho molti componenti riutilizzabili e parametrizzati che uso nei modelli Jinja. Sono implementati come {% macro %}s, risiedono in "moduli" dedicati e sono {% import %}inseriti in pagine reali. Tutto bello e ASCIUTTO ... tranne per il fatto che quei modelli importati apparentemente non vengono mai controllati per eventuali modifiche, poiché non passano render_templateaffatto.

(Curiosamente, questo non accade per i modelli invocati tramite {% extends %}. Per quanto riguarda {% include %}, non ne ho idea perché non li uso davvero.)

Quindi, per concludere, le radici di questo fenomeno sembrano essere da qualche parte tra Jinja e Flask o Werkzeug. Immagino che possa giustificare un viaggio al bug tracker per uno di questi progetti :) Nel frattempo, ho accettato il jd. La risposta è perché questa è la soluzione che ho effettivamente usato e funziona a meraviglia.


3
Assicurati che l'app configurata con DEBUG = True, vedi la documentazione .
Alex Morega

Risposte:


65

Nella mia esperienza, i modelli non hanno nemmeno bisogno del riavvio dell'applicazione per essere aggiornati, poiché dovrebbero essere caricati dal disco ogni volta che render_template()vengono chiamati. Forse i tuoi modelli sono usati in modo diverso però.

Per ricaricare la tua applicazione quando i modelli cambiano (o qualsiasi altro file), puoi passare l' extra_filesargomento a Flask().run(), una raccolta di nomi di file da controllare: qualsiasi modifica su quei file attiverà il ricaricatore.

Esempio:

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)

Vedi qui: http://werkzeug.pocoo.org/docs/0.10/serving/?highlight=run_simple#werkzeug.serving.run_simple


Roba buona! Ammetto di aver perso il collegamento nella documentazione Flask.runche porta ai documenti di Werkzeug. Ma questa particolare opzione sembra abbastanza utile da averla almeno menzionata nei documenti di Flask.
Xion

Se qualcuno incontra un errore che dice No such file or directory, prova a utilizzare il percorso relativo come in:extra_dirs = ['./directory/to/watch',]
Kevin

3
Se anche tu sei confuso su ciò che pathè, lo è os.path. ho pensato che valesse la pena menzionarlo
bjesus

Per il ricaricamento automatico dopo aver modificato i file statici, vedere questo .
simanacci

1
Qualche idea su come specificare file extra durante l'esecuzione flask rundalla riga di comando?
Michael Scheper

143

Puoi usare

TEMPLATES_AUTO_RELOAD = True

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

Indica se verificare le modifiche dell'origine del modello e ricaricarlo automaticamente. Per impostazione predefinita, il valore è Nessuno, il che significa che Flask controlla il file originale solo in modalità di debug.


11
Questa soluzione è convenzionale, supportata dalla documentazione, semplice da capire e facile da implementare. Dovrebbe essere accettato!
Carolyn Conway

Ho provato questa risposta ma funziona solo una volta, dopo un altro aggiornamento non funzionerebbe
medev21

3
Solo una nota per gli altri: l'ho fatto app.config['TEMPLATES_AUTO_RELOAD'] = True, e per qualche motivo mi aspettavo di vedere il riavvio automatico del server quando un modello cambiava, come fa in modalità debug. Non si riavvia, ma aggiorna il modello che esegue il rendering.
cs01

3
Qualche motivo per cui non funzionerebbe per 0.12? o qualche altra impostazione che impedirebbe di impostare correttamente?
user805981

3
@Federer Non sembra funzionare come una volta ... Prima, avrebbe rilevato le modifiche nella directory dei modelli e nelle sottodirectory e avrebbe ricaricato il server ... È qualcosa di nuovo nella 0.12 che cambiato?
user805981

54

Quando si lavora con i jinjamodelli, è necessario impostare alcuni parametri. Nel mio caso con python3, l'ho risolto con il seguente codice:

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

1
Hai salvato la mia sanità mentale. Grazie.
Nostalg.io

Stavo anche attraversando un periodo difficile con quel problema. Sono contento di aver potuto aiutare;)
silgon

Questo funziona per me su flask 1.0.2, ma non ho l'argomento host.
Enrico Borba

Sì @EnricoBorba, probabilmente non ne avrai bisogno. Di solito lo uso perché eseguo il debug in locale con docker e talvolta è necessario accedere all'applicazione da un altro contenitore. Qualche riferimento
silgon

@silgon Sì, ho capito. Principalmente stavo solo aggiungendo al commento per essere chiari su cosa ha funzionato su una nuova installazione di Flask versione 1.0.2
Enrico Borba


10

In realtà per me TEMPLATES_AUTO_RELOAD = Truenon funziona (versione 0.12). Uso jinja2 e cosa ho fatto:

  1. Crea funzione before_request

    def before_request():
        app.jinja_env.cache = {}
  2. Registralo nell'applicazione

    app.before_request(before_request)
  3. Questo è tutto.


3
Garret, non ho provato senza queste opzioni.
dikkini

Il passaggio 3 non è realmente necessario, ha funzionato molto bene per me.
Ricardo Ribeiro

4

Quello che ha funzionato per me è solo aggiungere questo:

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

( tratto dalla risposta di @ dikkini )


2

Utilizzando l'ultima versione di Flask su Windows, utilizzando il comando run e debug impostato su true; Flask non ha bisogno di essere reimpostato per rendere effettive le modifiche ai modelli. Prova Maiusc + F5 (o Maiusc più il pulsante di ricarica) per assicurarti che nulla venga memorizzato nella cache.



1

Aggiornato a giugno 2019:

Il flask CLI è consigliato su app.run () per l'esecuzione di un server di sviluppo, quindi se vogliamo utilizzare la CLI, la soluzione accettata non può essere utilizzata.

L'uso della versione di sviluppo di Flask (1.1) al momento della stesura di questo articolo ci consente di impostare una variabile d'ambiente FLASK_RUN_EXTRA_FILES che effettivamente fa la stessa cosa della risposta accettata.

Vedi questo problema di GitHub .

Utilizzo di esempio:

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

in Linux. Per specificare più file aggiuntivi, separare i percorsi dei file con i due punti. , per esempio

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

La CLI supporta anche un --extra-filesargomento a partire da Flask 1.1.


aggiornamento minore. il collegamento a "flask CLI" deve essere aggiornato alla versione corrente. flask.palletsprojects.com/en/1.1.x/cli altrimenti grazie :)
CodingMatters

1

I modelli vengono ricaricati automaticamente, perché non ctrl+f5aggiornare la pagina web, perché i browser web di solito salvano la cache.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.