Simply explained with examples and use cases

Usage

Decorator is a wrapper. efficient use examples:

  • for session authentication
  • parameters validation

Example

The next example is a handler which receives a request to delete some item:

@app.delete('/item/')
@auth_basic(validate_username_password)
def delete_item():
    return utils.json_dumps({'status': 'OK'})

After falling on the handler delete_item, A validation is executed by auth_basic and validate_username_password.
auth_basic wraps delete_item and receives auxiliary function validate_username_password to help it decide whether the credentials are correct.

The implementation according to bottle package is as follows:

def auth_basic(check, realm="private", text="Access denied"):
    def decorator(func):
        def wrapper(*a, **ka):
            user, password = request.auth or (None, None)
            if user is None or not check(user, password):
                err = HTTPError(401, text)
                err.add_header('WWW-Authenticate', 'Basic realm="%s"' % realm)
                return err
            return func(*a, **ka)
        return wrapper
    return decorator

As you can see auth_basic will return a new wrapped function named decorator. decorator input is the parameter func. this parameter is the wrapped function delete_item. decorator returns the new execution logic of delete_item which is authenticating and then if the authentication passes, the original function func will be executed with its original parameters *a, **ka.

validate_username_password implementation is as follows:

def validate_username_password(username, password):
    global correct_hashed_pwd
    global expected_username
    received_hashed_pwd = hashlib.sha256(password).hexdigest()
    return received_hashed_pwd == correct_hashed_pwd and username == expected_username

The decorator received it as check