Search code examples
pythonflaskflask-restplus

How do you pass default values to payload in flask-restplus?


I am setting up an restplus API, and want some default fields to be passed if the query don't contain these values. How do i pass these using an api model, preferably without the use of requestParser?

As it stands now, the payload doesn't get affected by setting default values, thus making it unnecessary. I have tried making the arguments required, but that is of no use since i want to be able to pass only parts of the expected payload.

from flask import Flask, request
from flask_restplus import Api, Resource, fields

app = Flask(__name__)
api = Api(app=app)
model = api.model("simple_model", {'some_bool': fields.Boolean(required=False, default=False),
                                   'some_int': fields.Integer(required=False, default=99)})


@api.route('/foo')
class SomeClass(Resource):

    @api.expect(model)
    def post(self):
        return request.json


if __name__ == '__main__':
    app.run(host='localhost', port=8000, threaded=False, debug=True)

Testing with the code

import requests

query = {"some_bool": True, "some_int": 20}
res = requests.post("http://localhost:8000/foo", json=query)
print(res.json())

query = {"some_bool": True}
res = requests.post("http://localhost:8000/foo", json=query)
print(res.json())

query = {"some_int": 20}
res = requests.post("http://localhost:8000/foo", json=query)
print(res.json())

res = requests.post("http://localhost:8000/foo")
print(res.json())

This gives the output

{'some_bool': True, 'some_int': 20}

{'some_bool': True}

{'some_int': 20}
None

The expected value, and the desired output is

{'some_bool': True, 'some_int': 20}

{'some_bool': True, 'some_int': 99}

{'some_bool': False, 'some_int': 20}

{'some_bool': False, 'some_int': 99}

All help is appreciated.

EDIT:

After the answer by @IMCoins, Iended up writing a function that made me able to acces the items inside the function like this

def get_content(api_model):
   @marshal_with(api_model)
   def get_request():
      return request.json
   return get_request()

and then just accessing the content inside as

content = get_content(model)

Solution

  • As far as I understand it, if you want to make sure you have all the keys you need at entry point, you need to use RequestParser(). api.expect() decorator is used to document the swagger.

    However, if you want to make sure your request always returns a basic template (something like your model here), you can use the model you created into the decorator api.marshal_with().

    For instance, in your examples here, just replace expect by marshal_with and it will include the missing values in the response.