Home > Blockchain >  What is the benefit of **kwargs in this wrapper function?
What is the benefit of **kwargs in this wrapper function?

Time:10-11

The following function was provided as part of an example in an introduction to web development:

def login_required(view):
    @functools.wraps(view)
    def wrapped_view(**kwargs):
        if g.user is None:
            return redirect(url_for('login'))
        return view(**kwargs)
    return wrapped_view

The function which this is called on takes no arguments:

@app.route('/topsecret')
@login_required
def top_secret():
    return f'<H1>Really top secret stuff!</H1>'

So what is the point in there being a **kwargs parameter here? Is it simply to allow the function to be more flexible if future functions use the wrapper and have parameters?

The following is the whole code for reference:

from flask import Flask, url_for, request, redirect, make_response, session, \
     render_template, g
import functools
import secrets

app = Flask(__name__)
app.secret_key = secrets.token_urlsafe(32)

@app.before_request
def user_logged_in():
    user_id = session.get('username')
    if user_id == None:
        g.user = None
    else:
        g.user='set'
        
def login_required(view):
    @functools.wraps(view)
    def wrapped_view(**kwargs):
        if g.user is None:
            return redirect(url_for('login'))
        return view(**kwargs)
    return wrapped_view

@app.route('/')
def index():
    if 'username' in session:
        return f'Logged in as {session["username"]}'
    return 'You are not logged in.'

@app.route('/login', methods=['GET', 'POST'])
def login():
    if request.method == 'POST':
        session['username'] = request.form['username']
        return redirect(url_for('index'))
    return '''
        <form method="post">
            <p><input type=text name=username>
            <p><input type=submit value=Login>
        </form>
        '''

@app.route('/logout')
def logout():
    session.pop('username', None)
    return redirect(url_for('index'))

@app.route('/topsecret')
@login_required
def top_secret():
    return f'<H1>Really top secret stuff!</H1>'

@app.route('/notsosecret')
def notsosecret():
    return f'<H1>Not so important stuff</H1>'

CodePudding user response:

So what is the point in there being a **kwargs parameter here? Is it simply to allow the function to be more flexible if future functions use the wrapper and have parameters?

Yes. Flask handlers can receive keyword arguments (and only keyword arguments) via route parameters. If you want login_required to work with such handlers it needs to forward the arguments along.

Consider:

@app.route('/topsecret/<key>')
@login_required
def top_secret(key="007"):
    return f'<H1>Really top secret stuff for {key}!</H1>'
  • Related