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.

Original source