Search code examples
pythonflaskflask-restful

parse_args doesn't seem to understand json arguments


Since I have wiped the VirtualEnv and installed the latest, the unit tests are no longer passing. I am very confused as it seems that Flask Restful doesn't seem to understand incoming json any longer.

self.headers['Content-Type'] = 'application/json'
rv = self.client.post('api/v1.0/ftrecords',
                      headers=self.headers,
                      data=self.events_to_json([event1, event2]))

def events_to_json(self, events):
    lst = []
    for event in events:
        lst.append(self.event_marshal(event))
    return json.dumps({'events': lst})

def event_marshal(self, event):
    evs = marshal(event, self.event_resource_fields)
    evs.update({'event_id': event.key.id()})
    return evs

self.event_resource_fields = {
    'event_id': fields.String,
    'time_of_day': fields.DateTime,
    'rating': fields.Integer,
    'location': fields.String,
    'notes': fields.String,
    'timestamp': fields.Integer,
    'is_deleted': fields.Boolean,
    'is_public': fields.Boolean
}   

The actual API:

class FTEventAPI(Resource):
    def __init__(self):
        super(FTEventAPI, self).__init__()
        self.reqparser = reqparse.RequestParser()
        self.reqparser.add_argument('events', type=list, required=True)

def post(self):
    arguments = self.reqparser.parse_args()
    json_events = arguments.get('events’)

==> expected a list with dictionaries

json_events ==>  Thats wrong.
[u'rating', u'is_deleted', u'event_id', u'timestamp', u'notes', u'time_of_day', u'location', u'is_public’]

    request.json.get('events') ==>  This is correct
[{u'rating': 1, u'is_deleted': None, u'event_id': u'fc1f1a18-5e3a-4e5c-9610-269bc99da9ca', u'timestamp': 1416820073, u'notes': None, u'time_of_day': u'Mon, 24 Nov 2014 09:07:53 -0000', u'location': None, u'is_public': None}, 
{u'rating': 2, u'is_deleted': None, u'event_id': u'74698ff2-8af2-45a2-9e66-d0dff4e9986b', u'timestamp': 1416906473, u'notes': None, u'time_of_day': u'Tue, 25 Nov 2014 09:07:53 -0000', u'location': None, u'is_public': None}]

Solution

  • I am not sure what has changed. But if I add the location parameter, it works:

    self.reqparser.add_argument('events', type=list, location='json', required=True)
    

    This could mean the same as this though:

    request.json.get('events')
    

    I am not sure, how this code worked before, and why it requires out of the sudden the location='json' parameter.