Search code examples
pythoncookiesflaskreturn

Python Flask not returning cookie / ValueError: View function did not return a response


I am still struggling to pass a string in Python to another function.

I am trying to follow the example given here: https://www.tutorialspoint.com/flask/flask_cookies.htm

I've tried to implement this into my code but I am now getting the following Traceback:

  Traceback (most recent call last):
  File "/Users/marcel/tensorflow/lib/python3.6/site-packages/flask/app.py", line 1982, in wsgi_app
    response = self.full_dispatch_request()
  File "/Users/marcel/tensorflow/lib/python3.6/site-packages/flask/app.py", line 1615, in full_dispatch_request
    return self.finalize_request(rv)
  File "/Users/marcel/tensorflow/lib/python3.6/site-packages/flask/app.py", line 1630, in finalize_request
    response = self.make_response(rv)
  File "/Users/marcel/tensorflow/lib/python3.6/site-packages/flask/app.py", line 1725, in make_response
    raise ValueError('View function did not return a response')
ValueError: View function did not return a response

Which would mean that I am not returning anything, but I can't really see where I'm going wrong and I have to admit I'm quite lost here.

My full code looks like this:

from __future__ import print_function
import tensorflow as tf
import argparse
import os
from six.moves import cPickle
from model import Model
from six import text_type
import flask 
from flask import jsonify, render_template, request, make_response

app = flask.Flask(__name__)


@app.route('/')
def index():
    return render_template('index.html')

@app.route('/test')
def tester():
    return "This is a test"

@app.route('/', methods = ['POST', 'GET'])
def main():
    if request.method == 'POST':
        parser = argparse.ArgumentParser(
                           formatter_class=argparse.ArgumentDefaultsHelpFormatter)
        parser.add_argument('--save_dir', type=str, default='save',
                            help='model directory to store checkpointed models')
        parser.add_argument('-n', type=int, default=500,
                            help='number of characters to sample')
        parser.add_argument('--prime', type=text_type, default=u' ',
                            help='prime text')
        parser.add_argument('--sample', type=int, default=1,
                            help='0 to use max at each timestep, 1 to sample at '
                                 'each timestep, 2 to sample on spaces')

        args = parser.parse_args()

        resp = make_response(render_template('sample.html'))
        resp.set_cookie('args', args)

        return resp


@app.route('/sampler', methods = ['POST', 'GET'])
def sample():
    args = request.cookies.get('args')
    with open(os.path.join(args.save_dir, 'config.pkl'), 'rb') as f:
        saved_args = cPickle.load(f)
    with open(os.path.join(args.save_dir, 'chars_vocab.pkl'), 'rb') as f:
        chars, vocab = cPickle.load(f)
    model = Model(saved_args, training=False)
    with tf.Session() as sess:
        tf.global_variables_initializer().run()
        saver = tf.train.Saver(tf.global_variables())
        ckpt = tf.train.get_checkpoint_state(args.save_dir)
        if ckpt and ckpt.model_checkpoint_path:
            saver.restore(sess, ckpt.model_checkpoint_path)
            if request.method == 'POST':
                text = model.sample(sess, chars, vocab, args.n, args.prime,
                                   args.sample).encode('utf-8')
                resp = make_response(render_template('text.html'))
                resp.set_cookie('verse', text)
                return resp


@app.route('/text')
def printer():    
    verse = request.cookies.get('verse')
    return verse


@app.errorhandler(404)
def page_not_found(error):
    return render_template('404.html'), 404

if __name__ == '__main__':
    main()

before I had tried to just send a cookie from my sample function to the printer function but it returned the same error.

My code before:

def sample(args):
    with open(os.path.join(args.save_dir, 'config.pkl'), 'rb') as f:
        saved_args = cPickle.load(f)
    with open(os.path.join(args.save_dir, 'chars_vocab.pkl'), 'rb') as f:
        chars, vocab = cPickle.load(f)
    model = Model(saved_args, training=False)
    with tf.Session() as sess:
        tf.global_variables_initializer().run()
        saver = tf.train.Saver(tf.global_variables())
        ckpt = tf.train.get_checkpoint_state(args.save_dir)
        if ckpt and ckpt.model_checkpoint_path:
            saver.restore(sess, ckpt.model_checkpoint_path)
            text = model.sample(sess, chars, vocab, args.n, args.prime,
                               args.sample).encode('utf-8')
            resp = make_response(render_template('text.html'))
            resp.set_cookie('verse', text)
            return resp


@app.route('/text')
def printer():    
    verse = request.cookies.get('verse')
    return verse

Solution

  • When verse cookie value is not present the value of the verse variable would become None. Which means that your text view would return None, which Flask does not like and understands as "View function did not return a response".

    You may need to handle this case properly - for instance, simply returning an empty string would fix the problem (of course, this is only a sample easy fix to demonstrate the difference):

    @app.route('/text')
    def printer():    
        return request.cookies.get('verse', '')
    

    Also, not all the code paths in the sample() view return a valid response - make sure to address it as well (for instance, making a GET request to the sample() view would result into the same "View function did not return a response" error).