简体   繁体   中英

TypeError: unexpected keyword argument with Python Decorator

I'm receiving the following type error:

TypeError: wrapper() got an unexpected keyword argument 'id'

When I try to execute a function with these decorators:

def owner_required(table):
    def tags_decorator(func):
        @wraps(func) # this requires an import
        def wrapper(id):
            user_profile = (session['username'], session['picture'])
            # Connect to the database
            con = connect()
            Base.metadata.bind = con
            # Creates a session
            DBSession = sessionmaker(bind=con)
            dbsession = DBSession()
            if table == 'incidents':
                query = dbsession.query(Incidents).
                    filter_by(case_num=id).first()
            if table == 'audits':
                query = dbsession.query(Audits).filter_by(id=id).first()
            if table == 'actions':
                query = dbsession.query(Actions).filter_by(id=id).first()

            creator = int(query.user_id)
            ses_user = int(session['user_id'])
            if 'username' not in session or creator != ses_user:
                flash("Sorry, %s,"
                      " you are not authorized to edit this incident." %
                      session['username'])
                return redirect('/incidents/')
            else:
                func()
        return wrapper
    return tags_decorator

def check_if_report_exists(table):
    def tags_decorator(func):
        @wraps(func) # this requires an import
        def wrapper(**kwargs):
            # Connect to the database
            con = connect()
            Base.metadata.bind = con
            # Creates a session
            DBSession = sessionmaker(bind=con)
            dbsession = DBSession()
            if table == 'incidents':
                query = dbsession.query(Incidents).filter_by(case_num=id).first()
            if table == 'audits':
                query = dbsession.query(Audits).filter_by(id=id).first()
            if table == 'actions':
                query = dbsession.query(Actions).filter_by(id=id).first()
            if query is None:
                flash("Sorry, %s,"
                      " this report does not exists" %
                      session['username'])
                return redirect('/dashboard/')
            else:
                 func(**kwargs)
        return wrapper
    return tags_decorator

Here is the function with the decorator:

app.route('/incidents/edit/<int:id>/', methods=['GET', 'POST'])
@login_required
@owner_required('incidents')
@check_if_report_exists('incidents')
def editIncident(id):
    some code...

Essentially, the route is passing an integer to the function using Flask to call a page with the correct information. I need to use this same number with the decorator to ensure that the user who is logged in is the one who created the page for them to edit it.

I have been following this guide to decorators, specifically the section on Passing Arguments to Decorators.

This was a silly mistake - I was so focused on the wrong decorator. The @login_required did not pass any arguments.

I solved it by passing (*args, **kwargs) to the wrapper and function:

def login_required(session):
    def tags_decorator(func):
        @wraps(func) # this requires an import
        def wrapper(*args, **kwargs):
            logger.info('Checking if user in logged in.')
            if 'username' not in session:
                logger.info('User is not logged in.')
                return redirect('login')
            else:
                logger.info('User is logged in.')
                return func(*args, **kwargs)
        return wrapper
    return tags_decorator

Another mistake I made was not returning the func(), so I received a View Error. I'm assuming this is because I'm using Python 3.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM