flask print not working...
제목 그대로 vscode로 python flask 웹 서버를 열고 print함수로 콘솔창에 결과를 확인하려던 중 발견한 문제,
# 3. app을 bp로 교체
@bp.route('/', methods=['GET', 'POST'])
def signUp():
print("signup페이지 이동")
if request.method == 'POST':
print(request.form)
username = request.form['username']
nickname = request.form['nickname']
email = request.form['email']
password = request.form['password']
print(username, nickname, email, password)
if checkEmailDuplicate(email):
#어쩌구 저쩌구 회원가입 로직
print("get 요청시")
return render_template('signup.html')
flask 서버를 run 하고 위와 같은 코드가 실행되었을 때 즉, 회원가입페이지 이동 요청이 들어왔을 때
signUp 함수 안의 가장 윗줄의 print함수가 실행이 되었어야함에도 불구하고 콘솔창에 출력이 되지 않았다..
2+1가지의 해결책이 있다.
당장 stack overflow에 가보면 여러 해결책이있다.
1. print 함수에 flush=True 옵션 주기
print("출력할 문자열", flush=True)
이렇게 하면 된다는 글이 stackoverflow에 엄청많다.
flush 옵션이 뭐길래 저렇게하면 된다는 걸까?
print 함수의 flush 옵션
flush = True 를 적용하면 print함수가 실행될때마다 버퍼에 저장된 문자열을 콘솔에 출력한다.
flush = False를 적용하면 print() 함수의 기본 end parameter로 설정된 줄 바꿈 이스케이프 문자 ( \n) 가 아닌, 예를 들어,
for i in range(0,10):
print(”글자사이띄어쓰기한개”, end = ' ')
위처럼 작성하면 아래와 같은 결과를 얻을 수 있는데,
>>> 글자사이띄어쓰기한개 글자사이띄어쓰기한개 글자사이띄어쓰기한개 .....
# 한번에 출력됨
이는 사실 출력물을 저장하는 버퍼에 한 덩어리씩 쌓이다가 flush되는 순간에 한 번에 출력된 것이다.
정확하게 실행된 순서를 말하자면 buffer에 print, buffer에 print, buffer에 print ...10번 실행되고 나서 buffer의 내용을 flush!
원리를 이해하자면 변기에 많이 뭘 집어넣긴(print) 넣었는데 물을 안내렸으니까! (flush) (좀 더럽다)
그러면 방금 상황에서 flush 옵션을 True로 주면?
print(”글자사이띄어쓰기한개”, end = ' ', flush=True)
>>> 글자사이띄어쓰기한개 글자사이띄어쓰기한개 글자사이띄어쓰기한개
# 한 덩어리씩 출력됨
결과는 같지만 한덩어리씩 콘솔에 출력되는 것이다.
그런데 이마저도 파이썬 실행환경에 따라 언제나 flush=True 인 것 처럼 실행되는 경우도 있다고 한다.
print("난 파이썬 싫어", flush = True)
flush 옵션은 그만 알아보고 그러면 이게 flask에서 print가 안되는거랑 무슨상관이냐 하면,
Console Application이 아닌 Web Application 등의 다른 어플리케이션에서는 Console 출력이 정상적으로 작동하지 않을 수도 있다.
그러니까 print 함수의 기본 옵션인 (flush = False) 를 바꿔가면서 강제로 버퍼에 담겨서 출력되지못하고있는 출력물들을 flush 해주는게 하나의 해결책이 될 수 있다.
콘솔 앱이 주로 실습할때 사용하던 그냥 그거다. cmd창도 콘솔앱이고 git bash도 콘솔앱.
웹 앱은 웹 서버를 구동하는 기능이 내장되어있는 프레임워크를 활용해서 여는 방식이고, 이 때는 콘솔창에 뭘 입력한다고 브라우저의 페이지 이동이 되는게 아니므로 콘솔 앱이 아니다.
(너무나도 간소화한 설명입니다. 이게 중요한게 아니니까)
그래서 왜 안되고 어떻게 해야하는지는 아래 3번에!
https://gitlab.com/meltano/meltano/-/issues/106
Cannot print from flask for debugging (#106) · Issues · Meltano / Meltano · GitLab
@iroussos @austinpray
gitlab.com
위 링크에서 flask를 WSGI서버에서 실행하는 경우 웹 서버 자체에서 print출력을 처리하지 않는다는 충격적인 이야기를 봤다.
왜냐하면 WSGI서버 자체가 console application이 아니니까 print로 console창에 출력하는게 잘 되지 않는 것이 오히려 자연스럽다는 말까지. (물론 이걸로 나의 문제를 해결한 건 아니였지만...)
2. app.logger 사용하여 print 대신 logger 활용
import logging
app.logger.setLevel(level=logging.DEBUG)
@app.route("엔드포인트")
def helloEndpoint():
app.logger.info("접속 요청 처리")
return render_template("어쩌구")
남녀노소 국적불문 flask에서 제공하는 app.logger를 활용하여 콘솔에 로그를 찍는 방식으로 출력물을 확인한다고 했는데, 또 나의 경우는 이게 문제가 아니였다.
3. (flask 문제 아님) 터미널 창이 여러개인 경우
사실 문제는 엉뚱한데 있었다.
위의 사진의 오른쪽 하단에 보면 여러개의 터미널 창을 띄운 것을 볼 수 있는데,
위 사진처럼 vscode에서 지원하는 Run and Debug 기능을 이용하여 flask 서버를 연 경우에는
위와같이 Python Debug Console이라는 이름의 새로운 터미널이 생기고,
이게 바로 Console Application이 아닌 Web Application이니까 이 Python Debug Console 터미널창에는 flask 서버 내부 로직 코드 내부에 있는 print함수로는 콘솔 출력이 찍히지 않는 오류였다!
(정확하게 말하면 1번 설명의 연장으로 오류는 아니고 Web Application을 Run 하는 상황에서 어느정도 자연스러운 결과이다.)
(app.run()이 실행되기 전에는, 그러니까 flask 서버가 열리기 전까지는 print 출력이 찍힌다.)
사실 Run and Debug 기능을 사용한 이유는 중단점을 걸고 디버깅을 하고자 함이었는데, 디버깅도 똑바로 되지 않았다. 결과적으로 디버깅도 못하고 print가 출력되지 않는 현상만 나타나다보니 프로젝트 제출 전날 23시 30분쯤에 머리가 터질 뻔 했다.
그래도 돌아보면 콘솔앱과 웹앱의 차이를 얕게나마 알게된 시간이였다.