EndenDragon EndenDragon - 4 months ago 25
Python Question

How do I pass in an argument to decorators?

I cannot seem to get the decorator thing to work. It keeps giving me error that another function is overwriting. Here is what I did,

def print_api_bool(api=False):
def decorator(f):
@wraps(f)
def decorated_function(*args, **kwargs):
print api # Prints the api boolean to console
return f(*args, **kwargs)
return decorated_function
return decorator

@fetch.route("/apipage")
@print_api_bool(api=True)
def a():
return "api"


But when starting flask, it throws this error:

Traceback (most recent call last):
File "run.py", line 2, in <module>
from apiapi.app import app
File "/var/www/python/apiapi.py", line 16, in <module>
app.register_blueprint(blueprints.fetch.fetch, url_prefix="/fetch")
File "/Library/Python/2.7/site-packages/Flask-0.10.1-py2.7.egg/flask/app.py", line 62, in wrapper_func
return f(self, *args, **kwargs)
File "/Library/Python/2.7/site-packages/Flask-0.10.1-py2.7.egg/flask/app.py", line 889, in register_blueprint
blueprint.register(self, options, first_registration)
File "/Library/Python/2.7/site-packages/Flask-0.10.1-py2.7.egg/flask/blueprints.py", line 153, in register
deferred(state)
File "/Library/Python/2.7/site-packages/Flask-0.10.1-py2.7.egg/flask/blueprints.py", line 172, in <lambda>
s.add_url_rule(rule, endpoint, view_func, **options))
File "/Library/Python/2.7/site-packages/Flask-0.10.1-py2.7.egg/flask/blueprints.py", line 76, in add_url_rule
view_func, defaults=defaults, **options)
File "/Library/Python/2.7/site-packages/Flask-0.10.1-py2.7.egg/flask/app.py", line 62, in wrapper_func
return f(self, *args, **kwargs)
File "/Library/Python/2.7/site-packages/Flask-0.10.1-py2.7.egg/flask/app.py", line 984, in add_url_rule
'existing endpoint function: %s' % endpoint)
AssertionError: View function mapping is overwriting an existing endpoint function: fetch.decorator


Is flask overwriting the functions or what? How would I fix the error so the decorator can take in arguments?

Answer

You decorator works alright, here is a Demo:

>>> from functools import wraps
>>> 
>>> def p(api=False):
    def decorator(f):
        @wraps(f)
        def decorated_f(*args, **kwargs):
            print(api)
            return f(*args, **kwargs)
        return decorated_f
    return decorator

>>> @p(api=True)
def a():
    return 'api'

>>> a()
True
'api'

The error is probably related to something else:

Traceback (most recent call last):
  File "run.py", line 2, in <module>
    from apiapi.app import app
  -> File "/var/www/python/apiapi.py", line 16, in <module>
    app.register_blueprint(blueprints.fetch.fetch, url_prefix="/fetch")

I would suspect that you must be defining this route @fetch.route("/apipage") more than one in your code.

Comments