Python Flask-Restful POST 不接受 JSON 参数

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/30491841/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-19 08:31:24  来源:igfitidea点击:

Python Flask-Restful POST not taking JSON arguments

pythonjsonrestflaskflask-restful

提问by sudhishkr

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

我对 Flask(和 Flask-Restful)很陌生。

My problem : jsonarguments for a POSTis getting set to NONE(not working).

我的问题: a 的json参数POST设置为NONE(不工作)。

I am able to take arguments from the form-data, using POSTMANplugin for chrome. But, when i switch to raw(& feed a json), it fails to read the json & assigns a NONEto all my arguments.

我可以form-data使用POSTMANchrome 插件从, 中获取参数。但是,当我切换到raw(& feed a json) 时,它无法读取 json 并将 a 分配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, POSTMANon Oracle Linux 6.5.

我使用python-2.6Flask-Restful-0.3.3Flask-0.10.1ChromePOSTMAN在Oracle的Linux 6.5。

Python codeapp.py:

蟒蛇代码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 thisusing POSTMAN:

使用POSTMAN以下方法测试

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

Things tried #1:

尝试过的事情#1

Add jsonparameter 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:{“用户名”:“你好”,“密码”:“世界”}

Output: { "p": "None", "u": "None" }

Output:{“p”:“无”,“u”:“无”}

Things tried #2:

尝试过的事情#2

Change type to unicodein add_argument()method in app.py

将类型更改为unicodeinadd_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:{“用户名”:“你好”,“密码”:“世界”}

Output: { "p": "None", "u": "None" }

Output:{“p”:“无”,“u”:“无”}



PS :I will keep updating my question, with every failed attempt. Please let me know if you need any more info to make this question more clear.

PS:每次尝试失败时,我都会不断更新我的问题。如果您需要更多信息以使这个问题更清楚,请告诉我。

采纳答案by junnytony

According to the documentation for Request.jsonand 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.jsonproperty which (I believe) is what Flask-Restful depends on to retrieve JSON data.

根据Request.json和新的Request.get_json的文档,您应该将 POST 请求中的 mimetype 设置为application/json。这是flask 将您的JSON 数据自动解析为Request.json属性的唯一方法(我相信)这是Flask-Restful 检索JSON 数据所依赖的属性。

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

注意:较新的get_json函数有一个选项可以强制将 POST 数据解析为 JSON,而不管 mimetype

回答by sudhishkr

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

junnytony 的回答给了我一个提示,我继续采用这种方法。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)

回答by Cleb

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']
TypeError: 'NoneType' object is not subscriptable

age = args['personal_data']['age']
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.

如上图所示

回答by moutaz samir

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

强制请求解析 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=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)