Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Flask JSON request is None

Tags:

python

json

flask

I'm working on my first Flask app (version 0.10.1), and also my first Python (version 3.5) app. One of its pieces needs to work like this:

  1. Submit a form
  2. Run a Celery task (which makes some third-party API calls)
  3. When the Celery task's API calls complete, send a JSON post to another URL in the app
  4. Get that JSON data and update a database record with it

Here's the relevant part of the Celery task:

if not response['errors']: # response comes from the Salesforce API call
    # do something to notify that the task was finished successfully
    message = {'flask_id' : flask_id, 'sf_id' : response['id']}
    message = json.dumps(message)
    print('call endpoint now and update it')
    res = requests.post('http://0.0.0.0:5000/transaction_result/', json=message)

And here's the endpoint it calls:

@app.route('/transaction_result/', methods=['POST'])
def transaction_result():
    result = jsonify(request.get_json(force=True))
    print(result.flask_id)
    return result.flask_id

So far I'm just trying to get the data and print the ID, and I'll worry about the database after that.

The error I get though is this: requests.exceptions.ConnectionError: None: Max retries exceeded with url: /transaction_result/ (Caused by None)

My reading indicates that my data might not be coming over as JSON, hence the Force=True on the result, but even this doesn't seem to work. I've also tried doing the same request in CocoaRestClient, with a Content-Type header of application/json, and I get the same result.

Because both of these attempts break, I can't tell if my issue is in the request or in the attempt to parse the response.

like image 511
Jonathan Stegall Avatar asked Jan 15 '16 16:01

Jonathan Stegall


People also ask

How do I return a JSON response from flask?

Flask has a utility called jsonify () that makes it more convenient to return JSON responses from flask import Flask, jsonify app = Flask (__name__) @app.route ('/api/get-json') def hello (): return jsonify (hello='world') # Returns HTTP Response with {"hello": "world"}

How to parse JSON data from an HTTP request?

If the mimetype of the HTTP request is application/json, calling request.get_json () will return the parsed JSON data (otherwise it returns None) The parameter -H 'Content-Type: application/json' specifies that this is a JSON request:

How to get flask_ID from jsonify?

First of all request.get_json (force=True) returns an object (or None if silent=True ). jsonify converts objects to JSON strings. You're trying to access str_val .flask_id. It's impossible. However, even after removing redundant jsonify call, you'll have to change result.flask_id to result ['flask_id'].

How to serve REST API from flask?

A working REST API can be served up in seconds through a few lines of code: from flask import Flask, request app = Flask (__name__) @app.route ('/') def hello(): return 'Hello!' if __name__ == "__main__" : app.run () The backbone of the modern web is the HTTP protocol - which sends requests and delivers responses back.


1 Answers

First of all request.get_json(force=True) returns an object (or None if silent=True). jsonify converts objects to JSON strings. You're trying to access str_val.flask_id. It's impossible. However, even after removing redundant jsonify call, you'll have to change result.flask_id to result['flask_id'].

So, eventually the code should look like this:

@app.route('/transaction_result/', methods=['POST'])
def transaction_result():
    result = request.get_json()
    return result['flask_id']

And you are absolutely right when you're using REST client to test the route. It crucially simplifies testing process by reducing involved parts. One well-known problem during sending requests from a flask app to the same app is running this app under development server with only one thread. In such case a request will always be blocked by an internal request because the current thread is serving the outermost request and cannot handle the internal one. However, since you are sending a request from the Celery task, it's not likely your scenario.

UPD: Finally, the last one reason was an IP address 0.0.0.0. Changing it to the real one solved the problem.

like image 171
Ivan Velichko Avatar answered Oct 07 '22 08:10

Ivan Velichko