Context: I have flask application, which is an NGINX authentication module, written in flask, and in some part of the code I am making a call to an LDAP server.
The objective is to use flask-caching library to cache the response from the LDAP server and avoid that costly call.
The code bellow its a very stripped down version showing only the relevant sections.
Problem
In the below scenario I can't use the decorator @cache.memoized
on a method of the Ldap class, as the variable cache
is not available in that module.
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
Research The weird thing for me here is that this decorator depends on an object instance and not on a class as so many other scenarios I've seen
Alternative:
Definitively if I put the definition of the class in the same main.py
and bellow the definition of the cache
variable it works, however this will make my main.py
file too long.
Attempt 1: Trying to import my module after the definition of the cache variable has the same error
Attempt 2:
doing from main import cache
inside ldap.py
creates a circular import error.
Idea:
Pass the cache
variable to the Ldap Class constructor and "somehow" use it to decorate the method, but I could not find how to do it exactly.
The solution is to initialize the cache in a different file, as described here.
# 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