Wrapping Functions in Python 3.4 missing required positional argument

5k Views Asked by At

I am trying to customize a login_required decorator from the Flask-Login package. I have read the source code and mimicked the syntax.

Mine:

def login_role_required(f, req_roles=['any']):
@wraps(f)
def decorated_view(*args, **kwargs):
    if current_app.login_manager._login_disabled:
        return f(*args, **kwargs)
    if not current_user.is_authenticated():
        return current_app.login_manager.unauthorized()

    if req_roles == ['any']:
        return f(*args, **kwargs)
    user_roles = current_user.get_roles

    # Check to make sure all required roles are had by user
    for r in req_roles:
        if r not in user_roles:
            current_app.login_manager.unauthorized()
    return f(*args, **kwargs)
return decorated_view

Source:

def login_required(func):
@wraps(func)
def decorated_view(*args, **kwargs):
    if current_app.login_manager._login_disabled:
        return func(*args, **kwargs)
    elif not current_user.is_authenticated():
        return current_app.login_manager.unauthorized()
    return func(*args, **kwargs)
return decorated_view

Please forgive bad indentation from copy/paste.

Problem: When I use my function to wrap, it cannot get the first argument, f (the function).

@app.route('/shutdown', methods=['POST'])
@login_role_required(req_roles=['admin'])
def shutdown_server():
   pass

TypeError: login_role_required() missing 1 required positional argument: 'f'

There must be something small I am doing not-so-smartly. Thanks for your time.

1

There are 1 best solutions below

0
On BEST ANSWER

login_role_required should be a function that returns a decorator function, which in turn takes a single argument—the decorated function—and returns a modified function. So it should look like this:

def login_role_required(req_roles = None):
    if req_roles is None:
        req_roles = ['any']

    def decorator (f):
        def decorated_view(*args, **kwargs):
            # …
            return f(*args, **kwargs)
        return decorated_view

    return decorator