背景: 我有 Flask 应用程序,它是一个 NGINX 身份验证模块,用 Flask 编写,在代码的某些部分我正在调用 LDAP 服务器。
目标是使用flask-caching库来缓存来自LDAP服务器的响应并避免昂贵的调用。
下面的代码是一个非常精简的版本,仅显示相关部分。
问题 在下面的场景中,我无法在 Ldap 类的方法上使用装饰器
@cache.memoized
,因为变量 cache
在该模块中不可用。
name 'cache' is not defined
main.py
from flask import Flask
from flask_caching import Cache
from ldap import Ldap
app = Flask(__name__)
cache = Cache(app)
@app.route('/', defaults={'path': ''})
@app.route('/<path:path>')
@auth.login_required
def index(path):
code = 200
msg = "Another LDAP Auth"
headers = [('x-username', getRegister('username')),
('x-groups', getRegister('matchedGroups'))]
return msg, code, headers
@auth.verify_password
def login(username, password):
ldap = Ldap()
ldap.verifyUser(username, password)
ldap.py
class Ldap:
@cache.memoized(timeout=300) <<<< error
def validateUser(self, username, password)
if <ldap query goes here>
return True
return False
研究 对我来说,奇怪的是这个装饰器依赖于一个对象实例,而不是像我见过的许多其他场景那样依赖于一个类
替代方案: 当然,如果我将类的定义放在同一个
main.py
中,并在 cache
变量的定义下面,它就可以工作,但这将使我的 main.py
文件太长。
尝试1: 在定义缓存变量后尝试导入我的模块有相同的错误
尝试2: 在
from main import cache
内执行 ldap.py
会导致循环导入错误。
想法: 将
cache
变量传递给 Ldap 类构造函数,并“以某种方式”使用它来装饰该方法,但我找不到确切的操作方法。
解决方案是在不同的文件中初始化缓存,如此处所述。
# cache.py
from flask_caching import Cache
cache = Cache()
# main.py
from flask import Flask
from cache import cache
config = {
"DEBUG": True,
"CACHE_TYPE": "filesystem",
"CACHE_DIR": "flask_cache"
}
app = Flask(__name__)
cache.init_app(app, config=config)
# other.py
from main import cache
@cache.memoize(50)
def some_func(abc):
# do stuff