简体   繁体   English

Python Flask-Restful POST不接受JSON参数

[英]Python Flask-Restful POST not taking JSON arguments

I am very new to Flask (& Flask-Restful). 我是Flask(&Flask-Restful)的新手。

My problem : json arguments for a POST is getting set to NONE (not working). 我的问题: POST json参数设置为NONE (不工作)。

I am able to take arguments from the form-data , using POSTMAN plugin for chrome. 我可以从form-data获取参数,使用POSTMAN插件进行chrome。 But, when i switch to raw (& feed a json ), it fails to read the json & assigns a NONE to all my arguments. 但是,当我切换到raw (并提供一个json )时,它无法读取json并为我的所有参数分配NONE

I have read some related stackoverflow posts related to this : link1 , link2 , link3 ... none of these helped me. 我已经阅读了一些与此相关的stackoverflow帖子: link1link2link3 ......这些都没有帮助我。

I am using python-2.6 , Flask-Restful-0.3.3 , Flask-0.10.1 , Chrome , POSTMAN on Oracle Linux 6.5. 我在Oracle Linux 6.5上使用python-2.6Flask-Restful-0.3.3Flask-0.10.1ChromePOSTMAN

Python code app.py : Python代码 app.py

from flask import Flask, jsonify
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):
        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)

Testing this using POSTMAN : 使用POSTMAN 测试

  • Using form-data : works perfectly ! 使用form-data :完美运行!
  • Using raw -> json : causes this issue 使用raw - > json导致此问题

Things tried #1 : 事情尝试#1

Add json parameter to my add_argument() method in app.py 添加json参数我add_argument()的方法app.py

parser = reqparse.RequestParser()
parser.add_argument('username', type=str, location='json') # added json
parser.add_argument('password', type=str, location='json') # added json

Input : { "username": "hello", "password": "world" } Input :{“username”:“hello”,“password”:“world”}

Output : { "p": "None", "u": "None" } Output :{“p”:“无”,“你”:“无”}

Things tried #2 : 事情尝试#2

Change type to unicode in add_argument() method in app.py 改变类型unicodeadd_argument()在方法app.py

parser = reqparse.RequestParser()
parser.add_argument('username', type=unicode, location='json') # change type to unicode
parser.add_argument('password', type=unicode, location='json') # change type to unicode

Input : { "username": "hello", "password": "world" } Input :{“username”:“hello”,“password”:“world”}

Output : { "p": "None", "u": "None" } Output :{“p”:“无”,“你”:“无”}


PS : I will keep updating my question, with every failed attempt. PS:我会不断尝试更新我的问题。 Please let me know if you need any more info to make this question more clear. 如果您需要更多信息以便更清楚地了解此问题,请与我们联系。

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 . 根据Request.json的文档和新的Request.get_json ,您应该将POST请求中的mimetype设置为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. 这是flask将自动将JSON数据解析为Request.json属性的唯一方法,我相信Flask-Restful依赖于它来检索JSON数据。

NOTE: The newer get_json function has an option to force the parsing of POST data as JSON irrespective of the mimetype 注意:较新的get_json函数可以选择强制将POST数据解析为JSON,而不管mimetype

junnytony's answer gave me a hint, and I went ahead with this approach. junnytony的回答给了我一个提示,我继续采用这种方法。 get_json seems to have done the trick. get_json似乎已经完成了这个伎俩。

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)

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: 现在,您可以轻松创建一些JSON数据:

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'] age = args ['personal_data'] ['age']
TypeError: 'NoneType' object is not subscriptable TypeError:'NoneType'对象不可订阅

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 . 如上所示

After forcing the request to parse json, it worked with me. 强制请求解析json后,它与我一起工作。 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)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM