2

I've developed a classifier for test classification. and trying to access it using REST API. Here is the code:

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)

I am trying to send the CSV file to the api using the below code:

url = 'http://localhost:9000/spend_api'
files = {'file': ('Test_data_final.csv')}
r = request.post(url,files=files)

I am getting a Runtime Error. Could you please help how to resolve the issue.

Here is the error:

  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.

This typically means that you attempted to use functionality that needed an active HTTP request. Consult the documentation on testing for information about how to avoid this problem.

9
  • Please post complete error output. Also try to reduce your code to a minimal, complete, and verifiable example. Commented Jul 22, 2017 at 8:45
  • @Christoph Edited the code as suggested. Please suggest how can I resolve the issue Commented Jul 22, 2017 at 9:12
  • @pavansubhash please share a minum reproducible example. I think you lost the identation when you pasted to SO. If not, start fixing that, The definition of the post request handler function make_predict is not clear. Commented Jul 22, 2017 at 9:19
  • @MedAli Is it fine now ? My apologies for the inappropriate identation Commented Jul 22, 2017 at 9:32
  • If you could add print after each step, it might help understanding the problem. Otherwise, there is a problem in this line: return jsonify(results=final_pred_file.to_csv(sub_file)). You can't jsonfiy a CSV file. The to_csv operation is going to send None, its role is to write to a file in the disk where you are executing your code. If you want to send a JSON, you should use final_pred_file.to_dict(orient="records") Commented Jul 22, 2017 at 9:49

1 Answer 1

1

If I understand well your requirement, you have a pre-trained classifier and you want to serve classification over an API. Your API receives a CSV file as input and sends back another CSV file. To refactor your code to do that, you need to add the follow changes.

Fix how you are sending the file in a request:

Fix the way you are loading the csv file into the files dictionary as follows:

url = 'http://localhost:9000/spend_api'
files = {'file': open('Test_data_final.csv','rb')}
r = request.post(url,files=files)

you can find more details in this SO thread.

Fix how to send the json response

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)

If you want to send a CSV file instead

here is a standalone working example:

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)

As a side note, I suggest that you rethink your design to use JSON instead.

Sign up to request clarification or add additional context in comments.

2 Comments

As I mentioned in the previous comment, now I am getting a ConnectionError: ConnectionError: ('Connection aborted.', error(10054, 'An existing connection was forcibly closed by the remote host'))
@pavansubhash your example doesn't reproduce the error. Unless you share a minimum example that I can run on my machine and exactly your error, I can't help you much. In the answer, I tried to give enough information in order to help fix the visible issue. Now, it's up to you.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.