Recarregue o aplicativo Flask quando o arquivo de modelo mudar

95

Por padrão, ao executar o aplicativo Flask usando o servidor integrado ( Flask.run), ele monitora seus arquivos Python e recarrega automaticamente o aplicativo se seu código mudar:

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

Infelizmente, isso parece funcionar apenas para arquivos * .py , e não consigo encontrar nenhuma maneira de estender essa funcionalidade a outros arquivos. Mais notavelmente, seria extremamente útil fazer o Flask reiniciar o aplicativo quando um modelo for alterado. Já perdi a conta de quantas vezes estava mexendo na marcação de modelos e ficando confuso por não ver nenhuma alteração, apenas para descobrir que o aplicativo ainda estava usando a versão antiga do modelo Jinja.

Então, existe uma maneira de ter os arquivos de monitoramento do Flask no diretório de modelos ou é necessário mergulhar no código-fonte do framework?

Editar : estou usando o Ubuntu 10.10. Não tentei isso em nenhuma outra plataforma realmente.


Após uma investigação mais aprofundada, descobri que as alterações nos modelos de fato são atualizadas em tempo real, sem recarregar o próprio aplicativo. No entanto, isso parece se aplicar apenas aos modelos que são passados ​​para flask.render_template.

Mas acontece que, em meu aplicativo, tenho muitos componentes parametrizados reutilizáveis ​​que uso em modelos Jinja. Eles são implementados como programas {% macro %}, residem em "módulos" dedicados e são {% import %}editados em páginas reais. Tudo bom e SECO ... exceto que esses modelos importados aparentemente nunca são verificados quanto a modificações, já que eles não passam de forma render_templatealguma.

(Curiosamente, isso não acontece com modelos invocados {% extends %}. Quanto a {% include %}, não tenho ideia, pois realmente não os uso.)

Então, para finalizar, as raízes desse fenômeno parecem estar em algum lugar entre Jinja e Flask ou Werkzeug. Eu acho que pode justificar uma viagem ao bug tracker para qualquer um desses projetos :) Enquanto isso, aceitei o jd. é a resposta porque essa é a solução que eu realmente usei - e funciona perfeitamente.

Xion
fonte
3
Certifique-se de que o aplicativo esteja configurado com DEBUG = True, consulte a documentação .
Alex Morega

Respostas:

65

Na minha experiência, os modelos nem precisam que o aplicativo seja reiniciado para ser atualizado, pois eles devem ser carregados do disco sempre que render_template()forem chamados. Talvez seus modelos sejam usados ​​de forma diferente.

Para recarregar seu aplicativo quando os modelos forem alterados (ou qualquer outro arquivo), você pode passar o extra_filesargumento para Flask().run(), uma coleção de nomes de arquivos a serem observados: qualquer alteração nesses arquivos acionará o recarregador.

Exemplo:

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)

Veja aqui: http://werkzeug.pocoo.org/docs/0.10/serving/?highlight=run_simple#werkzeug.serving.run_simple

jd.
fonte
Coisa boa! Eu admito que perdi o link na documentação Flask.runque leva aos documentos de Werkzeug. Mas esta opção em particular parece útil o suficiente para pelo menos ser mencionada na documentação do Flask.
Xion
Se alguém encontrar um erro que diga No such file or directory, tente usar o caminho relativo como em:extra_dirs = ['./directory/to/watch',]
Kevin
3
Se você também está confuso sobre o que pathé, é os.path. pensei que valia a pena mencionar
bjesus
Para recarregar automaticamente após alterar arquivos estáticos, consulte isto .
simanacci
1
Alguma ideia de como especificar arquivos extras ao executar a flask runpartir da linha de comando?
Michael Scheper,
143

você pode usar

TEMPLATES_AUTO_RELOAD = True

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

Se deve verificar se há modificações na fonte do modelo e recarregá-lo automaticamente. Por padrão, o valor é Nenhum, o que significa que o Flask verifica o arquivo original apenas no modo de depuração.

Loris
fonte
11
Esta solução é convencional, suportada por documentação, simples de entender e fácil de implementar. Deve ser aceito!
Carolyn Conway
Tentei esta resposta, mas só funciona uma vez, depois de outra atualização não funcionou
medev21
3
Apenas uma nota para os outros: eu fiz app.config['TEMPLATES_AUTO_RELOAD'] = True, e por algum motivo esperava ver o servidor reiniciar automaticamente quando um modelo fosse alterado, como acontece no modo de depuração. Ele não reinicia, mas atualiza o modelo que ele renderiza.
cs01
3
Alguma razão pela qual isso não estaria funcionando para 0,12? ou alguma outra configuração que impediria isso de configurar corretamente?
user805981
3
@Federer Não parece estar funcionando como antes ... Antes, ele teria detectado as mudanças no diretório de templates e nos subdiretórios e recarregaria o servidor .... Isso é algo novo no 0.12 que mudou?
user805981
54

Ao trabalhar com jinjamodelos, você precisa definir alguns parâmetros. No meu caso com python3, resolvi com o seguinte 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
fonte
1
Você salvou minha sanidade. Obrigado.
Nostalg.io
Eu também estava tendo dificuldades com esse problema. Estou feliz por ter ajudado;)
silgon
Isso está funcionando para mim no flask 1.0.2, mas não tenho o argumento host.
Enrico Borba
Sim @EnricoBorba, você provavelmente não vai precisar. Eu geralmente o uso porque depuro localmente com o docker e, às vezes, o aplicativo precisa ser acessado de outro contêiner. Alguma Referência
silgon
@silgon Sim, eu entendo. Eu estava apenas adicionando um comentário para deixar claro o que funcionou em uma nova instalação do Flask versão 1.0.2
Enrico Borba
16

Para mim funciona muito bem:

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

Veja mais em http://flask.pocoo.org/docs/1.0/config/

Nikandr Marhal
fonte
10

Na verdade, para mim TEMPLATES_AUTO_RELOAD = Truenão funciona (versão 0,12). Eu uso jinja2 e o que fiz:

  1. Criar função before_request

    def before_request():
        app.jinja_env.cache = {}
  2. Registre-o no aplicativo

    app.before_request(before_request)
  3. É isso aí.

diquíni
fonte
3
Garret, não testei sem essas opções.
dikkini
O passo 3 não é realmente necessário, funcionou muito bem para mim.
Ricardo Ribeiro
4

O que funcionou para mim foi apenas adicionar isto:

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

( retirado da resposta de @dikkini )

Garrett
fonte
2

Usando a versão mais recente do Flask no Windows, usando o comando run e debug definido como true; O Flask não precisa ser redefinido para que as alterações nos modelos tenham efeito. Tente Shift + F5 (ou Shift mais o botão recarregar) para se certificar de que nada está sendo armazenado em cache.

Drakekin
fonte
1

Atualizado em junho de 2019:

O frasco CLI é recomendado em vez de app.run () para executar um servidor de desenvolvimento, portanto, se quisermos usar o CLI, a solução aceita não pode ser usada.

Usar a versão de desenvolvimento do Flask (1.1) no momento em que este livro foi escrito nos permite definir uma variável de ambiente FLASK_RUN_EXTRA_FILES que efetivamente faz a mesma coisa que a resposta aceita.

Veja este problema do github .

Exemplo de uso:

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

no Linux. Para especificar vários arquivos extras, separe os caminhos de arquivo com dois pontos. , por exemplo

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

A CLI também suporta um --extra-filesargumento do Flask 1.1.

no exterior
fonte
pequena atualização. o link para 'flask CLI' precisa ser atualizado para a versão atual. flask.palletsprojects.com/en/1.1.x/cli, caso contrário, obrigado :)
CodingMatters
1

Os modelos são recarregados automaticamente, por que não ctrl+f5atualizar a página da web, pois os navegadores da web geralmente salvam o cache.

Chefe Shiv
fonte