Python Flask-Restful POST not taking JSON arguments

后端 未结 4 804
难免孤独
难免孤独 2020-12-23 14:29

I am very new to Flask (& Flask-Restful).

My problem : json arguments for a POST is getting set to NONE (not working).

相关标签:
4条回答
  • 2020-12-23 15:11

    I ran into a similar issue and here is a solution that works for me. let's say your application looks like this:

    from flask import Flask, jsonify
    from flask_restful import Api, Resource, reqparse
    
    app = Flask(__name__)
    api = Api(app)
    
    # Define parser and request args
    parser = reqparse.RequestParser()
    parser.add_argument('last_name', type=str)
    parser.add_argument('first_name', type=str)
    # not the type=dict
    parser.add_argument('personal_data', type=dict)
    
    
    class Item(Resource):
    
        def post(self):
    
            args = parser.parse_args()
    
            ln = args['last_name']
            fn = args['first_name']
            # we can also easily parse nested structures
            age = args['personal_data']['age']
            nn = args['personal_data']['nicknames']
    
            return jsonify(fn=fn, ln=ln, age=age, nn=nn)
    
    
    api.add_resource(Item, '/item')
    
    if __name__ == '__main__':
        app.run(debug=True)
    

    Now, you can easily create some JSON data:

    import json
    
    d = {'last_name': 'smith', 'first_name': 'john', 'personal_data': {'age': 18, 'height': 180, 'nicknames': ['johnny', 'grandmaster']}}
    
    print(json.dumps(d, indent=4))
    
    {
        "last_name": "smith",
        "first_name": "john",
        "personal_data": {
            "age": 18,
            "height": 180,
            "nicknames": [
                "johnny",
                "grandmaster"
            ]
        }
    }
    
    json.dumps(d)
    '{"last_name": "smith", "first_name": "john", "personal_data": {"age": 18, "height": 180, "nicknames": ["johnny", "grandmaster"]}}'
    

    and call the application:

    curl http://localhost:5000/item -d '{"last_name": "smith", "first_name": "john", "personal_data": {"age": 18, "height": 180, "nicknames": ["johnny", "grandmaster"]}}'
    

    This will crash with the error (I shortened the traceback):

    age = args['personal_data']['age']
    TypeError: 'NoneType' object is not subscriptable

    the reason is that the header is not specified. If we add the

    -H "Content-Type: application/json"
    

    and then call

    curl http://localhost:5000/item -H "Content-Type: application/json" -d '{"last_name": "smith", "first_name": "john", "personal_data": {"age": 18, "height": 180, "nicknames": ["johnny", "grandmaster"]}}'
    

    The output looks as expected:

    {
      "age": 18, 
      "fn": "john", 
      "ln": "smith", 
      "nn": [
        "johnny", 
        "grandmaster"
      ]
    }
    

    The function can be also further simplified to:

    class Item(Resource):
    
        def post(self):
    
            json_data = request.get_json()
            # create your response below
    

    as shown above.

    0 讨论(0)
  • 2020-12-23 15:14

    According to the documentation for Request.json and the new Request.get_json, you should have the mimetype on your POST request set to application/json. This is the only way flask will automatically parse your JSON data into the Request.json property which (I believe) is what Flask-Restful depends on to retrieve JSON data.

    NOTE: The newer get_json function has an option to force the parsing of POST data as JSON irrespective of the mimetype

    0 讨论(0)
  • 2020-12-23 15:17

    junnytony's answer gave me a hint, and I went ahead with this approach. get_json seems to have done the trick.

    from flask import Flask, jsonify, request
    from flask_restful import reqparse, abort, Api, Resource
    
    app = Flask(__name__)
    api = Api(app)
    
    #parser = reqparse.RequestParser()
    #parser.add_argument('username', type=unicode, location='json')
    #parser.add_argument('password', type=unicode, location='json')
    
    class HelloWorld(Resource):
        def post(self):
            json_data = request.get_json(force=True)
            un = json_data['username']
            pw = json_data['password']
            #args = parser.parse_args()
            #un = str(args['username'])
            #pw = str(args['password'])
            return jsonify(u=un, p=pw)
    
    api.add_resource(HelloWorld, '/testing')
    
    if __name__ == '__main__':
        app.run(host='0.0.0.0', port=5444 ,debug=True)
    
    0 讨论(0)
  • 2020-12-23 15:18

    After forcing the request to parse json, it worked with me. Here is the code:

    from flask import Flask, jsonify, request
    from flask_restful import reqparse, abort, Api, Resource
    
    app = Flask(__name__)
    api = Api(app)
    
    parser = reqparse.RequestParser()
    parser.add_argument('username', type=str)
    parser.add_argument('password', type=str)
    
    class HelloWorld(Resource):
        def post(self):
            request.get_json(force=True)
            args = parser.parse_args()
            un = str(args['username'])
            pw = str(args['password'])
            return jsonify(u=un, p=pw)
    
    api.add_resource(HelloWorld, '/testing')
    
    if __name__ == '__main__':
        app.run(host='0.0.0.0', port=5444 ,debug=True)
    
    0 讨论(0)
提交回复
热议问题