Redis
 sql >> Base de Dados >  >> NoSQL >> Redis

frasco python como passar um parâmetro dinâmico para um decorador


Se verificarmos os documentos para o aplicativo flask global, flask.g , diz:

Para compartilhar dados válidos para uma solicitação apenas de uma função para outra, uma variável global não é boa o suficiente porque ela seria interrompida em ambientes encadeados. O Flask fornece um objeto especial que garante que é válido apenas para a solicitação ativa e isso retornará valores diferentes para cada solicitação.

Isso é feito usando um proxy local de thread (em flask/globals.py ):
g = LocalProxy(partial(_lookup_app_object, 'g'))

A outra coisa que devemos ter em mente é que o Python está executando a primeira passagem do nosso decorador durante a fase de "compilação", fora de qualquer solicitação, ou flask inscrição. Isso significa key argumento recebe um valor de 'shop_{}_style'.format(g.city.id) quando seu aplicativo é iniciado (quando sua classe está sendo analisada/decorada), fora do flask contexto do pedido.

Mas podemos atrasar facilmente o acesso a flask.g usando um proxy lento, que busca o valor somente quando usado, por meio da função de retorno de chamada. Vamos usar o que já vem com flask , o 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

Em geral (para não flask ou não-werkzeug apps), podemos usar um LazyProxy semelhante dos ProxyTypes pacote.

Não relacionado a isso, você também deve corrigir seu redis_hash_shop_style decorador para não apenas buscar de redis , mas também para atualizar (ou criar) o valor se estiver obsoleto (ou inexistente), chamando o f() encapsulado quando for apropriado.