好久没用python,第一次实际使用python开发web微服务,选择很早之前试验过的flask框架。
故把flask使用中的所有问题记录下来。
flask 并发访问
默认应该是任何一个web框架都支持并发路由的。但flask默认不支持,即如不做配置,并发访问多个接口会阻塞(笔者亲测)。
当然但开启并发访问的方法也很简单:
if __name__ == '__main__':
app.run(host='127.0.0.1', port=5000, threaded=True)
这样就开启了并发访问
拦截器(同理过滤器)
flask支持拦截器的方法十分智能。只需要自定义annotation即可。
def require_login(f):
def decorated_function(*args, **kwargs):
if 'ticket' in request.args:
valid = request.args['ticket']
if valid:
o = urlparse(request.url)
return redirect('{}://{}{}'.format(o.scheme, o.netloc, o.path))
else:
return redirect('/')
if 'user' not in session:
return redirect_to_sso()
return f(*args, **kwargs)
return decorated_function
这样就定义了一个拦截器。
将它放在需要被拦截的接口上面:
@app.route("/get_result")
@require_login
def get_result():
特别注意的是@require_login声明在路由@app.route(“/get_result”)的下面,表示@require_login拦截器最先被调用。上下的先后顺序是有区别的。
日志
python中日志的定义可以使用配置文件。
简单如下配置,就可以实现日志了:
logging.config.fileConfig("conf/logging.conf")
logger = logging.getLogger("project")
logger.info("hello world")
配置文件logging.conf如下:
[loggers]
keys=root,project
[handlers]
keys=consoleHandler,fileHandler,rotatingFileHandler
[formatters]
keys=simpleFmt
[logger_root]
level=DEBUG
handlers=rotatingFileHandler
[logger_bubuji]
level=DEBUG
handlers=rotatingFileHandler
qualname=bubuji
propagate=0
[handler_consoleHandler]
class=StreamHandler
level=DEBUG
formatter=simpleFmt
args=(sys.stdout,)
[handler_fileHandler]
class=FileHandler
level=DEBUG
formatter=simpleFmt
args=("log/logging.log", "a")
[handler_rotatingFileHandler]
class=handlers.RotatingFileHandler
level=DEBUG
formatter=simpleFmt
args=("log/logging.log", "a", 20*1024*1024, 10)
[formatter_simpleFmt]
format=%(asctime)s - %(name)s - %(levelname)s - %(message)s - [%(filename)s:%(lineno)s]
datefmt=
需要注意的是,如此配置的日志只会写入文件,而不会再打印到屏幕上了,若在开发时需要将日志同时打印到屏幕上,还需要配置如下:
logging.config.fileConfig("conf/logging.conf")
logger = logging.getLogger("project")
console_handler = logging.StreamHandler()
console_handler.setLevel(logging.DEBUG)
formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s - [%(filename)s:%(lineno)s]')
console_handler.setFormatter(formatter)
logger.addHandler(console_handler)
logger.info("hello world") #该消息会被同时写入日志文件和打印到屏幕中
异常
日志和异常都是在实际开发中常被无视的模块。
flask中使用@app.errorhandler()注释实现自定义异常。
被@app.errorhandler()注释的方法将捕获指定的异常,并做处理。