วิธีการพิมพ์จาก Flask @ app.route ไปยัง python console


91

ฉันต้องการเพียงแค่พิมพ์ "สวัสดีชาวโลก" ไปยังคอนโซล python หลังจาก / ปุ่มถูกเรียกโดยผู้ใช้

นี่เป็นวิธีการที่ไร้เดียงสาของฉัน:

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

ความเป็นมา: ฉันต้องการเรียกใช้คำสั่ง python อื่น ๆ จากขวด (ไม่ใช่เชลล์) "พิมพ์" น่าจะเป็นกรณีที่ง่ายที่สุด ฉันเชื่อว่าฉันไม่เข้าใจเรื่องพื้นฐานที่นี่ ขอบคุณล่วงหน้า!


1
คุณกำลังสับสนสองสิ่งที่นี่ คุณสามารถเรียกใช้ฟังก์ชันใดก็ได้ที่คุณต้องการจากตัวจัดการ แต่ปัญหาในการพิมพ์คือสิ่งที่ Flask กำลังทำเพื่อ stdout
Daniel Roseman

สวัสดี @DanielRoseman และขอบคุณสำหรับความคิดเห็น! ดังนั้น flask จึงค่อนข้างกำหนดเส้นทางการพิมพ์ไปที่ http? ฉันควรทำอย่างไรเพื่อป้องกันปัญหานี้? ขออภัยหากคำถามงี่เง่า :)
Robert Filter

1
ไม่มีคำถามโง่ ๆ :)
Ciaran Liedeman

Flask ไม่ได้กำหนดเส้นทางprintไปยังการตอบสนอง หากคุณกำลังเรียกใช้เซิร์ฟเวอร์การพัฒนาจากเซสชันเทอร์มินัลคุณจะเห็นผลลัพธ์ที่นั่น หากคุณใช้งานผ่านเซิร์ฟเวอร์ WSGI เช่น uWSGI ผลลัพธ์จะปรากฏในบันทึกแทน
dirn

คุณเริ่มกระติกน้ำอย่างไร?
Ciaran Liedeman

คำตอบ:


117

ดูเหมือนว่าคุณจะได้ผล แต่สำหรับคนอื่นที่กำลังมองหาคำตอบนี้วิธีง่ายๆในการทำเช่นนี้คือการพิมพ์ไปยัง stderr คุณสามารถทำได้ดังนี้:

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 จะแสดงสิ่งที่พิมพ์ไปยัง stderr ในคอนโซล สำหรับวิธีอื่น ๆ ในการพิมพ์ไปยัง stderr โปรดดูโพสต์ stackoverflow นี้


Thx @Gabe นี่ดูเหมือนจะเป็นวิธีที่จะไป
Robert Filter

ฉันต้องการจริงๆไปกว่าไฟล์ทั้งหมดและเพิ่มfrom __future__ import print_functionยังfile=sys.stderrทุกพิมพ์? มีวิธีสั้น ๆ ไหม
e271p314

ฉันขอแนะนำให้ดูโพสต์ที่ฉันลิงก์ไว้ในคำตอบเดิม มีคนหนึ่งแนะนำให้กำหนดฟังก์ชันที่จะพิมพ์ไปที่ stderr เสมอ (คุณสามารถใส่ไว้ในไฟล์ util ที่คุณนำเข้าแล้ว) อีกคนแนะนำ sys.stderr.write
Gabe

นอกจากนี้คุณยังสามารถบันทึกการทำซ้ำได้เล็กน้อยด้วย: from sys import stderr, file=stderr. ใน Python 3+ คุณไม่จำเป็นต้องใช้from __future__ import print_functionนั่นคือฟังก์ชันเริ่มต้น
ฟีนิกซ์

หากทิ้งวัตถุสิ่งนี้ดูเหมือนจะใช้ได้pprint(vars(myobject), sys.stderr)
jcroll

25

เรายังสามารถใช้การบันทึกเพื่อพิมพ์ข้อมูลบนคอนโซล

ตัวอย่าง:

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)

1
ดูสิ่งนี้หากคุณไม่สามารถทำให้เครื่องบันทึกข้อมูลทำงานได้: flask.palletsprojects.com/th/1.0.x/logging
gunslingor

8

ฉันคิดว่าปัญหาหลักของ Flask คือ stdout ถูกบัฟเฟอร์ ฉันสามารถพิมพ์ด้วยprint('Hi', flush=True). คุณยังสามารถปิดใช้งานบัฟเฟอร์ได้โดยตั้งค่าPYTHONUNBUFFEREDตัวแปรสภาพแวดล้อม (เป็นสตริงที่ไม่ว่างเปล่า)


นี่เป็นวิธีที่ดีที่สุดสำหรับการดีบักการพิมพ์โดยเฉพาะอย่างยิ่งในโปรเจ็กต์ขนาดเล็ก
เรียน 00

ค่าที่ควรตั้งในตัวแปร PYTHONUNBUFFERED env คืออะไร?
thanos.a

1
@ thanos.a คุณสามารถตั้งค่าเป็นสตริงใดก็ได้ที่ไม่ว่างเปล่า ฉันอัปเดตคำตอบแล้ว
คริส

คุณสามารถเพิ่มตัวอย่างเช่น PYTHONUNBUFFERED = "anything_here"
thanos.a

0

ฉันพยายามเรียกใช้โค้ดของ @Viraj Wadate แต่ไม่สามารถรับเอาต์พุตจากapp.logger.infoบนคอนโซลได้

ที่จะได้รับINFO, WARNINGและERRORข้อความในคอนโซลdictConfigวัตถุสามารถนำมาใช้ในการสร้างการกำหนดค่าการบันทึกสำหรับบันทึกทั้งหมด ( แหล่งที่มา ):

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)

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.