1. Handling Errors in Flask¶
Error Handling with errorhandler
¶
- Use
@app.errorhandler
to define custom pages for HTTP error codes. - If no error code is passed as the second argument of
return
, the server defaults to a200
success response.
In [ ]:
# Error Hanlder Example Code
from flask import Flask
import requests
app = Flask(__name__)
# Handle requests for non-existent pages (404 error)
@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="5555")
2. Logging in Flask¶
2.1. Why Use Logging?¶
- Servers operate 24/7, so logging helps identify issues when problems occur.
- Logging can monitor user activity, detect hacking attempts, and handle various operational challenges.
- While logging is not essential during development, it becomes crucial during deployment.
Note: Logging is primarily for production, so this section provides a brief overview. Further implementation can be done during deployment.
2.2. Using Python's logging
Library¶
- Python provides the
logging
library for managing logs. - Logging has levels that allow restricting the output of logs.
- DEBUG > INFO > WARNING > ERROR > CRITICAL
In [ ]:
# Logging Example Code
import logging
# Write logs to a file
logging.basicConfig(filename='test.log', level=logging.DEBUG)
# Log messages based on their levels
logging.debug("debug")
logging.info("info")
logging.warning("warning")
logging.error("error")
logging.critical("critical")
2.2. Flask with Logging¶
- Flask integrates with Python's
logging
library to support advanced logging handlers. - Common Logging Handlers:
- FileHandler: Saves logs to a file.
- RotatingFileHandler: Saves logs to multiple files with a maximum size for each file.
- Example:
maxBytes=2000
,backupCount=10
creates 10 files, each up to 2000 bytes.
- Example:
- SysLogHandler: Logs to Unix-based system logs.
- NTEventLogHandler: Logs to Windows event logs.
Tip: Use
RotatingFileHandler
to avoid filling up disk space with log files.
If you're testing in Jupyter Notebook, note that logging configurations may not behave as expected. For instance, setting the logging level to debug might still record only warnings and above. This is due to how Jupyter handles logging internally. Therefore,
it's recommended to test
logging configurations using astandalone Python script
liketest_logging.py
instead of in Jupyter Notebook.
In [ ]:
# Logging with Flask Production Example Code
from flask import Flask
import datetime
app = Flask(__name__)
# Set debug mode to False for production
app.debug = False
if not app.debug:
import logging
# Specify the logging handler to use
from logging.handlers import RotatingFileHandler
file_handler = RotatingFileHandler('server.log', maxBytes=2000, backupCount=10)
# Define the logging level
app.logger.level = logging.INFO
# Register the handler with app.logger to enable logging
app.logger.addHandler(file_handler)
@app.route('/')
def home():
time_now = datetime.datetime.now()
time_now = time_now.strftime("%Y-%m-%d %H:%M:%S")
app.logger.debug(f'{time_now} :: [Debug]Home Page !!')
app.logger.info(f'{time_now} :: [Info]Home Page !!')
app.logger.warning(f'{time_now} :: [Warning]Home Page !!')
app.logger.error(f'{time_now} :: [Error]Home Page !!')
app.logger.critical(f'{time_now} :: [Critical]Home Page !!')
return "<h1>home</h1>"
@app.errorhandler(404)
def page_not_found(error):
app.logger.error(error)
return "<h1>404 Error</h1>", 404
if __name__ == "__main__":
app.run(host="0.0.0.0", port="5555", debug=False)
3. Using Flask Decorators for Advanced Functionality¶
3.1. Available Decorators¶
@before_request
:- Executes before every HTTP request.
- Cannot accept arguments.
@after_request
:- Executes after the HTTP request is processed but before the response is sent.
- Must accept the
response
object as an argument and return it.
@before_first_request
:- Executes only once before the first HTTP request after the server starts.
In [ ]:
# Before and After Decorator Example Code
from flask import Flask
app = Flask(__name__)
# Track if the first request is processed
initialized = False
# Function to execute only before the first request
def before_first_request():
print("Executed before the first HTTP request after server start.")
# Function to execute before every request
@app.before_request
def before_request():
global initialized
if not initialized:
before_first_request()
initialized = True
return
print("Executed before every HTTP request.")
# Function to execute after every request
@app.after_request
def after_request(response):
print("Executed after every HTTP request, before the response is sent.")
return response
@app.route("/")
def index():
return "<h1>Home!</h1>"
@app.route("/hello")
def hello():
return "<h1>Hello Flask!</h1>"
if __name__ == "__main__":
app.run(host="0.0.0.0", port=5555)