0

I have a basic flask application, where one of the routes calls a new thread and returns like this:

@app.route("/beginDelivery", methods=["POST"])
def begin_delivery():
if request.get_json(force=True):
    js = request.json
else:
    return jsonify(status=wrong_json())

pid = js['pid']

Thread(target=asynchronously_deliver, args=[pid]).start()
return jsonify(status=0)

Now, in my asynchronously_deliver function, there is a loop that calls send_sms function. send_sms does not have any loop and it ends like this:

#....
#....
print("sending sms...")
rb = urllib.request.urlopen("someurl").read()
rsp = str(rb.decode('utf-8'))

if rsp[0] == '0' and rsp[1] == '0' and rsp[2] == '0' and rsp[3] == '0':
    provider_id = rsp[7:]
    print("provider: success")
else:
    provider_id = '0'
    print("provider: error")
return provider_id

Now, the issue is, that when I examine the console, sometimes, instead of

sending sms...
127.0.0.1 - - [19/May/2016 10:16:54] "GET /someurl HTTP/1.1" 200 -
provider: success

I get

sending sms...
provider: success
127.0.0.1 - - [19/May/2016 10:16:56] "GET /someurl HTTP/1.1" 200 -

Meaning that for some reason, in send_sms both prints where executed before urllib.request.urlopen("someurl").read().

What could be the reason?

EDIT:

I added sleep(10) to my /someurl route and there was a 10 second delay between sending sms... and provider: success. Although, consider this:

127.0.0.1 - - [19/May/2016 11:32:06] "GET /someurl

wasn't printed until 10 seconds elapsed, right before provider:success, therefore, flask doesn't send the message to console until the request is completed and response is returned. Also, that means (I think) that rb = urllib.request.urlopen("someurl").read() is not called asynchronously. Am I wrong?

nicks
  • 2,161
  • 8
  • 49
  • 101
  • 1
    As you said, it's asynchronous. Thus the event occurs whenever the response is received - so it actually is the correct order, printing first what is happening first. – Pinke Helga May 19 '16 at 07:04
  • no, the `send_sms` method itself executes consecutively, without any async calls. – nicks May 19 '16 at 07:12
  • And how is `urllib.request.urlopen("someurl").read()` output? – Pinke Helga May 19 '16 at 07:19
  • what do you mean, how is? – nicks May 19 '16 at 07:19
  • I am sorry, I don't understand your question. How is done what? How is `urllib.request.urlopen().read()` implemented? What does it return? – nicks May 19 '16 at 07:24
  • How does it work? Is it printing a response "127.0.0.1 - - [19/May/2016 10:16:56] "GET /someurl HTTP/1.1" 200 -" asynchronously? I would expect so, since a response can last several seconds under circumstances. – Pinke Helga May 19 '16 at 07:28
  • @Quasimodo'sclone please see question edit – nicks May 19 '16 at 07:36
  • I've absolutely no clue of python, however, that seems logical to me. – Pinke Helga May 19 '16 at 07:38
  • There could also be output buffers obfuscating asynchronous outputs (actually writing to buffer, not directly to screen). – Pinke Helga May 19 '16 at 07:44
  • One more idea: Try redirecting stderr stream to a file. The status message might be streamed to stderr and mixed with stdout. – Pinke Helga May 19 '16 at 08:06

0 Answers0