背景
Flask搭建一个服务,返回结果如果不用string包一下res,就报错,服务不返回内容。代码片段:
labels = []
for i in range(len(ctx.score)):
one_dict = {}
one_dict['label'] = ctx.label[i]
one_dict['score'] = ctx.score[i]
one_dict['description'] = ctx.description[i]
labels.append(one_dict)
res['labels'] = str(labels)
if detail == '1':
res['detail'] = str(ctx.scores)
if request.json:
params = request.json
logger.error("bad json format" + params['text'])
return Response(json.dumps(res))
输出如下,value是string的形式,这种不能解析为json格式,线上使用的时候不容易解析:
{'labels': "[{'label': 0, 'score': 0.2620824873447418, 'description': '大厂求职'}, {'label': 2, 'score': 0.1379653662443161, 'description': '单身交友'}, {'label': 15, 'score': 0.12444800138473511, 'description': '其他'}]", 'detail': '[0.2620824873447418, 0.07963509112596512, 0.1379653662443161, 0.07759057730436325, 0.048343781381845474, 0.057344596832990646, 0.04375828802585602, 0.029765404760837555, 0.037037044763565063, 0.02573602832853794, 0.03256792947649956, 0.013453250750899315, 0.006017305422574282, 0.01480005495250225, 0.009454798884689808, 0.12444800138473511]'}
希望的输出能解析为json标准格式,如下:
{'labels': [{'label': '0', 'score': 0.2620824873447418, 'description': '大厂求职'}, {'label': '2', 'score': 0.1379653662443161, 'description': '单身交友'}, {'label': '15', 'score': 0.12444800138473511, 'description': '其他'}], 'detail': [0.2620824873447418, 0.07963509112596512, 0.1379653662443161, 0.07759057730436325, 0.048343781381845474, 0.057344596832990646, 0.04375828802585602, 0.029765404760837555, 0.037037044763565063, 0.02573602832853794, 0.03256792947649956, 0.013453250750899315, 0.006017305422574282, 0.01480005495250225, 0.009454798884689808, 0.12444800138473511]}
解决方案
将返回结果改为希望的格式,如下,看看报什么错,去看日志
labels = []
for i in range(len(ctx.score)):
one_dict = {}
one_dict['label'] = ctx.label[i]
one_dict['score'] = ctx.score[i]
one_dict['description'] = ctx.description[i]
labels.append(one_dict)
res['labels'] = labels
if detail == '1':
res['detail'] = ctx.scores
if request.json:
params = request.json
logger.error("bad json format" + params['text'])
return Response(json.dumps(res))
服务调用方式:
import requests,json
if __name__ == '__main__':
headers = {'content-type': 'application/json'}
pred_data = {'text': '美团已经进入三面了,有点紧张', 'detail': '1'}
r = requests.post("http://newf:5993/bert/g_classify", data=json.dumps(pred_data), headers=headers)
print(r.json())
print(r.content)
此时打印下res返回形式,是我们希望的json格式,但是服务返回为空{},打印了一下r.content的内容:500 Internal Server Error,说是服务中断。
b'<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">\n<title>500 Internal Server Error</title>\n<h1>Internal Server Error</h1>\n<p>The server encountered an internal error and was unable to complete your request. Either the server is overloaded or there is an error in the application.</p>\n'
再去看下日志:
Traceback (most recent call last):
File "/Users/wang/anaconda3/envs/torch_20201223/lib/python3.6/site-packages/flask/app.py", line 2447, in wsgi_app
response = self.full_dispatch_request()
File "/Users/wang/anaconda3/envs/torch_20201223/lib/python3.6/site-packages/flask/app.py", line 1952, in full_dispatch_request
rv = self.handle_user_exception(e)
File "/Users/wang/anaconda3/envs/torch_20201223/lib/python3.6/site-packages/flask/app.py", line 1821, in handle_user_exception
reraise(exc_type, exc_value, tb)
File "/Users/wang/anaconda3/envs/torch_20201223/lib/python3.6/site-packages/flask/_compat.py", line 39, in reraise
raise value
File "/Users/wang/anaconda3/envs/torch_20201223/lib/python3.6/site-packages/flask/app.py", line 1950, in full_dispatch_request
rv = self.dispatch_request()
File "/Users/wang/anaconda3/envs/torch_20201223/lib/python3.6/site-packages/flask/app.py", line 1936, in dispatch_request
return self.view_functions[rule.endpoint](**req.view_args)
File "/Users/wang/bigdata/feedrec/bert_gossip_cls_server/run.py", line 121, in channel_classify
return Response(json.dumps(res))
File "/Users/wang/anaconda3/envs/torch_20201223/lib/python3.6/json/__init__.py", line 231, in dumps
return _default_encoder.encode(obj)
File "/Users/wang/anaconda3/envs/torch_20201223/lib/python3.6/json/encoder.py", line 199, in encode
chunks = self.iterencode(o, _one_shot=True)
File "/Users/wang/anaconda3/envs/torch_20201223/lib/python3.6/json/encoder.py", line 257, in iterencode
return _iterencode(o, 0)
File "/Users/wang/anaconda3/envs/torch_20201223/lib/python3.6/json/encoder.py", line 180, in default
o.__class__.__name__)
TypeError: Object of type 'int64' is not JSON serializable
[2021-04-01 11:31:56,497] [27312] [INFO] - _internal._log (_internal.py:113) - 127.0.0.1 - - [01/Apr/2021 11:31:56] "[35m[1mPOST /bert/g_classify HTTP/1.1[0m" 500 -
重点:返回的结果中有一个int64不能被json序列化。所以去看看res中有哪些是int64的,把它改为int32或者直接string,这样就解决。
TypeError: Object of type 'int64' is not JSON serializable
我的代码中,label是int64的,将其改为str,再返回res时,成功返回。
one_dict['label'] = str(ctx.label[i])
参考:
1.在flask中使用jsonify和json.dumps的区别:https://blog.csdn.net/Duke_Huan_of_Qi/article/details/76064225