A decorator is a function which wraps another function. Say you have a function f(x) and you have a decorator h(x), the decorator function takes as argument your function f(x) and so in effect what you will have is a new function h(f(x)). It makes for cleaner code as for instance in your login_required, you do not have to put in the same code to test if a user is logged in rather you can wrap the function in a login_required function so that such a function is called only if the user is logged in. Study this snippet below
def login_required(restricted_func):
"""Decorator function for restricting access to restricted pages.
Redirects a user to login page if user is not authenticated.
Args:
a function for returning a restricted page
Returns:
a function
"""
def permitted_helper(*args, **kwargs):
"""tests for authentication and then call restricted_func if
authenticated"""
if is_authenticated():
return restricted_func(*args, **kwargs)
else:
bottle.redirect("/login")
return permitted_helper