#MultiThreading in #Python #Flask Web API

First of all, a real-world scenario, before we dig into a simplified code demo to show a generic solution. Let’s say that we want to implement a web site and connect it to a third party Web API (either weather or trading or what you prefer) and on top of that we want to keep track of the api results in an internal db for their versioning .

The idea

The high level solution is that you call the API online and you retrieve the expected result also from your previously saved data history in your app db. Then if they are different, you insert a new history record. So far, very cool idea, now imagine an optimization. The first two data retrieval operations – from the third party api and from your db – can go parallel with two IO threads. Finally you will do the comparison and eventually save if it is needed. To simplify the code, let’s just do a trivial int sum instead of the comparison in the real business logic and let’s make an effectful code that writes to a log instead of a real db.

Enters python Flask

From the user point of view you want to return the async Flask API to the browser ASAP. In the above scenario, you simply want to return the first third party API result as soon as it completes. Hence the conclusion is that you will write another thread to wait the DB operation of the second thread and finally compose their results (comparing the result of the third part API from the first thread with the result from your db history from the second thread), so that you can return from Flask API in the shortest possible time. Find below my module for this demo:

import threading
import time

class ThirdParty(threading.Thread):
     def __init__(self,low,high):
         super(ThirdParty, self).__init__()
         self.low=low
         self.high=high
         self.total=0

     def run(self):
         #call the third party API
         self.total = #retrieve the result

class ComparingThread(threading.Thread):
     def __init__(self,total1,thread2,logger):
         super(ComparingThread, self).__init__()
         self.total1=total1
         self.thread2=thread2
         self.result=0
         self.logger=logger

     def run(self):
         self.thread2.join()
         # At this point, both threads have completed
         self.result = self.total1 - self.thread2.total
         # compare the results and save the update to DB accordingly
         time.sleep(10)
         self.logger (self.result)

def test_threading(logger): #app.logger.info
    thread1 = ThirdParty(0,500000)
    thread2 = RetrieveFromDB(0,500000)
    thread1.start() # This actually causes the thread to run
    thread2.start()
    thread1.join()  # This waits until the thread has completed
    thread3 = ComparingThread(thread1.total,thread2,logger)
    thread3.start()
    logger('return flask result to users\'s browser thread 1: ' + str(thread1.total))
    return "client side done now!"

And here it is the Flask server part:

@app.route("/flask/api/threadtest")
def thread_test():
    return flaskthread.test_threading(app.logger.info)
    

Finally the client javascript:

function myFunction() {
  document.getElementById("demo_threading").innerHTML = "test multi-threading log: started...";
      var ipThreading = "/flask/api/threadtest";
      $.ajax({
          url: ipThreading
        })
        .done(function( data ) {
          console.log( "ipThreading data", data );
          var d = new Date();
          var n = d.toLocaleTimeString();
          document.getElementById("demo_threading").innerHTML = n + " - test multi-threading log: " + data;
        })
        .fail(function(e) {
          document.getElementById("demo_threading").innerHTML = "test multi-threading log: " + data;
        })
        .always(function() {
          var d = new Date();
          var n = d.toLocaleTimeString();
          console.log( n + " - ipThreading complete" );
        });
    };
Advertisement

One thought on “#MultiThreading in #Python #Flask Web API

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s