I had created a decorator to check if a person has session as follows: (comments added for brevity)
def session_enabled(func=None, prefix='calling: '):
# some preprocessing
def session_enabled_wrapper(*args, **kwargs):
# check for session in request obj
# execute the function and get result onto a variable say result
# some API profiling logic
return result
return session_enabled_wrapper
I have used this on some views as follows:
@session_enabled
@csrf_exempt
def view_function(request):
# some processing
My goal was to check if any function are being accessed without this decorator in place on the logs. So i wrote a middleware as follows:
class SessionEnabledMiddleware(object):
'''
class that represents middleware called during requests
'''
def process_view(self, request, view_func, view_args, view_kwargs):
'''
called during the request cycle
:param request: request param
:param view_func: view function object
:param view_args: args passed to view function
:param view_kwargs: kwargs passed to view function
:return: None
'''
print('############# Inside session enabled middleware ###################')
if not view_func.__name__ == 'session_enabled_wrapper':
print('Function Not session enabled', request.path)
else:
print('function is session enabled', request.path)
I added the above middleware to tuple of MIDDLEWARE_CLASSES in settings.py file. I was happy as this worked, but the happiness was short lived as my APIs started to crash with 403 forbidden error.
After some research, i changed the decorator as follows:
import functools
def session_enabled(func=None, prefix='calling: '):
# some preprocessing
@wraps(func)
def session_enabled_wrapper(*args, **kwargs):
# check for session in request obj
# execute the function and get result onto a variable say result
# some API profiling logic
return result
return session_enabled_wrapper
This meant that my earlier middleware logic failed. I needed to overcome this. So changed my middleware and decorator as follows:
decorator:
def session_enabled(func=None, prefix='calling: '):
# some preprocessing
@wraps(func)
def wrapper(*args, **kwargs):
wrapper.session_enabled = True
# check for session in request obj
# actual function execution and get result onto a varible say result
# some API profiling logic
return result
wrapper.session_enabled = False
return wrapper
middleware:
class SessionEnabledMiddleware(object):
'''
class that represents middleware called during requests
'''
def process_view(self, request, view_func, view_args, view_kwargs):
'''
called during the request cycle
:param request: request param
:param view_func: view function object
:param view_args: args passed to view function
:param view_kwargs: kwargs passed to view function
:return: None
'''
print('############# Inside session enabled middleware ###################')
if not view_func.session_enabled:
print('Function Not session enabled', request.path)
else:
print('function is session enabled', request.path)
But i was greeted with function object has no attribute 'session_enabled'.
I even tried:
view_function.__closure__[0].cell_contents.__name__
but couldn't get the name of the decorator.
What am i doing wrong? Is there any possible way to get the name of the decorator to be used as a condition in middleware or a way to find if the function is decorated and take necessary actions?
Note: Stackoverflow question which almost meet the above requirement: Detect Decorator in Python
EDIT:
After considering Vitor Freitas recommended link i changed the code as follows:
@register(session_enabled, csrf_exempt)
def view_function(request):
# some processing
middleware:
class SessionEnabledMiddleware(object):
'''
class that represents middleware called during requests
'''
def process_view(self, request, view_func, view_args, view_kwargs):
'''
called during the request cycle
:param request: request param
:param view_func: view function object
:param view_args: args passed to view function
:param view_kwargs: kwargs passed to view function
:return: None
'''
try:
print('############# Inside session enabled middleware ###################')
decorators = [decorator.__name__ for decorator in view_func._decorators]
if 'session_enabled' in decorators:
print('Function is session enabled', request.path)
except:
print('function is not session enabled or decorated using register', request.path)
Work's like a charm.....