我开发了一个用于测试分类的分类器,并尝试通过REST API访问它。以下是代码:
clf_model = joblib.load('MNB_Clf.pkl','r')app = Flask(__name__)@app.route('/spend_api',methods=['POST'])def make_predict(): data = request.get_json(force=True) test_data = pd.read_csv(data) pred_proba_class = clf_model.predict_proba(test_data['ColumnName1']) final_pred_file = pd.DataFrame(pred_proba_class) sub_file = 'output_'+str(datetime.datetime.now().strftime("%Y-%m-%d-%H-%M")) + '.csv' return jsonify(results=final_pred_file.to_csv(sub_file))if __name__ == '__main__': app.run(port = 9000,debug=True)
我尝试使用以下代码将CSV文件发送到API:
url = 'http://localhost:9000/spend_api'files = {'file': ('Test_data_final.csv')}r = request.post(url,files=files)
我遇到了一个运行时错误。您能帮助我解决这个问题吗?
这是错误信息:
RuntimeError Traceback (most recent call last) <ipython-input-15-4b8522aa1eb0> in <module>() 3 url = 'http://localhost:9000/spend_api' 4 files = {'file': ('Test_data_final.csv')} ----> 5 r = request.post(url,files=files) 6 7 C:\Users\pavansubhash_t\AppData\Local\Continuum\Anaconda2\lib\site - packages\werkzeug\local.pyc in __getattr__(self, name) 345 if name == '__members__': 346 return dir(self._get_current_object())--> 347 return getattr(self._get_current_object(), name) 348 349 def __setitem__(self, key, value):C:\Users\pavansubhash_t\AppData\Local\Continuum\Anaconda2\lib\site-packages\werkzeug\local.pyc in _get_current_object(self) 304 """ 305 if not hasattr(self.__local, '__release_local__'):--> 306 return self.__local() 307 try: 308 return getattr(self.__local, self.__name__)C:\Users\pavansubhash_t\AppData\Local\Continuum\Anaconda2\lib\site-packages\flask\globals.pyc in _lookup_req_object(name) 35 top = _request_ctx_stack.top 36 if top is None:---> 37 raise RuntimeError(_request_ctx_err_msg) 38 return getattr(top, name) 39 RuntimeError: Working outside of request context.
这通常意味着您尝试使用需要活动HTTP请求的功能。请查阅有关测试的文档,了解如何避免此问题。
回答:
如果我理解您的需求,您有一个预训练的分类器,希望通过API提供分类服务。您的API接收一个CSV文件作为输入,并返回另一个CSV文件。要重构您的代码以实现这一点,需要进行以下更改。
修复请求中发送文件的方式:
按照以下方式修复将csv文件加载到文件字典中的方法:
url = 'http://localhost:9000/spend_api'files = {'file': open('Test_data_final.csv','rb')}r = request.post(url,files=files)
您可以在SO线程中找到更多详细信息。
修复发送JSON响应的方式
clf_model = joblib.load('MNB_Clf.pkl','r')app = Flask(__name__)@app.route('/spend_api',methods=['POST'])def make_predict(): data = request.get_json(force=True) test_data = pd.read_csv(data) pred_proba_class = clf_model.predict_proba(test_data['ColumnName1']) final_pred_file = pd.DataFrame(pred_proba_class) return jsonify(results=final_pred_file.to_dict(orient="records"))if __name__ == '__main__': app.run(port = 9000,debug=True)
如果您想发送CSV文件而不是JSON
这里是一个独立的工作示例:
from flask import Flask from flask import send_file from StringIO import StringIO import pandas as pd app = Flask("csv")@app.route("/get_csv")def hello(): st = """col1|col2 1|2 3|4 """ df = pd.read_csv(StringIO(st), sep="|") df.to_csv("/tmp/my_test_csv.csv", index=False, sep="|") return send_file("/tmp/my_test_csv.csv")if __name__ == '__main__': app.run(port=5000)
作为旁注,我建议您重新考虑设计,使用JSON而不是CSV文件。