halloleo halloleo - 4 months ago 23
JSON Question

How to force a flask-restful app to interpret the post body as json regardsless of the request's mime-type

I have a python

flask-restful
app which receives json in the post body. Here the two minimal files
app.py
and
info.py
:

The application module
app.py
:


from flask import Flask
from flask_restful import Resource, Api, reqparse

flaskApp = Flask(__name__)
api = Api(flaskApp)

from endpoints.info import Info

api.add_resource(Infp, '/v1/info')


The endpoint module
info.py
(in subfolder
endpoints
):


from flask_restful import Resource, reqparse

myParser = reqparse.RequestParser()
reqparse.RequestParser.
myParser.add_argument('argA', location='json')
myParser.add_argument('argB', location='json')


class Info(Resource):

def post(self):
args = myParser.parse_args()
return args


This app works correct when I send a request as mime type
application/json
:

curl -s "http://127.0.0.1:5000/v1/info" -d '{"locality":"Barton"}' -H Content-Type:application/json


returns as expected:

{
"locality": "Barton"
}


However the client will send the requests as the normal url-encoded mimetype. When I just do

curl -s "http://127.0.0.1:5000/v1/info" -d '{"locality":"Barton"}'


the app returns
{}
So it did not interpret the body as intended.

How can I force the app to interpret the post body as json regardsless of the request's mime-type?

I know about this StackOverflow question; it suggests using
Request.get_json
. But how can I access this method in the
Resource
class
Info
to feed it into
myParser
?

Answer

According to the flask-restful docs, the location keyword argument of add_argument indicates a property of flask.Request from which to pull the argument.

According to the Flask docs, the json property will be empty if the mimetype of the request is not application/json.

But if you use Request.get_json(force=True) directly, you don't need the parser. You can just access the value:

from flask import request
class Info(Resource):
    def post(self):
        data = request.get_json(force=True)
        return data['locality']