I have something roughly like the following. Basically I need to access the class of an instance method from a decorator used upon the instance method in its definition.
What flask-classy does is create a temporary cache that it stores on the method, then it uses something else (the fact that Flask will register the classes using a register class method) to actually wraps the method.
You can reuse this pattern, this time using a metaclass so that you can wrap the method at import time.
def route(rule, **options):
"""A decorator that is used to define custom routes for methods in
FlaskView subclasses. The format is exactly the same as Flask's
`@app.route` decorator.
"""
def decorator(f):
# Put the rule cache on the method itself instead of globally
if not hasattr(f, '_rule_cache') or f._rule_cache is None:
f._rule_cache = {f.__name__: [(rule, options)]}
elif not f.__name__ in f._rule_cache:
f._rule_cache[f.__name__] = [(rule, options)]
else:
f._rule_cache[f.__name__].append((rule, options))
return f
return decorator
On the actual class (you could do the same using a metaclass):
@classmethod
def register(cls, app, route_base=None, subdomain=None, route_prefix=None,
trailing_slash=None):
for name, value in members:
proxy = cls.make_proxy_method(name)
route_name = cls.build_route_name(name)
try:
if hasattr(value, "_rule_cache") and name in value._rule_cache:
for idx, cached_rule in enumerate(value._rule_cache[name]):
# wrap the method here
Source: https://github.com/apiguy/flask-classy/blob/master/flask_classy.py