Search code examples
pythondecorator

Pass multiple arguments to a decorator in Python


I am trying to build a flask app which will be having RBAC feature. For this I have written a decorator which is working fine but it can only take one argument meaning only one access level(e.g WRITE, READ, admin etc), but I want to pass multiple arguments to it. I have tried passing a list but its not taking it. I have never worked with decorators so need help with it. Thanks.

def permission_required(permission):
  def decorator(f):
    @wraps(f)
      def decorated_function(*args, **kwargs):
        if not current_user.can(permission):
          abort(403)
        return f(*args, **kwargs)
     return decorated_function
   return decorator

def admin_required(f):
  return permission_required(Permission.ADMIN)(f)

I as passing it like this:

@role_needed(Permission.VIEW), but I want to have this @role_needed(Permission.VIEW, Permission.WRITE)

My permission class is like this:

class Permission:
  VIEW = 'Vew'
  WRITE = 'Write'
  ADMIN = 'admin'


Solution

  • First, I'd advise that you have a look at some tutorial on decorators, they are pretty cool and you definitely need to understand the basics if you want to use flask. I personally quite like this RealPython tutorial.

    Second, you have two solutions : either default second argument or argument packing.

    def permission_required(permission1, permission2=None):
    ...
    

    or

    def permission_required(*perms):
    ...
    

    I personaly way prefer the second option. Example:

    def permission_required(*perms):
      def decorator(f):
        @wraps(f)
          def decorated_function(*args, **kwargs):
            for perm in perms:
                if not current_user.can(perm):
                  abort(403)
            return f(*args, **kwargs)
         return decorated_function
       return decorator