I am working on my first Flask application. Taking some code directly out of this, I am trying to make sure that a value is present in the user's cookies.
def after_this_request(f): if not hasattr(g, 'after_request_callbacks'): g.after_request_callbacks =  g.after_request_callbacks.append(f) return f @app.after_request def call_after_request_callbacks(response): for callback in getattr(g, 'after_request_callbacks', ()): response = callback(response) return response @app.before_request def detect_unique_id(): unique_id = request.cookies.get('unique_id') if unique_id is None: unique_id = generate_unique_id() @after_this_request def remember_unique_id(response): response.set_cookie('unique_id', unique_id) g.unique_id = unique_id
I keep getting this error:
Traceback (most recent call last): File "/..../env/lib/python2.7/site-packages/flask/app.py", line 1701, in __call__ return self.wsgi_app(environ, start_response) File "/..../env/lib/python2.7/site-packages/flask/app.py", line 1690, in wsgi_app return response(environ, start_response) TypeError: 'NoneType' object is not callable
I am trying to understand the reason for this error. Please help.
remember_unique_id does not return the response object, but
call_after_request_callbacks assigns the result of calling each callback added via the
after_this_request decorator to
result and then returns it. That is to say:
# This for callback in getattr(g, 'after_request_callbacks', ()): response = callback(response) # translates to this for callback in [remember_unique_id]: response = callback(response) # which translates to this response = remember_unique_id(response) # which translates to this response = None
remember_unique_idto return the modified response object
call_after_request_callbacks to check the returned object and make sure it is not None:
for callback in getattr(g, 'after_request_callbacks', ()): result = callback(response) if result is not None: response = result
Flask is a WSGI application under the covers and it expects
response to be a WSGI application (that is, a callable object). When it is handling responses from view templates it runs some checks to make sure that it is being something it can use as a response object and if the returned value is not a WSGI application it converts it to one. It does not check that the response object hasn't been altered by the
after_request decorators, and so when it tries to call the response object (which it assumes is a valid WSGI application at this point) you get the