How to parse the POST argument to a REST service?
I ended up raising this as an issue on flask-resful github and got this solution, which works for me. Credit goes to Doug Black.
reqparse doesn't really know how to handle JSON. To deal with JSON posts, you'll want to use the flask.request.json dict.
Here's an updated example for what you probably want:
from flask import Flask, request
from flask.ext import restful
class Records(restful.Resource):
def post(self, email, password, last_sync_date):
records = request.json['records']
return records, 201
app = Flask(__name__)
api = restful.Api(app)
api.add_resource(
Records,
'/rest/records/<string:email>/<string:password>/<string:last_sync_date>'
)
The docs on request.json are here.
You'll need to make sure you post with the content type header set to application/json so flask knows to populate the json dictionary.
self.app.post(
'/rest/records/{0}/{1}/{2}'.format(email, password, sync_date),
data=json.dumps(records),
headers={'Content-Type': 'application/json'
)
Houman
I'm a thinker and a dreamer. Love pets but don't have any. I'm a passionate tech entrepreneur.
Updated on July 26, 2022Comments
-
Houman almost 2 years
It seems I have another JSON problem, this time when posting to the REST service. I am using
Flask-Restful
.api.add_resource(Records, '/rest/records/<string:email>/<string:password>/<string:last_sync_date>') parser = reqparse.RequestParser() parser.add_argument('record_date', type=str) parser.add_argument('records', type=str) parser.add_argument('rating', type=str) parser.add_argument('notes', type=str) class Records(Resource): def post(self, email, password, last_sync_date): args = parser.parse_args() records = args['records'] # 'records' = None, but why? return records, 201
Unit test:
resource_fields = { 'record_date': fields.String, 'rating': fields.Integer, 'notes': fields.String, 'last_updated': fields.DateTime, } records = {"records":[]} records["records"].append(marshal(record1, resource_fields)) rv = self.app.post('/rest/records/{0}/{1}/{2}'.format(email, password, sync_date), data=json.dumps(records))
json.dumps(records) is:
str: {"records": [{"rating": 1, "notes": null, "last_updated": "Tue, 15 Oct 2013 15:52:44 -0000", "record_date": "2013-10-15 15:52:44.746815"}]}
Why is
args['records']
None, where I am clearly sending it over the wire?UPDATE:
Strange part is when I send a single object, its all dandy. So strange:
record = dict(record_date=record1.record_date, rating=record1.rating, notes=record1.notes, last_updated=record1.last_updated) rv = self.app.post('/rest/records/{0}/{1}/{2}'.format(email, password, sync_date), data=record)
args:
{'records': None, 'notes': None, 'task': None, 'record_date': '2013-10-15 16:48:40.662744', 'rating': '1'}
-
kralyk over 8 yearsYes, this works, the unpleasant thing is that you need to check that the json dict is not
None
.