问题提出
最近遇到个需求,需要将doc/docx/pdf/xls等格式的文件发送到服务器,交给程序去解析。所以很自然地想到了使用flask。但之前我没有用flask传输过文件,所以这里经过了一些调研和尝试后,找到了一种很方便的方法,在这里分享一下
由于我们一方需要发送文件,另一方需要接收文件,所以这个解决方案中需要包括两部分——
- 请求端POST文件到服务器;
- 服务器端接收并解析收到的文件。
问题解决
请求端发送文件
请求端发送文件,是使用requests执行的。发送的文件,实际上发送的应该是该文件的二进制iostream。最终按照flask的接口要求,将之打包成一个Python-dict。具体操作见code:
import requests
data = {'file': open('/path-to-your-file/test.doc', 'rb')}
rr = requests.post('http://xxx.xx.xxx.x:40000/convert', files=data)
如以上code,服务的端口是40000。具体要传送的数据,feed到request.post的``files``参数上
服务器端接收并解析文件
服务器端接收文件,使用flask执行的。对于发送过来的文件,我们直接使用file.save("your-path")方法存储,然后再从存储的路径下,按照程序需要读取或者使用,完成本次文件的解析操作。具体见code:
from run_oa_con import extract_single
from flask import Flask,request
import json, os
app = Flask(__name__)
@app.route('/convert', methods=['POST'])
def convert():
ff = request.files['file'] # 获取二进制文件流。注意,'file'这个参数,来自于请求端POST时的dict的key的取值
save_path = './your-save-path/' # 文件的存储地址
ff.save(os.path.join(save_path, ff.filename)) # 直接调用flask提供的save()函数,将文件存到指定路径
try:
dic, state = extract_single(os.path.join(save_path, ff.filename))
except Exception as e:
print(e)
dic, state = {}, 0
res = json.dumps({'data':dic, 'success': state}, ensure_ascii=False)
return res
if __name__ == '__main__':
app.run(port=40000, host='0.0.0.0') # 加上`host='0.0.0.0'`,即可以让你的服务监听所有公网ip,而不是只有本地请求才能访问
如上,关键代码只有convert()函数的前三行,整体过程清晰简单