Davide Pugliese

Software development articles, nerdy news

Create big apps with Flask – part 3

2017-06-27 Davide Pugliesepython

Welcome back to this series of tutorial on Flask and complex apps.

The Decorator pattern

The decorator pattern is one of those patterns that nowadays we encounter in a variety of frameworks.

From The Gang of Four’s book:

Decorators Attach additional responsibilities to an object dynamically.
Decorators provide a flexible alternative to subclassing for extending functionality.
Also Known As Wrapper

When it comes to a function we have two possibilities:

  1. We don’t pass any extra parameters from the caller because we do not need to do some extra computation

    def example_decorator_function(original_function):      
        def some_new_function(*args,**kwargs):
            print("Back to the future")              
            x = original_function(*args,**kwargs)                
            print("American Pie"); 
            return x                                             
        return some_new_function()                                   
    def func_a(stuff):
        print("Life is beautiful and " + stuff)
  2. We pass some extra parameters for example for some verification purposes

    def router_acl(user_type):
      def router_acl_decorator(fn):
          @wraps(fn)  # it basically updates the context with the new function, variables, etc.
          def func_wrapper(*args, **kwargs):
              current_user = CurrentUserHelper()
              if request.method == 'GET':
                  if user_type == CURRENT_USER_ONLY:
                      if current_user.id == int(request.args.get('user_id')):
                          return fn()
                          # you can test this by changing status to whatever you like and
                          # then trying to connect to a route with
                          # a wrong user id e.g. http://localhost:5001/api/user/edit?id=24
                          response = json.jsonify({"status": "fail"})
                          response.status_code = 403