Cara mencetak dari Flask @ app.route ke konsol python

90

Saya hanya ingin mencetak "hello world" ke konsol python setelah tombol / dipanggil oleh pengguna.

Ini adalah pendekatan naif saya:

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

Latar Belakang: Saya ingin menjalankan perintah python lain dari flask (bukan shell). "print" harus menjadi kasus termudah. Saya yakin saya belum memahami perubahan mendasar di sini. Terima kasih sebelumnya!

Robert Filter
sumber
1
Anda membingungkan dua hal di sini. Anda dapat memanggil fungsi apa pun yang Anda suka dari pawang; tapi masalah dengan print adalah apa yang dilakukan Flask pada stdout.
Daniel Roseman
Hai @DanielRoseman dan terima kasih atas komentarnya! Jadi flask agak mengarahkan print ke http? Apa yang harus saya lakukan untuk mencegahnya? Maaf jika pertanyaannya konyol :)
Robert Filter
1
Tidak ada pertanyaan konyol :)
Ciaran Liedeman
Flask tidak mengarahkan printke respon. Jika Anda menjalankan server pengembangan dari sesi terminal, Anda akan melihat hasilnya di sana. Jika Anda menjalankannya melalui server WSGI seperti uWSGI, hasilnya akan muncul di log.
dirn
Bagaimana Anda memulai flask?
Ciaran Liedeman

Jawaban:

117

Sepertinya Anda sudah berhasil, tetapi bagi orang lain yang mencari jawaban ini, cara mudah untuk melakukannya adalah dengan mencetak ke stderr. Anda bisa melakukannya seperti ini:

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('/')

Flask akan menampilkan hal-hal yang dicetak ke stderr di konsol. Untuk cara lain mencetak ke stderr, lihat posting stackoverflow ini

Gabe
sumber
Terima kasih @Gabe, ini sepertinya cara untuk pergi.
Robert Filter
Apakah saya benar-benar perlu memeriksa semua file dan menambahkan from __future__ import print_functionjuga file=sys.stderruntuk setiap cetakan? apakah ada jalan pintas untuk itu?
e271p314
Saya akan merekomendasikan untuk melihat posting yang saya tautkan di jawaban asli. Ada satu orang yang merekomendasikan untuk menentukan fungsi yang selalu dicetak ke stderr (Anda dapat meletakkan ini di file util yang sudah Anda impor). Orang lain merekomendasikan sys.stderr.write.
Gabe
Anda juga bisa menghemat sedikit pengulangan dengan: from sys import stderr, file=stderr. Di Python 3+, Anda tidak perlu from __future__ import print_function, itu adalah fungsionalitas default.
phoenix
Jika membuang suatu objek, ini sepertinya berhasilpprint(vars(myobject), sys.stderr)
jcroll
25

Kami juga dapat menggunakan logging untuk mencetak data di konsol.

Contoh:

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
sumber
1
Lihat ini jika Anda tidak dapat mengaktifkan
Gunslingor
8

Saya pikir masalah inti dengan Flask adalah stdout mendapat buffer. Saya bisa mencetak dengan print('Hi', flush=True). Anda juga dapat menonaktifkan buffering dengan menyetel PYTHONUNBUFFEREDvariabel lingkungan (ke string tidak kosong apa pun).

Chris
sumber
Ini adalah cara terbaik untuk proses debug cetak, terutama dalam proyek kecil
pelajar0000
Berapa nilai yang harus disetel dalam variabel env PYTHONUNBUFFERED?
thanos.a
1
@ thanos.a Anda dapat menyetelnya ke sembarang string yang tidak kosong. Saya memperbarui jawabannya.
Chris
Anda dapat menambahkan contoh seperti PYTHONUNBUFFERED = "anything_here"
thanos.a
0

Saya mencoba menjalankan kode @Viraj Wadate, tetapi tidak bisa mendapatkan hasilnya app.logger.info konsol.

Untuk mendapatkan INFO,, WARNINGdan ERRORpesan di konsol, dictConfigobjek dapat digunakan untuk membuat konfigurasi logging untuk semua log ( sumber ):

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
sumber