Python decorator access argument by name Python decorator access argument by name flask flask

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]