Custom decorator in flask not working?
decorator, flask, python
Solution
The other answers seem to be missing that you're getting "bar" as a response from "/foo" when you switch the order of the decorators. You must use `@wraps` here unless you update the `__name__`, `__module__`, and such manually. Flask uses your methods kinda like singletons, and sees your decorator just as the `wrapped()` method, instead of the methods you actually wrapped. Hence, your routes will keep getting overwritten by the last method to use your decorator.
import datetime
from functools import wraps
from flask.app import Flask
app = Flask(__name__)
app.config.from_object(__name__)
app.debug = True
def track_time_spent(name):
def decorator(f):
@wraps(f)
def wrapped(*args, **kwargs):
start = datetime.datetime.now()
ret = f(*args, **kwargs)
delta = datetime.datetime.now() - start
print name, "took", delta.total_seconds(), "seconds"
return ret
return wrapped
return decorator
@app.route('/foo')
@track_time_spent('foo')
def foo():
print "foo"
return "foo"
@app.route('/bar')
@track_time_spent('bar')
def bar():
print "bar"
return "bar"
app.run(host='0.0.0.0', port=8888)
Problem
I have the following code: ``` import datetime from flask.app import Flask app = Flask(__name__) app.config.from_object(__name__) app.debug = True def track_time_spent(name): def decorator(f): def wrapped(*args, **kwargs): start = datetime.datetime.now() ret = f(*args, **kwargs) delta = datetime.datetime.now() - start print name, "took", delta.total_seconds(), "seconds" return ret return wrapped return decorator @app.route('/foo') @track_time_spent('foo') def foo(): print "foo" return "foo" @app.route('/bar') @track_time_spent('bar') def bar(): print "bar" return "bar" ``` I am unable to get foo to return 'foo': ``` $ curl localhost:8888/foo bar (flask window) bar bar took 8.2e-05 seconds 127.0.0.1 - - [18/Apr/2013 19:21:31] "GET /foo HTTP/1.1" 200 - $ curl localhost:8888/bar bar (flask window) bar bar took 3.5e-05 seconds 127.0.0.1 - - [18/Apr/2013 19:21:35] "GET /bar HTTP/1.1" 200 - ``` What's going on? Why isn't my decorator working? EDIT I don't think you guys seem to be able to see the problem. When I have `@app.route` before `@track_time_spent`, both methods return bar. The error here is that calling localhost:8888/foo results in `bar` in both the http response as well as the print function.