Si nous vérifions les docs pour flask application global, flask.g
, il dit :
Pour partager des données valides pour une seule requête d'une fonction à une autre, une variable globale n'est pas suffisante car elle se briserait dans les environnements threadés. Flask vous fournit un objet spécial qui garantit qu'il n'est valide que pour la demande active et cela renverra des valeurs différentes pour chaque requête.
Ceci est réalisé en utilisant un proxy local de thread (dans flask/globals.py
):
g = LocalProxy(partial(_lookup_app_object, 'g'))
L'autre chose que nous devons garder à l'esprit est que Python exécute la première passe de notre décorateur pendant la phase de "compilation", en dehors de toute requête, ou flask
application. Cela signifie key
l'argument se voit attribuer une valeur de 'shop_{}_style'.format(g.city.id)
lorsque votre application démarre (lorsque votre classe est analysée/décorée), en dehors de flask
contexte de la requête.
Mais nous pouvons facilement retarder l'accès à flask.g
en utilisant un proxy paresseux, qui récupère la valeur uniquement lorsqu'il est utilisé, via la fonction de rappel. Utilisons celui déjà fourni avec flask
, le werkzeug.local.LocalProxy
:
from werkzeug.local import LocalProxy
class ShopAreaAndStyleListAPI(Resource):
@redis_hash_shop_style(key=LocalProxy(lambda: 'shop_{}_style'.format(g.city.id)))
def get(self):
# if not found from redis, query from mysql
pass
En général (pour non-flask
ou non werkzeug
apps), nous pouvons utiliser un LazyProxy
similaire à partir des ProxyTypes
paquet.
Sans rapport avec cela, vous voudrez également corriger votre redis_hash_shop_style
décorateur non seulement pour récupérer à partir de redis
, mais aussi pour mettre à jour (ou créer) la valeur si périmée (ou inexistante), en appelant le f()
enveloppé le cas échéant.