'Python Flask_restplus flash_restx dynamic marshalling response

Is it possible to dynamicaly modify the marshalled response model (ie : change fields list, add mask, ...) ?

ex :

from flask_restplus import Resource, fields

model = api.model('Model', {
    'name': fields.String,
    'address': fields.String,
    'date_updated': fields.DateTime(dt_format='rfc822'),
})

@api.route('/todo')
class Todo(Resource):
    @api.marshal_with(model, envelope='resource')
    def get(self, **kwargs):
        return db_get_todo()  # Some function that queries the db

Here the marshalling is staticaly declared with decorator. If i would like to mask from example date_updated when user is not admin, or depending on user preferences I can't.

I saw this example : https://blog.fossasia.org/dynamically-marshaling-output-in-flask-restplus/ It is interesting but it uses another static model, so it is not trully dynamic and implies code duplication (sure I can use inherit,...)

What I would like is be able to change dynamicaly the fields or add a mask from a list that could come from a db for example (user preferences or rights).

I have tried to manualy marshal the answer

wanted_field_list='name,address'
return  marshal(db_get_todo(),model , mask=wanted_field_list),  200

If I remove the decorator @marshall_with it works perfectly but the drawback is I don't have Swagger doc anymore

{ 'name':'blabla',
'address':'xxx'}

If I keep the decorator it still works by the unwanted fields are still rendered with a Null value :

{ 'name':'blabla',
'address':'xxx',
'date_updated : null}

This is not the expected result

I tried to move to flask_restx and my swagger is not rendered at all and I have some other problems.

Any help is very welcome !



Solution 1:[1]

I know its a bit late, but here it is anyway incase someone needs it:

You have a few options to accomplish what you need:

  • Use the skip_none flag to true. This would ignore the date_updated field from the response when it is null.
  • Use the X-Fields mask when calling the API. The mask value is a list of comma separated variable that you'd like to fetch. Rest are ignored.
  • The one in the blog post you linked, which you didn't like... ;)

Solution 2:[2]

use the following decorator

@api.marshal_with(model, skip_none=True)

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Muhammad Ali
Solution 2 Hashir Irfan