我正在尝试组织我的 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中
我应该如何处理传递限制器变量或任何其他全局对象?
我昨天工作了几个小时,但我终于理解了做这种事情的Pythonic方法。
我无法理解导入的功能,所以我一直在努力解决诸如“如何在导入过程中传递变量”等问题。
最后,我意识到我需要在导入中遵循“拉”方法,而不是尝试将变量推入其中。 IE。我在包的
__init__
中设置了中心位置,它将导入我的记录器模块,然后我的其他模块将从那里导入该记录器变量。
所以在我的应用程序的
__init__
中,我有
from .limiter import limiter
在
app/apis/v1.py
我有
from .. import limiter
这似乎终于奏效了。我不知道这是否是预期的方式,意味着使用相对模块路径,所以如果有更优雅的方式,请告诉我
您可以为限制器创建一个单独的文件,并使用 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")