I'm trying to replace the marshal_with
decorator from flask-restful
with a decorator that does something before calling marshal_with
. My approach is to try to implement a new decorator that wraps marshal_with
.
My code looks like:
from flask.ext.restful import marshal_with as restful_marshal_with
def marshal_with(fields, envelope=None):
def wrapper(f):
print("Do something with fields and envelope")
@wraps(f)
def inner(*args, **kwargs):
restful_marshal_with(f(*args, **kwargs))
return inner
return wrapper
Unfortunately this seems to break things... no error messages but my API returns a null response when it shouldn't be. Any insights on what I'm doing wrong?
I was doing a couple things wrong here, first, failing to return the output of restful_marshal_with
as jonrsharpe pointed out, secondly, failing to understand a decorator written as a class instead of a function, and how to properly pass values to it. The correct code ended up being:
def marshal_with(fields, envelope=None):
def wrapper(f):
print("Do something with fields and envelope")
@wraps(f)
def inner(*args, **kwargs):
rmw = restful_marshal_with(fields, envelope)
return rmw(f)(*args, **kwargs)
return inner
return wrapper
As you can see, in addition to not returning rmw()
, I needed to properly initialize the request_marshal_with
class before calling it. Finally, it is important to remember that decorators return functions, therefore the arguments of the original function should be passed to the return value of rmw(f)
, hence the statement return rmw(f)(*args, **kwargs)
. This is perhaps more apparent if you take a look at the flask_restful.marshal_with
code here.