Thanks to what I learned from this question, I've been able to make a Flask-Login process with a endpoint like this:
@app.route('/top_secret')
@authorize
@login_required
def top_secret():
return render_template("top_secret.html")
and (for now) a completely pass-through "authorize" decorator:
from functools import wraps
def authorize(func):
@wraps(func)
def newfunc(*args, **kwargs):
return func(*args, **kwargs)
return newfunc
The @wraps(func)
call allows Flask to find the endpoint that it's looking for. So far, so good.
But I want to pass an group name to the "authorize" process, and things go bad when I try to make a decorator that accepts incoming parameters. This seems to be the correct syntax, unless I'm mistaken:
from functools import wraps
def authorize(group=None):
def real_authorize(func):
@wraps(func)
def newfunc(*args, **kwargs):
return func(*args, **kwargs)
return newfunc
return real_authorize
But once again the error appears as Flask is unable to figure out the 'top-secret' endpoint:
werkzeug.routing.BuildError: Could not build url for endpoint 'top_secret'.
I thought perhaps it needed @wraps(authorize)
decoration right above def real_authorize(func)
, but that did nothing to help.
Can someone help me figure out where my @wraps
are going wrong?
Decorating a function is equivalent to re-binding the name to the result of calling the decorator with the function.
The function you've written is a decorator factory: you call it, with an optional argument, to get a decorator.
Currently, you're passing
top_secret
as thegroup
argument to the factory, so you're never actually creating a route. Since there's no route, there's no url to build either.