Flask 입문 수업을 듣고 중요한 내용을 정리했습니다.
개인 공부 후 자료를 남기기 위한 목적이므로 내용 상에 오류가 있을 수 있습니다.
flask의 다양한 기능(Python)
flask의 다양한 기능을 예제를 통해 학습하고 연습하고자 한다.
에러(error) 다루기
from flask import Flask
import requests
app = Flask(__name__)
@app.errorhandler(404)
def page_not_found(error):
return "<h1>404 Error</h1>", 404 # 없는 페이지를 요청했을 때의 에러
@app.route("/google")
def get_google():
response = requests.get("http://www.google.co.kr")
return response.text
if __name__ == "__main__":
app.run(host="0.0.0.0", port="8080")
```
결과 :
(존재하는 웹 페이지를 요청한 경우)
참고로, response 객체의 text를 사용하면 해당 객체로 들어온 웹 페이지의 HTML 파일을 웹 브라우저로 오픈할 수 있다.
(존재하지 않는 웹 페이지를 요청한 경우)
```
errorhandler() 함수를 사용하면 HTTP 오류 코드가 나오는 페이지를 정의할 수 있다.
참고로, return의 두 번째 인자에 에러코드를 넘겨주지 않으면 웹 페이지의 요청을 성공(HTTP status code : 200)한 것으로 인지한다.
로깅(logging) 다루기
서버는 24시간 동작하므로, 문제가 있을 때 어떤 문제가 있었는지 파악하기 위해 로깅 기능을 사용한다.
일반적으로 로깅은 개발 단계에서는 사용하지 않고, 상용화 단계에서 사용자 모니터링 및 해킹 확인 등의 다양한 문제를 파악하기 위해 사용된다.
*참고
파이썬에는 로그를 다루는 logging 라이브러리를 제공한다.
또한, 로깅 정보에는 레벨이 있으며 로깅 정보는 로그의 레벨에 따라 출력(기록)을 제한할 수 있다.
- DEBUG > INFO > WARNING > ERROR > CRITICAL
DEBUG에서 CRITICAL로 갈수록 심각한 문제(에러)임을 의미한다.
import logging
# 파일로 남기기 위해서는 filename='test.log' 파라미터, 어느 로그까지 남길 것인지를 level로 설정 가능
logging.basicConfig(filename='test.log', level=logging.ERROR)
# 로그를 남길 부분에 다음과 같이 로그 레벨에 맞추어 출력해주면 해당 내용이 파일에 들어감
logging.debug("debug")
logging.info("info")
logging.warning("warning")
logging.error("error")
logging.critical("critical")
```
결과 :
```
위의 예시코드에서는 level = logging.ERROR로 로그 레벨이 설정되어 있기 때문에, debug부터 critical까지의 모든 에러를 기록하도록 코드를 작성했음에도 ERROR 이상의 문제만을 해당 파일에 기록하는 것이다.
*예제 코드
from flask import Flask
import requests
app = Flask(__name__)
if not app.debug:
import logging
from logging.handlers import RotatingFileHandler # 사용할 logging 핸들러 이름을 적어줌
file_handler = RotatingFileHandler(
'test_server.log', maxBytes=2000, backupCount=10)
file_handler.setLevel(logging.WARNING) # 어느 단계(level)까지 로깅을 할지를 적어줌
app.logger.addHandler(file_handler) # app.logger.addHandler()에 등록시켜줘야 app.logger로 사용 가능
@app.errorhandler(404)
def page_not_found(error):
app.logger.error('이것은 중요한 에러입니다. page_not_found에서 일어났습니다.')
return "<h1>해당 경로에 맞는 웹페이지가 없습니다. 문제가 지속되면, 관리자에게 연락해주세요</h1>", 404
if __name__ == "__main__":
app.run(host="0.0.0.0", port="8080", debug=False)
```
결과 :
(존재하지 않는 웹 페이지를 요청한 경우 : 404 에러)
```
- flask와 logging 기능
logging 라이브러리와 함께 flask logging 기능을 사용할 수 있다.
- 주요 logging 핸들러 종류(어떻게 로그를 다룰 것인지에 대해 미리 구현된 함수들을 제공함)
- FileHandler : 파일로 로그를 저장함
- RotatingFileHandler : 파일로 로그를 저장하되, 파일의 정해진 사이즈를 넘어가면 새로운 파일을 생성하여 로그를 기록함(maxBytes : 하나의 파일 사이즈, backupCount : 생성할 파일 개수, 참고로 모든 파일을 다 쓰면 맨 앞의 파일에 로그 기록을 덮어씌워 저장함)
- NTEventLogHandler : 윈도우 시스템에서 로그를 기록함
- SysLogHandler : 유닉스 계열(리눅스) 시스템에서 로그를 syslog로 기록함
- 예제 코드 주요내용
- 로그를 기록하는 파일(test_server.log)는 해당 파이썬 코드가 실행되는 폴더에 생성된다.
- 위의 예제코드처럼 404 에러가 발생하면 errorhandler() 함수의 인자에 404 에러가 들어가고, page_not_found() 함수의 인자(error)로 에러 메세지가 들어간다. 그 이후에는 해당 함수가 실행되며 지정된 파일에 로그를 기록한다. (참고로 웹 페이지에는 retrun 값을 반환하여 띄워준다.)
- 참고로, app.run(host='0.0.0.0', port='8080', debug=False)의 코드에서 debug = False이어야만 에러가 발생했을 때 로깅 기능이 작동한다. (debug가 False이어야만 if절의 not app.debug가 True가 되어 해당 if절이 실행됨 : 로깅 기능 실행)
다양한 데코레이터의 기능(flask)
*다양한 데코레이터의 종류
- before_first_request : flask(서버)를 실행한 후, 첫 번째 HTTP 요청에만 앞서 실행되는 데코레이터
- before_request : HTTP 요청이 들어올 때마다, 해당 요청에 앞서 실행되는 데코레이터
- after_request : HTTP 요청을 처리한 후, 해당 리턴 값을 통해 HTTP 응답 데이터가 만들어지면 이를 웹 브라우저에 전달하기에 앞서 실행되는 데코레이터 (참고로, after_reques는 HTTP 응답 데이터를 인자(response)로 받아서 return 해줘야만 데코레이터를 실행한 후에도 HTTP 응답 데이터를 웹 브라우저로 전달함)
*예제 코드
from flask import Flask
import requests
app = Flask(__name__)
@app.before_first_request
def before_first_request():
print("flask 실행 후 첫 요청 때만 실행")
@app.before_request
def before_request():
print("HTTP 요청이 들어올 때마다 실행")
@app.after_request
def after_request(response):
print("HTTP 요청 처리가 끝나고 브라우저에 응답하기 전에 실행")
return response
@app.route("/hello")
def hello():
print('hello')
return "<h1>Hello Flask!</h1>"
if __name__ == "__main__":
app.run(host="0.0.0.0", port="8080")
```
결과 :
(첫 번째 HTTP 요청 결과)
flask 실행 후 첫 요청 때만 실행
HTTP 요청이 들어올 때마다 실행
hello
HTTP 요청 처리가 끝나고 브라우저에 응답하기 전에 실행
127.0.0.1 - - [27/Nov/2021 15:13:41] "GET /hello HTTP/1.1" 200 -
(두 번째 HTTP 요청 결과)
HTTP 요청이 들어올 때마다 실행
hello
HTTP 요청 처리가 끝나고 브라우저에 응답하기 전에 실행
127.0.0.1 - - [27/Nov/2021 15:15:44] "GET /hello HTTP/1.1" 200 -
```
*참고
데코레이터의 특성을 고려하여 위의 예제코드 결과를 분석해볼 것
'Flask' 카테고리의 다른 글
Flask - flask 이해를 위한 파이썬 객체 지향 (0) | 2021.12.01 |
---|---|
Flask - MVC 패턴과 flask blueprint (0) | 2021.11.29 |
Flask - bootstrap·vue(axios)/flask로 REST API 구현 (0) | 2021.11.27 |
Flask - jinja2 template (1) | 2021.11.25 |
Flask - flask로 정적 웹 페이지 지원 (0) | 2021.11.25 |
댓글