flask-restplus
flask-restplus copied to clipboard
api.header decorator of flask-restplus does not work for swagger documentation
I posted this on SO but did not got any reply: https://stackoverflow.com/q/48972880/3311276 maybe this is an issue. Can you please look at this ?
I have a simple API GET method that returns list of IP's in terminal the implementation works fine and and I can use JWT token to get list of IP. However when I try the same using TRY-OUT button on Swagger documentation page it hangs for ever.
Here is the implementation:
@url_api.route("/getallips")
@url_api.header('Authorization: Bearer', 'JWT TOKEN', required=True)
class IpList(Resource):
@jwt_required
def get(self):
"""
this function handles request to provide all ip's.
:return: List of registered ip address metadata mapped to url's.
"""
return jsonify(get_all_publicIp())
@sanfx hi my question like this, Has this problem been solved?
Yes, same here. The headers decorator is recognised, but does not create an input prompt (like it used to in the previous version of Flask-restplus)
Name | Description | Type |
---|---|---|
Authorization | Access Token | string |
if like this, it's ok....
Thanks @guomaoqiu - that works in some of my cases. However, I'm mainly using the api.model approach for my arguments instead of the requestparser, so using api.doc(parser=parser) doesn't quite fit.
I just noticed a note in the docs that says:
Using RequestParser is prefered over the api.param() decorator to document form fields as it also perform validation.
Any thoughts? Should I rewrite, or is there another way to do this?
After some experimentation, I can't get swagger documentation for an auth header and additional json parameters. 'form' works for the parameters. This used to work in the previous version.
I don't know if my answer is what you want. Now, you can document response headers (not request headers) with the @api.header() decorator. https://flask-restplus.readthedocs.io/en/stable/swagger.html#headers
Fought with this for a few hours this evening.
I was able to get it working via the security / authorization mechanism. This makes it required for all endpoints, you can override a specific endpoint by putting the decoratos @api.doc(security=None)
to make it not require auth. I can now login and copy the token and click the authorize button and put in Bearer <paste>
and the other calls succeed as I would expect.
authorizations = {
'Bearer Auth': {
'type': 'apiKey',
'in': 'header',
'name': 'Authorization'
},
}
api = Api(app, security='Bearer Auth', authorizations=authorizations)
Still not able to document request header. Is there any alternative solution available for custom headers ? I am using api.model
approach for api.expect
decorator. As @garrywilliams said, model and request header both don't play together. any idea ?
I was able to get it with the first example using the request parser... however I don't like that way because I was unable to mask the password with *****.
I also got the second solution working for Basic Auth. If anyone needs that instead of the api key authorization... this worked for me:
authorizations = {
'Basic Auth': {
'type': 'basic',
'in': 'header',
'name': 'Authorization'
},
}
api = Api(
blueprint,
doc='/',
version='1.0',
title=title,
description=desc,
security='Basic Auth',
authorizations=authorizations
)
And then in my endpoint just get the header from the request like normal and extract the base64 encoded string:
try:
encoded_auth_header = request.headers['Authorization'].split()[1]
username, password = b64decode(encoded_auth_header).split(':')
except Exception:
resp = app.response_class(
response=json.dumps({"error": "bad username/password"}),
status=401,
content_type='application/json'
)
return resp
In my opinion the header decorator has nothing to do with this and this issue should be closed but I may be mistaken. I think the header decorator is for the response header that gets returned?
I think that the second method of Authorization should really be put in the documentation.
@agpt if you use the second solution (not request parser), you don't even need the api.model or api.expect etc... unless you are trying to pass in additional parameters other than Basic Auth in the header
Now, you can document response headers (not request headers) with the @api.header() decorator.
It seems the requests headers are treated as parameters. So they can be documented and used in "Try it out" mode by means of @api.doc
decorator having 'in': 'header'
:
@api.route('/some-endpoint')
@api.doc(params={'Authorization': {'in': 'header', 'description': 'An authorization token'}})
It gives:
try
auth = request.authorization
this will return dict with decoded username and password keys and values from basic authorization
@api.doc(params={'Authorization': {'in': 'header', 'description': 'An authorization token'}})
That's what I looked so long. But it still demand a "Bearer" word before the token, can we get rid of it somehow?
But it still demand a "Bearer" word before the token, can we get rid of it somehow?
Did you every figure this out?
Did you every figure this out? No, If I've got you right. Even did'nt have time for it. I understand the "Bearer" word is necessary, but I want to find a way to hide it from user in swagger so he can would put only the token in the field and "Bearer" word should be added automatically somehow. Do we have this opportunity? Maybe some parameter in doc decorator or something else?
Did you every figure this out? No, If I've got you right. Even did'nt have time for it. I understand the "Bearer" word is necessary, but I want to find a way to hide it from user in swagger so he can would put only the token in the field and "Bearer" word should be added automatically somehow. Do we have this opportunity? Maybe some parameter in doc decorator or something else?
That's what I'd like to know too