flask-restplus-server-example
flask-restplus-server-example copied to clipboard
Decorate with multiple/chained parameters
I would like to add multiple parameters to an endpoint, essentially chaining them as so:
@api.parameters(SomeParameters())
@api.parameters(MoreParameters())
@api.parameters(EvenMoreParameters())
def get(self, args):
...
However, this results in a separate dict for each set of parameters and does not concatenate the arguments as I had expected. Also, Swagger does not seem to parse all of the argument options as only the topmost decorator appears in the docs.
I could simply create another Parameters class that combines all of the fields from the others, but I'd like to avoid having to create one for each desired combination of parameters.
Another idea I had was to create a method that would accept any number of Parameter objects and return a new dynamic Schema object with all of the combined fields. Something like:
@api.parameters(many_params(SomeParameters(), MoreParameters(), EvenMoreParameters()))
def get(self, args):
...
What is the recommended approach to accomplish this? I feel like I must be missing an easier way...
Currently, there are no plans to support chained parameters (simply due to the lack of time, and because implementing it the right way may take more time than it might be expected). Multiple Inheritance is the way to go now. Still, you can implement many_params
helper yourself. It would be great if you share your experience and the implementation, so we can consider to include it into this example/boilerplate.
Thank you for your interest and sharing this idea!
Good to know, thanks @frol. I'm very appreciative of all your hard work on this project, and if I end up going the helper method route, I'll be sure to post my implementation details back here.
Here's what I ended up going with:
def multi_params(*params):
m = Parameters()
for p in params:
m.fields = dict(m.fields, **p.fields)
return m
And then you can simply put that callable in the decorate and pass in any number of parameter objects to it:
@api.parameters(multi_params(IncludeParameters(), OnlyParameters()))
It's somewhat crude and is definitely limited in handling more complex objects, but it serves my purpose for simple parameters with one or two fields (and it keeps Swagger happy too).
For anyone looking to do something similar, please feel free to improve/refine it!
@jdjodrey Thanks for sharing. I will just comment an obvious limitation of your implementation: custom validations defined on the classes will be ignored, and the reason I haven't touched it is that I have no idea on how to merge @validates_schema
handlers.
I'm running across the same problem here. I'd like to add that it would be nice to be able to specify different locations for each set of parameters. Something like:
@api.parameters(AuthenticationParameters(), locations['header', ])
@api.parameters(PaginationParameters(), locations['query', ])
@api.parameters(SearchQueryParameters(), locations=['json', ])
def get():
return {}
If I come up with anything I'll drop it here.
👍 on this
@jdjodrey Your method has been working quite well for me.
Thanks for @jdjodrey sharing. But it seems that not support locations='path'
. I don't know how to adapt your method...Could you help me? pls @jdjodrey