1. flask框架中request请求
在日常中我们通常会对我们已经做好的端对端对机器学习或者深度学习项目,部署到网页端或者GPU服务器中,具体的模型工程部署的方法有几种,如下:
- 将模型预测直接打包成http api接口
- PMML
- TensorFlow Serving
这里我只介绍第一个,将模型打包成api接口这一种方法
将模型打包成api接口通常需要借助一些web框架,最常用的就是flask框架。
我们部署的方式,就是将模型打包成一个http地址,当我们要去访问这个地址时,我们通过http协议向服务器传递一个request对象,这个request对象就包含了的请求参数,以及请求方式。当模型拿到这个request,就开始模型eval,最后返回请求的结果,通常request返回的结果格式为json。
其中flask request请求方式分为两种POST和GET。
1.1 GET和POST区别
最直观的区别就是GET把参数包含在URL中,POST通过request body传递参数。
- get是获取数据的,而post是提交数据的。
- GET 用于获取信息,是无副作用的,是幂等的,且可缓存, 而POST 用于修改服务器上的数据,有副作用,非幂等,不可缓存。
2. flask request 属性
在Flask的官方文档中是这样介绍request的:对于 Web 应用,与客户端发送给服务器的数据交互至关重要。在 Flask 中由全局的 request 对象来提供这些信息。
从Flask模块导入request:from flask import request
2.1 常用方法使用
这里以一个示例来以此介绍request属性
from flask import Flask,request app=Flask(__name__) @app.route('/login', methods = ['GET','POST']) def login(): if request.method == 'POST': if request.form['username'] == request.form['password']: return 'TRUE' else: #当form中的两个字段内容不一致时,返回我们所需要的测试信息 return str(request.headers) #需要替换的部分 else: return render_template('login.html')
2.1.1 method:请求方法
return request.method #POST • 1
2.1.2 form:返回form的内容
return json.dumps(request.form) #{"username": "123", "password": "1234"}
2.1.3 args和values:args返回请求中的参数,values返回请求中的参数和form
return json.dumps(request.args) #url:http://192.168.1.183:5000/login?a=1&b=2、返回值:{"a": "1", "b": "2"} print(request.args['a']) #输出:1 return str(request.values) #CombinedMultiDict([ImmutableMultiDict([('a', '1'), ('b', '2')]), ImmutableMultiDict([('username', '123'), ('password', '1234')])])
2.1.4 cookies:cookies信息
return str(request.headers) #headers信息 request.headers.get('User-Agent') #获取User-Agent信息
2.1.5 url、path、script_root、base_url、url_root
return 'url: %s , script_root: %s , path: %s , base_url: %s , url_root : %s' % (request.url,request.script_root, request.path,request.base_url,request.url_root) ''' url: http://192.168.1.183:5000/testrequest?a&b , script_root: , path: /testrequest , base_url: http://192.168.1.183:5000/testrequest , url_root : http://192.168.1.183:5000/ '''
2.1.6 date、files:date请求的数据,files上传的文件
@app.route('/upload',methods=['GET','POST']) def upload(): if request.method == 'POST': f = request.files['file'] filename = secure_filename(f.filename) #f.save(os.path.join('app/static',filename)) f.save('app/static/'+str(filename)) return 'ok' else: return render_template('upload.html') #html <!DOCTYPE html> <html> <body> <form action="upload" method="post" enctype="multipart/form-data"> <input type="file" name="file" /><br /> <input type="submit" value="Upload" /> </form> </body> </html>
其中POST与GET区别:
请求方式 | request.args | request.form | request.values |
POST | ☑️ | ☑️ | |
GET | ☑️ | ☑️ |
GET请求方式
get请求的数据是放在QuerySting中的request.args封装的就是get请求的数据 类型为字典
示例:
获取name的值:
request.args["name"] request.args.get("name") request.args.getlist("name_list")
@app.route('/form_do') def form_do(): uname = request.args.get('uname') upwd = request.args.get('upwd') print() return '用户名称:%s,用户密码:%s' % (uname,upwd)
POST请求方式
post请求的数据是放在 form中的request.form封装的就是POST请求的数据 类型为字典
示例:
获取name的值:
request.form["name"] request.form.get("name") request.form.getlist("name_list")
@app.route('/post_do',methods=['POST']) def post_do(): uname=request.form.get('uname') upwd = request.form.get('upwd') uemail = request.form.get('uemail') trueName = request.form.get('trueName') return "姓名:%s,密码:%s,邮件:%s,真实姓名:%s" % (uname,upwd,uemail,trueName)
最后需要知道的是return的返回的值必须为json格式,可以使用函数如下函数进行格式转换
- json.dumps()
- jsonify()
- 先将数据转化为字典,再通过以上二个函数转化
3. flask部署模型api
up主做的都是与计算机视觉有关的,所以传人的参数通常为一个图片,也就是request.files,但是request.files传入的文件参数,不能直接被深度学习模型使用需要转换。
这里实例用到模型是yolov5,通过torch在github下载获取
3.1 加载模型
model = torch.hub.load('ultralytics/yolov5', 'yolov5s', pretrained=True) • 1
3.2 部署模型api
from flask import Flask,request,jsonify app=Flask(__name__) @app.route('/predict',methods=["GET","POST"]) def predict(): if not request.method == "POST": return if request.files.get("image"): image_file = request.files["image"] print(image_file) image_bytes = image_file.read() img = Image.open(io.BytesIO(image_bytes)) results=model(img) return jsonify(results)
3.3 运行api接口
app.run(host="127.0.0.1",port=5005) • 1
3.4 模拟客户端请求request模型
curl -X POST -F image=@1.jpg http://127.0.0.1:5005/predict
详细的curl命令可以参考下面这个链接