flask-compress 插件可以使用gzip算法压缩flask服务返回的响应数据,压缩后,数据的体积更小,网络传播速度更快,如果你的服务返回的数据体积比较大,使用flask-compress将极大提高网络传输的效率,却并不用付出太多的cpu投入。
安装方法
pip install flask-compress
为了更好的展示flask-compress 的作用,我先不使用这个插件返回一个体积比较大的数据
from flask import Flask, jsonify
from flask_compress import Compress
app = Flask(__name__)
# Compress(app)
@app.route('/json')
def get_json_data():
data = {
'name': '小明',
'age': 14
}
lst = []
for i in range(1000):
lst.append(data)
return jsonify(lst)
if __name__ == '__main__':
app.run(port=5500)
启动服务后在浏览器里访问 http://127.0.0.1:5500/json , 服务端返回的数据大小为33002 字节,接下来,打开注释掉的Compress(app) 这一行代码,对返回数据进行gzip压缩, 重启服务,在浏览器里再次访问前面的地址,通过开发者工具可以查看压缩后服务端返回的数据只有49字节。
之所以有这么大的压缩比,是因为构造的数据很适合压缩,列表里的数据每一项都是相同的,才会有这么搞的压缩比,这只是认为构造的个例。
COMPRESS_REGISTER 参数默认为True, 表示对所有视图返回的数据进行压缩,如果你不希望如此,可以将它设置为False,然后只在自己希望压缩的视图上进行注册
from flask import Flask, jsonify
from flask_compress import Compress
app = Flask(__name__)
app.config['COMPRESS_REGISTER'] = False
compress = Compress(app)
@app.route('/json')
@compress.compressed()
def get_json_data():
data = {
'name': '小明',
'age': 14
}
lst = []
for i in range(1000):
lst.append(data)
return jsonify(lst)
if __name__ == '__main__':
app.run(port=5500)
COMPRESS_MIMETYPES 规定了对那些类型的返回数据进行压缩,默认的范围是
['text/html', 'text/css', 'text/xml',
'application/json',
'application/javascript']
response 的content-type如果不在这些类型中,则不会进行压缩。
这个参数默认值是500字节,如果返回数据的大小没有超过这个数值则不会进行gzip压缩,gzip压缩会消耗服务器的性能,如果数据量太小,就没有必要进行压缩。
其他的参数,可以参考其源码进行设置。
flask 的插件都有着相同的构建方法,使用他们时,你写的代码都类似于下面的样子
app = Flask(__name__)
app.config['COMPRESS_REGISTER'] = False
compress = Compress(app)
来看一下Compress 的初始化函数
def __init__(self, app=None):
self.app = app
if app is not None:
self.init_app(app)
继续追踪阅读init_app 方法,你就能够找到事情的真相
def init_app(self, app):
defaults = [
('COMPRESS_MIMETYPES', ['text/html', 'text/css', 'text/xml',
'application/json',
'application/javascript']),
('COMPRESS_LEVEL', 6),
('COMPRESS_BR_LEVEL', 4),
('COMPRESS_BR_MODE', 0),
('COMPRESS_BR_WINDOW', 22),
('COMPRESS_BR_BLOCK', 0),
('COMPRESS_DEFLATE_LEVEL', -1),
('COMPRESS_MIN_SIZE', 500),
('COMPRESS_CACHE_KEY', None),
('COMPRESS_CACHE_BACKEND', None),
('COMPRESS_REGISTER', True),
('COMPRESS_ALGORITHM', ['br', 'gzip', 'deflate']),
]
for k, v in defaults:
app.config.setdefault(k, v)
backend = app.config['COMPRESS_CACHE_BACKEND']
self.cache = backend() if backend else None
self.cache_key = app.config['COMPRESS_CACHE_KEY']
algo = app.config['COMPRESS_ALGORITHM']
if isinstance(algo, str):
self.enabled_algorithms = [i.strip() for i in algo.split(',')]
else:
self.enabled_algorithms = list(algo)
if (app.config['COMPRESS_REGISTER'] and
app.config['COMPRESS_MIMETYPES']):
app.after_request(self.after_request)
看最后一行代码
app.after_request(self.after_request)
在flask-compress 内部,利用app的after_request方法为flask服务注册了一个钩子,当请求结束时就会执行Comporess 的after_request 方法,其他的flask插件的实现原理大体也是如此。
QQ交流群: 211426309