TypeError on CORS for flask-restful

点点圈 提交于 2019-12-04 04:42:59
matthewjaestokeley

I recently came across this issue myself. @MartijnPieters is correct, decorators can't be called on single methods of the view.

I created an abstract base class that contained the decorator list. The class that consumes Resource (from flask-restful) also inherits the base class, which is the class actually applying the decorator list to the view.

    class AbstractAPI():
       decorators = [cors.crossdomain(origin='*')]

    class HelloWorld(restful.Resource, AbstractAPI):
       #content

nope.

just add the decorator list to the parameters after you create the Api instance

api = Api(app)
api.decorators=[cors.crossdomain(origin='*')]

The return value of the wrapped function is passed (as one argument) to flask.make_response(); anything that a normal Flask view can return is acceptable. The decorator is essentially the same as this Flask snippet.

Because the Flask-restful Resource is a subclass of flask.views.MethodView you should really not put decorators directly on the methods here. As documented in Decorating Views you should list view decorators in a special class attribute, decorators which is a list:

class HelloWorld(restful.Resource):
    decorators = [cors.crossdomain(origin='*')]

    def get(self):
        return {'hello': 'world'}

and Flask will apply the view to the actual view method returned by HelloWorld.as_view(), which is what Flask actually calls when dispatching the route to the view.

Applying them directly to the methods will only server to confuse the restful.Resource dispatcher as it is expecting methods to return python datastructures suitable for encoding to JSON, which is not what cors.crossdomain() returns anyway.

I found that you can still use the decorator provided you return a string or JSON response (which is probably good practice for an API anyway). This is important if you want to do route-specific CORS headers, using the decorator makes life much easier. See this merged pull req for more information: https://github.com/flask-restful/flask-restful/pull/131

Here's an example:

from . import app
from flask_restful import reqparse, abort, Api, Resource
from flask.ext.cors import cross_origin
from datetime import datetime
from flask import jsonify

api = Api(app)


class DateTime(Resource):
    @cross_origin(origins="http://localhost:63342*")
    def get(self):
        return jsonify({'DateTime': str(datetime.today())})

api_root = '/api/v1/'
api.add_resource(DateTime, api_root + 'DateTime')

If you're using flask-security, adding auth decorators had some weird behavior in my testing. I recommend assert current_user.is_authenticated instead. If you are allowing credentials, make sure to CSRF protect.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!