Redis
 sql >> Database >  >> NoSQL >> Redis

python flask come passare un parametro dinamico a un decoratore

Se controlliamo i documenti per l'applicazione flask globale, flask.g , dice:

Per condividere dati validi per una richiesta solo da una funzione all'altra, una variabile globale non è sufficiente perché si interromperebbe negli ambienti con thread. Flask ti fornisce un oggetto speciale ciò garantisce che sia valido solo per la richiesta attiva e questo restituirà valori diversi per ogni richiesta.

Ciò si ottiene utilizzando un proxy thread-local (in flask/globals.py ):

g = LocalProxy(partial(_lookup_app_object, 'g'))

L'altra cosa che dovremmo tenere a mente è che Python sta eseguendo il primo passaggio del nostro decoratore durante la fase di "compilazione", al di fuori di qualsiasi richiesta, o flask applicazione. Ciò significa key all'argomento viene assegnato un valore di 'shop_{}_style'.format(g.city.id) all'avvio della tua applicazione (quando la tua classe viene analizzata/decorata), al di fuori di flask contesto della richiesta.

Ma possiamo facilmente ritardare l'accesso a flask.g utilizzando un proxy pigro, che recupera il valore solo quando viene utilizzato, tramite la funzione di callback. Usiamo quello già in bundle con flask , il 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

In generale (per non flask o non werkzeug app), possiamo usare un simile LazyProxy da ProxyTypes pacchetto.

Non correlato a questo, vorrai anche correggere il tuo redis_hash_shop_style decoratore non solo per recuperare da redis , ma anche per aggiornare (o creare) il valore se stantio (o non esistente), chiamando il wrapping f() quando appropriato.