I need to use both decorators but they conflict with each other. Here is my routes:
channel_args = {
'name': fields.Str(required=True),
'description': fields.Str(required=False, missing=None, default=None)
}
class ChannelListRoutes(Resource):
@require_oauth
@use_args(channel_args, locations=['json'])
def post(self, args):
channel = Channel()
channel.name = args['name']
channel.description = args['description']
channel.user_id = current_token.user.id
db.session.commit()
db.session.flush()
return ChannelJson(channel).to_json(), status.HTTP_201_CREATED
where require_oauth = ResourceProtector()
from Authlib, @use_args
using webargs library.
I am sending data by cURL:
curl -H "Authorization: Bearer {access_token}" -H "Content-Type: application/json" -X POST -d "{\"name\":\"Pets\"}" http://127.0.0.1:5000/api/channels
After request my app just crashes:
Traceback (most recent call last):
File "/home/ghostman/Projects/vistory/auth/venv/lib/python3.6/site-packages/flask/app.py", line 2309, in __call__
return self.wsgi_app(environ, start_response)
File "/home/ghostman/Projects/vistory/auth/venv/lib/python3.6/site-packages/flask/app.py", line 2295, in wsgi_app
response = self.handle_exception(e)
File "/home/ghostman/Projects/vistory/auth/venv/lib/python3.6/site-packages/flask_restful/__init__.py", line 273, in error_router
return original_handler(e)
File "/home/ghostman/Projects/vistory/auth/venv/lib/python3.6/site-packages/flask/app.py", line 1741, in handle_exception
reraise(exc_type, exc_value, tb)
File "/home/ghostman/Projects/vistory/auth/venv/lib/python3.6/site-packages/flask/_compat.py", line 34, in reraise
raise value.with_traceback(tb)
File "/home/ghostman/Projects/vistory/auth/venv/lib/python3.6/site-packages/flask/app.py", line 2292, in wsgi_app
response = self.full_dispatch_request()
File "/home/ghostman/Projects/vistory/auth/venv/lib/python3.6/site-packages/flask/app.py", line 1815, in full_dispatch_request
rv = self.handle_user_exception(e)
File "/home/ghostman/Projects/vistory/auth/venv/lib/python3.6/site-packages/flask_restful/__init__.py", line 273, in error_router
return original_handler(e)
File "/home/ghostman/Projects/vistory/auth/venv/lib/python3.6/site-packages/flask/app.py", line 1718, in handle_user_exception
reraise(exc_type, exc_value, tb)
File "/home/ghostman/Projects/vistory/auth/venv/lib/python3.6/site-packages/flask/_compat.py", line 34, in reraise
raise value.with_traceback(tb)
File "/home/ghostman/Projects/vistory/auth/venv/lib/python3.6/site-packages/flask/app.py", line 1813, in full_dispatch_request
rv = self.dispatch_request()
File "/home/ghostman/Projects/vistory/auth/venv/lib/python3.6/site-packages/flask/app.py", line 1799, in dispatch_request
return self.view_functions[rule.endpoint](**req.view_args)
File "/home/ghostman/Projects/vistory/auth/venv/lib/python3.6/site-packages/flask_restful/__init__.py", line 484, in wrapper
return self.make_response(data, code, headers=headers)
File "/home/ghostman/Projects/vistory/auth/venv/lib/python3.6/site-packages/flask_restful/__init__.py", line 513, in make_response
resp = self.representations[mediatype](data, *args, **kwargs)
File "/home/ghostman/Projects/vistory/auth/venv/lib/python3.6/site-packages/flask_restful/representations/json.py", line 21, in output_json
dumped = dumps(data, **settings) + "\n"
File "/usr/lib/python3.6/json/__init__.py", line 238, in dumps
**kw).encode(obj)
File "/usr/lib/python3.6/json/encoder.py", line 201, in encode
chunks = list(chunks)
File "/usr/lib/python3.6/json/encoder.py", line 437, in _iterencode
o = _default(o)
File "/usr/lib/python3.6/json/encoder.py", line 180, in default
o.__class__.__name__)
TypeError: Object of type 'function' is not JSON serializable
P.S. I tried to change the order of decorators, it doesn't help too, although it produces a new stack trace:
File "/home/ghostman/Projects/vistory/auth/venv/lib/python3.6/site-packages/webargs/core.py", line 482, in wrapper
return func(*new_args, **kwargs)
TypeError: wrapper() takes 1 positional argument but 2 were given
reading the doc might help...
require_oauth
expects a "scope" argument, so the correct syntax isYou can also avoid specifying a scope by passing
None
explicitely (@require_oauth(None)
) or implicitely by callingrequire_oauth
without any argument, but you still need to call the decorator, ie:=> note the parens (the call operator in python).