Python Rate Limit class based view Flask

心已入冬 提交于 2019-12-24 00:44:04

问题


I'm following this example:

http://flask-limiter.readthedocs.org/en/stable/#ratelimit-string

app = Flask(__name__)
limiter = Limiter(app, key_func=get_remote_address)

class MyView(flask.views.MethodView):
    decorators = [limiter.limit("10/second")]
    def get(self):
        return "get"

    def put(self):
        return "put"

My problem is that in example, the application, limiter and classes are defined in the same file in my case the application and limiter are defined in the same file but my classes live in a separate file.

If I import either limiter or app my Flask app doesn't start because circular dependencies. How can fix this, what is the recommended way? I want to apply limiter to specific endpoints. I tried from flask import current_appin order to initialize limiter but this function was not take it as a valid parameter. Any recommendations?

File information:

  • app.py
  • api_main.py

Under app.py I have defined my resources:

api_app = Flask(__name__)  # Flask Application
api_app.config.from_pyfile("../../../conf/settings.py")  # Flask configuration

imbue_api = restful.Api(api_app)  # Define API
limiter = Limiter(api_app, key_func=get_remote_address, global_limits=["10 per second"])

imbue_api.add_resource(ApiBase, settings.BASE_API_URL)

In api_main.py I have defined all my classes:

class ApiBase(Resource):
    @authenticator.requires_auth
    def get(self):
        """

        :return:
        """
        try:
            # =========================================================
            # GET API
            # =========================================================
            log.info(request.remote_addr + ' ' + request.__repr__())
            if request.headers['Content-Type'] == 'application/json':
                # =========================================================
                # Send API version information
                # =========================================================
                log.info('api() | GET | Version' + settings.api_version)
                response = json.dumps('version: ' + settings.api_version)
                resp = Response(response, status=200, mimetype='application/json')
                return resp

        except KeyError:
            response = json.dumps('Invalid type headers. Use application/json')
            resp = Response(response, status=415, mimetype='application/json')
            return resp

        except Exception, exception:
            log.exception(exception.__repr__())
            response = json.dumps('Internal Server Error')
            resp = Response(response, status=500, mimetype='application/json')
            return resp

回答1:


Use the Resource.method_decorators

https://github.com/flask-restful/flask-restful/blob/master/flask_restful/init.py#L574

It is applied for each request. You can override it in your view class:

@property
def method_decorators(self):
    # get some limiter bound to the `g` context
    # maybe you prefer to get it from `current_app`
    return g.limiter

If you prefer, you can append the limiter to the existing method_decorators before adding the resource to your restful API.

ApiBase.method_decorators.append(limiter)
imbue_api.add_resource(ApiBase, settings.BASE_API_URL)


来源:https://stackoverflow.com/questions/36859660/python-rate-limit-class-based-view-flask

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