Python decorator access argument by name
You can use the inspect.getfullargspec()
function to access the names used in a function:
try: # Python 3 from inspect import getfullargspecexcept ImportError: # Python 2, use inspect.getargspec instead # this is the same function really, without support for annotations # and keyword-only arguments from inspect import getargspec as getfullargspecfrom functools import wrapsdef access_course_permission(argument_name): def decorator(f): argspec = getfullargspec(f) argument_index = argspec.args.index(argument_name) @wraps(f) def wrapper(*args, **kwargs): try: value = args[argument_index] except IndexError: value = kwargs[argument_name] # do something with value return f(*args, **kwargs) return wrapper return decorator
The above finds out at what index your specific argument is positioned; this covers both positional and keyword arguments (because in Python, you can pass in a value for a keyword argument by position too).
Note however that for your specific example, Flask will call view_course
with course_id
as a keyword argument, so using kwargs[argument_name]
would suffice.
You'll have to pass in a string to name that argument:
@app.route('/admin/courses/<int:course_id>')@access_course_permission('course_id')def view_course(course_id): # ... view code here
Note however, that in Flask you could just access request.view_args
, without the need to parse this information out of the function arguments:
course_id = requests.view_args[argument_name]