如何在结构化烧瓶应用程序中导入相同的烧瓶限制器

问题描述 投票:0回答:2

我正在尝试组织我的 Flask 应用程序,因为它的长度变得相当大,接近 1000 行

我正在尝试使用此处所示的方法将 REST API 与我的主应用程序分开:https://flask-restx.readthedocs.io/en/latest/scaling.html#multiple-apis-with-reusable-命名空间

我的 main.py 中剩下的内容是这样的

from apiv1 import blueprint as api1

REST_API = Flask(__name__)
REST_API.wsgi_app = ProxyFix(REST_API.wsgi_app, x_for=1)
REST_API.register_blueprint(api1)

但是在我的应用程序中,我使用的是烧瓶限制器

# Very basic DOS prevention
try:
    limiter = Limiter(
        REST_API,
        key_func=get_remote_address,
        storage_uri="redis://localhost:6379/1",
        # storage_options={"connect_timeout": 30},
        strategy="fixed-window", # or "moving-window"
        default_limits=["90 per minute"]
    )
# Allow local workatation run
except:
    limiter = Limiter(
        REST_API,
        key_func=get_remote_address,
        default_limits=["90 per minute"]
    )

这同样被放置在我的各种 API 函数的装饰器中

    decorators = [limiter.limit("30/minute")]
    def post(self, server_id = ''):
       # [..]

现在我将 REST api 从声明端点的同一文件中分离出来,我不知道如何传递它的对象。 REST_API var仅存在于我的main.py中

我应该如何处理传递限制器变量或任何其他全局对象?

flask flask-limiter
2个回答
0
投票

我昨天工作了几个小时,但我终于理解了做这种事情的Pythonic方法。

我无法理解导入的功能,所以我一直在努力解决诸如“如何在导入过程中传递变量”等问题。

最后,我意识到我需要在导入中遵循“拉”方法,而不是尝试将变量推入其中。 IE。我在包的

__init__
中设置了中心位置,它将导入我的记录器模块,然后我的其他模块将从那里导入该记录器变量。

enter image description here

所以在我的应用程序的

__init__
中,我有

from .limiter import limiter

app/apis/v1.py
我有

from .. import limiter

这似乎终于奏效了。我不知道这是否是预期的方式,意味着使用相对模块路径,所以如果有更优雅的方式,请告诉我


0
投票

您可以为限制器创建一个单独的文件,并使用 Flask 构造函数在其中初始化限制器。

假设flaskapp是您的主文件夹,并且其他所有内容都在里面,您可以像这样创建限制器

flaskapp/limiter.py

from flask import Flask
from flask_limiter import Limiter
from flask_limiter.util import get_remote_address

app = Flask(__name__)

limiter = Limiter(
        get_remote_address,
        app=app,
        storage_uri="mongodb://<<MONGODBURI>>",
        strategy="fixed-window", # or "moving-window"
        default_limits=["60 per minute"],
        )

现在您可以直接在各种routes.py文件或任何文件中导入此限制器,并在那里使用它

来自我的flaskapp/apps/api/routes.py 文件的代码

from limiter import limiter
.
.
.
.
.    
@api_blueprint.route('/apisearch', methods=['GET'])
@limiter.limit("1/2second")
def api_search_get_404():
    return render_template('templates/my_view.html')

适用于在另一个路径文件中导入相同的限制器 例如,在我的flaskapp/apps/dashboard/routes.py

from limiter import limiter

@dashboard_blueprint.route('/index')
@limiter.limit("1/2second")
def index():
    return render_template("index_stuff.html")

从项目组织的角度来看,这实际上非常有用,现在您可以将所有限制器相关的内容保存在自己的文件中。例如,我添加了一个共享限制器,我可以将其导入到所有路由中并直接在那里使用

from flask import Flask
.
.
.
shared_limit = limiter.shared_limit("1/5second", scope="database")

在我的路线文件中

from limiter import limiter,shared_limit

@dashboard_blueprint.route('/index')
@shared_limit #@limiter.limit("1/2second")
def index():
    return render_template("index_stuff.html")
© www.soinside.com 2019 - 2024. All rights reserved.