Search code examples
ajaxsessionflaskflask-session

Flask session not passing to different function


I have two functions:

@app.route('/firstfunc', methods = ['POST'])
def firstfunc():
        session['final_box'] = 10
        session.modified = True
        return jsonify("success")
    return jsonify("error")

@app.route('/secondfunc', methods = ['GET','POST'])
def secondfunc():
    if request.method == 'POST':
        final_boxx = session['final_box']
        print("VALUE----------------------->>>>>>", session['final_box'])
    return render_template('some.html', final_boxx = final_boxx)

The AJAX CALL:

$.ajax({
            type: "POST",
            cache: false,
            data:{data:annotation_Jsonstringify,image_height:realHeight,image_width:realWidth,image_name:filename},
            url: "/firstfunc",
            dataType: "json",
            success: function(data) {
                alert(data);
              return true;  
            }
        

    });

The session variable is sent through Ajax. After form submission, when I try to access the session variable, I get this error message.

The Error:

in __getitem__ return super(SecureCookieSession, self).__getitem__(key)
KeyError: 'final_box'

I have come across a number of similar questions in this platform..none was appropriate for this case.
What I have already tried:

  1. session.modified=True after session['final_box']=final_box
  2. app.secret_key was already there
  3. wait for all pending requests to complete in server side

Any pointers or nudge towards solution is appreciated.


Solution

  • This error is because numpy array was tried to pass into JSON format. The built-in python json module can serialize the usual python data structures but cannot do the same for Numpy arrays. For that we need to use a custom json encoder.

    from json import JSONEncoder
    
    class NumpyArrayEncoder(JSONEncoder):
        def default(self, obj):
            if isinstance(obj, numpy.ndarray):
                return obj.tolist()
            return JSONEncoder.default(self, obj)
    
    numpyArrayOne = numpy.array([[11, 22, 33], [44, 55, 66], [77, 88, 99]])
    
    # Serialization
    numpyData = {"array": numpyArrayOne}
    encodedNumpyData = json.dumps(numpyData, cls=NumpyArrayEncoder) 
    
    # Deserialization
    decodedArrays = json.loads(encodedNumpyData)
    

    This way the final_box which is an image array can be sent across functions as a session.