Skip to content Skip to sidebar Skip to footer

Python Flask How To Pass A Dynamic Parameter To A Decorator

I am using python flask framework. I write a decorator which will be need a parameter, and this parameter will be dynamic. my decorator like below, will be get a key ,and using the

Solution 1:

If we check the docs for flask application global, flask.g, it says:

To share data that is valid for one request only from one function to another, a global variable is not good enough because it would break in threaded environments. Flask provides you with a special object that ensures it is only valid for the active request and that will return different values for each request.

This is achieved by using a thread-local proxy (in flask/globals.py):

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

The other thing we should keep in mind is that Python is executing the first pass of our decorator during the "compile" phase, outside of any request, or flask application. That means key argument get assigned a value of 'shop_{}_style'.format(g.city.id) when your application starts (when your class is being parsed/decorated), outside of flask request context.

But we can easily delay accessing to flask.g by using a lazy proxy, which fetches the value only when used, via callback function. Let's use the one already bundled with flask, the werkzeug.local.LocalProxy:

from werkzeug.local import LocalProxy

classShopAreaAndStyleListAPI(Resource):
    @redis_hash_shop_style(key=LocalProxy(lambda: 'shop_{}_style'.format(g.city.id)))defget(self):
        # if not found from redis, query from mysqlpass

In general (for non-flask or non-werkzeug apps), we can use a similar LazyProxy from the ProxyTypes package.

Unrelated to this, you'll also want to fix your redis_hash_shop_style decorator to not only fetch from redis, but to also update (or create) the value if stale (or non-existing), by calling the wrapped f() when appropriate.

Post a Comment for "Python Flask How To Pass A Dynamic Parameter To A Decorator"