Je suis très nouveau à Flask (& Flask-Restful).
Mon problème: les arguments json
pour une POST
sont définis à NONE
(ne fonctionne pas).
Je suis capable de prendre des arguments à partir du form-data
, en utilisant le plugin POSTMAN
pour chrome. Mais, lorsque je passe à raw
(& feed a json
), il ne parvient pas à lire le json & assigne une NONE
à tous mes arguments.
J'ai lu des articles liés à stackoverflow liés à ceci: link1 , link2 , link3 ... aucun de ceux-ci ne m'a aidé.
J'utilise python-2.6
, Flask-Restful-0.3.3
, Flask-0.10.1
, Chrome
, POSTMAN
sur Oracle Linux 6.5.
Code Pythonapp.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 __== '__main__':
app.run(Host='0.0.0.0', port=5444 ,debug=True)
Test this en utilisant POSTMAN
:
form-data
: fonctionne parfaitement!raw
-> json
: cause ce problèmeLes choses essayées # 1:
Ajoutez le paramètre json
à ma méthode add_argument()
dans 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
: {"nom d'utilisateur": "bonjour", "mot de passe": "monde"}
Output
: {"p": "Aucun", "u": "Aucun"}
Les choses essayées # 2:
Remplacez le type par unicode
dans la méthode add_argument()
dans 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
: {"nom d'utilisateur": "bonjour", "mot de passe": "monde"}
Output
: {"p": "Aucun", "u": "Aucun"}
PS: Je continuerai à mettre à jour ma question à chaque tentative infructueuse. S'il vous plaît laissez-moi savoir si vous avez besoin de plus d'informations pour rendre cette question plus claire.
Selon la documentation de Request.json et le nouveau Request.get_json , le type MIME de votre demande POST doit être défini sur application/json
. C’est la seule façon pour flask d’analyser automatiquement vos données JSON dans la propriété Request.json
qui (je crois) est ce dont dépend Flask-Restful pour récupérer les données JSON.
REMARQUE: La nouvelle fonction get_json
dispose d'une option permettant de forcer l'analyse des données POST au format JSON, quel que soit le type de mim
la réponse de junnytony m'a donné un indice et je suis allé de l'avant avec cette approche. get_json
semble avoir fait le tour.
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 __== '__main__':
app.run(Host='0.0.0.0', port=5444 ,debug=True)
J'ai rencontré un problème similaire et voici une solution qui fonctionne pour moi. Disons que votre application ressemble à ceci:
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 __== '__main__':
app.run(debug=True)
Maintenant, vous pouvez facilement créer des données 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"]}}'
et appelez l'application:
curl http://localhost:5000/item -d '{"last_name": "smith", "first_name": "john", "personal_data": {"age": 18, "height": 180, "nicknames": ["johnny", "grandmaster"]}}'
Cela va planter avec l'erreur (j'ai raccourci le retraçage):
age = args ['personal_data'] ['age']
TypeError: l'objet 'NoneType' n'est pas souscriptable
la raison en est que l'en-tête n'est pas spécifié. Si on ajoute le
-H "Content-Type: application/json"
et ensuite appeler
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"]}}'
La sortie ressemble comme prévu:
{
"age": 18,
"fn": "john",
"ln": "smith",
"nn": [
"johnny",
"grandmaster"
]
}
La fonction peut également être simplifiée pour:
class Item(Resource):
def post(self):
json_data = request.get_json()
# create your response below
comme montré ci-dessus .