Como imprimir do Flask @ app.route para o console python

90

Eu gostaria de simplesmente imprimir um "hello world" no console do python após o botão / ser chamado pelo usuário.

Esta é minha abordagem ingênua:

@app.route('/button/')
def button_clicked():
    print 'Hello world!'
    return redirect('/')

Contexto: Eu gostaria de executar outros comandos python a partir do flask (não do shell). "imprimir" deve ser o caso mais fácil. Eu acredito que não entendi uma torção básica aqui. Desde já, obrigado!

Robert Filter
fonte
1
Você está confundindo duas coisas aqui. Você pode chamar qualquer função que desejar de um manipulador; mas o problema com o print é o que o Flask está fazendo com o stdout.
Daniel Roseman
Olá @DanielRoseman e obrigado pelo comentário! Então o flask está direcionando a impressão para http? O que devo fazer para evitar isso? Desculpe se a pergunta for boba :)
Robert Filter
1
Não há perguntas bobas :)
Ciaran Liedeman
O frasco não direciona printpara a resposta. Se você estiver executando o servidor de desenvolvimento a partir de uma sessão de terminal, verá a saída lá. Se você estiver executando-o por meio de um servidor WSGI, como uWSGI, a saída aparecerá nos logs.
dirn
Como você está começando o frasco?
Ciaran Liedeman

Respostas:

117

Parece que você já resolveu, mas para outras pessoas que procuram essa resposta, uma maneira fácil de fazer isso é imprimindo em stderr. Você pode fazer isso assim:

from __future__ import print_function # In python 2.7
import sys

@app.route('/button/')
def button_clicked():
    print('Hello world!', file=sys.stderr)
    return redirect('/')

O Flask exibirá as coisas impressas em stderr no console. Para outras maneiras de imprimir em stderr, consulte esta postagem sobre fluxo de pilha

Gabe
fonte
Thx @Gabe, este parece ser um caminho a percorrer.
Robert Filter
Eu realmente preciso revisar todos os arquivos e adicionar from __future__ import print_functiontambém file=sys.stderrpara cada impressão? existe um caminho curto para isso?
e271p314
Eu recomendaria dar uma olhada no post que criei um link na resposta original. Alguém recomenda definir uma função que sempre imprime em stderr (você pode colocar isso em um arquivo util que você já importou). Outra pessoa recomenda sys.stderr.write.
Gabe
Você também pode economizar um pouco de repetição com: from sys import stderr, file=stderr. No Python 3+, você não precisa from __future__ import print_function, essa é a funcionalidade padrão.
Phoenix
Se despejar um objeto, isso parece funcionarpprint(vars(myobject), sys.stderr)
jcroll
25

Também podemos usar o registro para imprimir dados no console.

Exemplo:

import logging
from flask import Flask

app = Flask(__name__)

@app.route('/print')
def printMsg():
    app.logger.warning('testing warning log')
    app.logger.error('testing error log')
    app.logger.info('testing info log')
    return "Check your console"

if __name__ == '__main__':
    app.run(debug=True)
Viraj Wadate
fonte
1
Veja isso se você não conseguir fazer o registrador de informações funcionar: flask.palletsprojects.com/en/1.0.x/logging
gunslingor
8

Acho que o principal problema com o Flask é que o stdout fica armazenado em buffer. Consegui imprimir com print('Hi', flush=True). Você também pode desabilitar o armazenamento em buffer definindo a PYTHONUNBUFFEREDvariável de ambiente (para qualquer string não vazia).

Chris
fonte
Esta é a melhor forma de depuração de impressão, especialmente em pequenos projetos
learner0000
Qual é o valor que deve ser definido na variável env PYTHONUNBUFFERED?
thanos.a
1
@ thanos.a Você pode defini-lo como qualquer string não vazia. Eu atualizei a resposta.
Chris
Você pode adicionar um exemplo como PYTHONUNBUFFERED = "qualquer
coisa_aqui
0

Tentei executar o código de @Viraj Wadate, mas não consegui obter a saída app.logger.infono console.

Para chegar INFO, WARNINGe ERRORmensagens no console, o dictConfigobjeto pode ser usado para criar configuração de registo para todos os logs ( fonte ):

from logging.config import dictConfig
from flask import Flask


dictConfig({
    'version': 1,
    'formatters': {'default': {
        'format': '[%(asctime)s] %(levelname)s in %(module)s: %(message)s',
    }},
    'handlers': {'wsgi': {
        'class': 'logging.StreamHandler',
        'stream': 'ext://flask.logging.wsgi_errors_stream',
        'formatter': 'default'
    }},
    'root': {
        'level': 'INFO',
        'handlers': ['wsgi']
    }
})


app = Flask(__name__)

@app.route('/')
def index():
    return "Hello from Flask's test environment"

@app.route('/print')
def printMsg():
    app.logger.warning('testing warning log')
    app.logger.error('testing error log')
    app.logger.info('testing info log')
    return "Check your console"

if __name__ == '__main__':
    app.run(debug=True)

Saurabh
fonte