Forums

AJAX 499 http error

Hi,

I have been having a problem with AJAX HTTP POST requests. I am using the Flask framework with AJAX to communicate between client and server.

When submitting a POST request, it is being received in the Python code, however the response is not being recieved by the client. After waiting 300 seconds, the request times out and I receive a 499 error code (client time out). The code runs fine on my personal machine, so it must be a networking problem.

AJAX code:

function setNetwork(){
  var $SCRIPT_ROOT = {{ request.script_root|tojson|safe }};
  var networkType = document.getElementById("networkSelect").value
  if(networkType != "none"){
  $.ajax({
    type: "POST",
    url: $SCRIPT_ROOT + "/setNetwork/",
    data: networkType,
    success: function(response) {
    console.log(response)
          }
        }
      );
    }
  }

Python code:

@app.route('/setNetwork/',methods=['GET','POST'])
def setNetwork():
'''Set the network to make the prediciton.

Returns:
    The type of network to be used.
'''
data = request.get_data()
print(str(data))
set_network(str(data))
print("setNetwork ok")
return(data)

Access log error code:

 [21/Apr/2018:19:56:55 +0000] "POST /setNetwork/ HTTP/1.1" 499 0 "http://georgelancaster.pythonanywhere.com/guest" "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:59.0) Gecko/20100101 Firefox/59.0" "86.20.42.188" response-time=300.000

I don't think it's specifically a networking problem -- the request is arriving, it's just not getting a response in the 300 second limit. A good way to drill down to find out what's taking up all the time would be to put print statements around each line in the view -- their output will go to the server log, and you can work out where it's blocking.

Thanks Giles,

I found the cause of the problem to be with the Keras library causing the hang, using:

out = model.predict(img)

and

model.load_weights('%s/weights.best.hdf5' % location)

Do you have any experience using Keras with PythonAnywhere as I can't seem to get it working. The code runs fine on my personal machine.

I don't have any experience with it myself, no. The one thing that comes to mind as a possible issue is threading -- it's disabled for websites on PythonAnywhere. Do you think Keras might be trying to start threads?

Thank you, I have tried to limit the number of threads to 1 without any luck. The Keras classifier can make a prediction as the app is starting (by putting the code outside of a function, then restarting the app). The problem only seems to occur once the application is running.

Not sure if this is helpful information or not.

OK, it does sound very much like it's trying to spin off threads, then. When the application is initially loaded, there's only one copy of your code running and threads are enabled (this isn't a deliberate choice on our side, it's just how the server system works). It then forks off the multiple processes needed to run as a live website, and that's when the disabling kicks in. So if it works before the fork happens, and doesn't afterwards, that would certainly be compatible with the hypothesis that it's just hanging when it tries and fails to spin off a thread.

What option did you use to limit the number of threads? Perhaps we can find an alternative way.

I think that Keras has a problem when a model is accessed from a different thread than the one it was created in, which sounds like you were right!

When classifying an image I have used:

graph = tf.get_default_graph()
.
.
.
def pred_test():
    global graph
    img = cv2.imread('0.jpg', 0)
    img = img.reshape(1,28,28,1)
    with graph.as_default():
        res = model.predict(img) #This is the line that hangs.

This appears to have worked for people on the github repo hosting Keras models on similar systems, but it has not yet worked for me.

I have also tried:

import keras.backend.tensorflow_backend as ktf
ktf.set_session(ktf.Session(config=ktf.ConfigProto(intra_op_parallelism_threads=1, inter_op_parallelism_threads=1)))

I would be extremely grateful for any more suggestions you may have.

Update: This problem is solved by changing the Keras back-end to Theano.

Install Theano using

pip install theano

You can change Keras back-end by modifying the keras.json file in /home/your_name/.keras/keras.json

{
"backend": "theano",
"floatx": "float32",
"image_data_format": "channels_last",
"epsilon": 1e-07
}

That's useful -- thanks! Sounds like it must be a tensorflow thing, then -- we'll have to debug a bit more.