Python Flask How To Pass A Dynamic Parameter To A Decorator
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"