Python - Returning query result from server to client in Flask










3
















  • What I have



    I have a Client/Server in Flask. The client sends a query in JSON format to the server and the server creates a JSON file. There is another tool which takes this query, executes it on a db and writes the result to a results.txt file. The server periodically checks the 'results' directory for .txt files and if it finds a new file it extracts the result. For the periodic checking part I used APS.



  • What I want to do
    Now I want to send this data (queryResult) which the server has extracted from the .txt file back to the client.


This is what I have done so far.



  • Server Code:


app = Flask(__name__)
api = Api(app)

# Variable to store the result file count in the Tool directory
fileCount = 0

# Variable to store the query result generated by the Tool
queryResult = 0

# Method to read .txt files generated by the Tool
def readFile():
global fileCount
global queryResult
# Path where .txt files are created by the Tool
path = "<path>"
tempFileCount = len(fnmatch.filter(os.listdir(path), '*.txt'))
if (fileCount != tempFileCount):
fileCount = tempFileCount
list_of_files = glob.iglob(path + '*.txt')
latest_file = max(list_of_files, key=os.path.getctime)
print("nLast modified file: " + latest_file)
with open(latest_file, "r") as myfile:
queryResult = myfile.readlines()
print(queryResult) # I would like to return this queryResult to the client

scheduler = BackgroundScheduler()
scheduler.add_job(func=readFile, trigger="interval", seconds=10)
scheduler.start()

# Shut down the scheduler when exiting the app
atexit.register(lambda: scheduler.shutdown())

# Method to write url parameters in JSON to a file
def write_file(response):
time_stamp = str(time.strftime("%Y-%m-%d_%H-%M-%S"))
with open('data' + time_stamp + '.json', 'w') as outfile:
json.dump(response, outfile)
print("JSON File created!")


class GetParams(Resource):
def get(self):
response = json.loads(list(dict(request.args).keys())[0])
write_file(response)

api.add_resource(GetParams, '/data') # Route for GetJSON()

if __name__ == '__main__':
app.run(port='5890', threaded=True)



  • Client Code


data = 
'query': 'SELECT * FROM table_name'


url = 'http://127.0.0.1:5890/data'

session = requests.Session()
retry = Retry(connect=3, backoff_factor=0.5)
adapter = HTTPAdapter(max_retries=retry)
session.mount('http://', adapter)
session.mount('https://', adapter)

resp = session.get(url, params=json.dumps(data))
print(resp)



Can anyone please help me as to how to send this queryResult back to the Client?



EDIT: I would like the server to send the queryResult back to the client each time it encounters a new file in the Tool directory i.e., every time it finds a new file, it extracts the result (which it is doing currently) and send it back to the client.










share|improve this question




























    3
















    • What I have



      I have a Client/Server in Flask. The client sends a query in JSON format to the server and the server creates a JSON file. There is another tool which takes this query, executes it on a db and writes the result to a results.txt file. The server periodically checks the 'results' directory for .txt files and if it finds a new file it extracts the result. For the periodic checking part I used APS.



    • What I want to do
      Now I want to send this data (queryResult) which the server has extracted from the .txt file back to the client.


    This is what I have done so far.



    • Server Code:


    app = Flask(__name__)
    api = Api(app)

    # Variable to store the result file count in the Tool directory
    fileCount = 0

    # Variable to store the query result generated by the Tool
    queryResult = 0

    # Method to read .txt files generated by the Tool
    def readFile():
    global fileCount
    global queryResult
    # Path where .txt files are created by the Tool
    path = "<path>"
    tempFileCount = len(fnmatch.filter(os.listdir(path), '*.txt'))
    if (fileCount != tempFileCount):
    fileCount = tempFileCount
    list_of_files = glob.iglob(path + '*.txt')
    latest_file = max(list_of_files, key=os.path.getctime)
    print("nLast modified file: " + latest_file)
    with open(latest_file, "r") as myfile:
    queryResult = myfile.readlines()
    print(queryResult) # I would like to return this queryResult to the client

    scheduler = BackgroundScheduler()
    scheduler.add_job(func=readFile, trigger="interval", seconds=10)
    scheduler.start()

    # Shut down the scheduler when exiting the app
    atexit.register(lambda: scheduler.shutdown())

    # Method to write url parameters in JSON to a file
    def write_file(response):
    time_stamp = str(time.strftime("%Y-%m-%d_%H-%M-%S"))
    with open('data' + time_stamp + '.json', 'w') as outfile:
    json.dump(response, outfile)
    print("JSON File created!")


    class GetParams(Resource):
    def get(self):
    response = json.loads(list(dict(request.args).keys())[0])
    write_file(response)

    api.add_resource(GetParams, '/data') # Route for GetJSON()

    if __name__ == '__main__':
    app.run(port='5890', threaded=True)



    • Client Code


    data = 
    'query': 'SELECT * FROM table_name'


    url = 'http://127.0.0.1:5890/data'

    session = requests.Session()
    retry = Retry(connect=3, backoff_factor=0.5)
    adapter = HTTPAdapter(max_retries=retry)
    session.mount('http://', adapter)
    session.mount('https://', adapter)

    resp = session.get(url, params=json.dumps(data))
    print(resp)



    Can anyone please help me as to how to send this queryResult back to the Client?



    EDIT: I would like the server to send the queryResult back to the client each time it encounters a new file in the Tool directory i.e., every time it finds a new file, it extracts the result (which it is doing currently) and send it back to the client.










    share|improve this question


























      3












      3








      3


      0







      • What I have



        I have a Client/Server in Flask. The client sends a query in JSON format to the server and the server creates a JSON file. There is another tool which takes this query, executes it on a db and writes the result to a results.txt file. The server periodically checks the 'results' directory for .txt files and if it finds a new file it extracts the result. For the periodic checking part I used APS.



      • What I want to do
        Now I want to send this data (queryResult) which the server has extracted from the .txt file back to the client.


      This is what I have done so far.



      • Server Code:


      app = Flask(__name__)
      api = Api(app)

      # Variable to store the result file count in the Tool directory
      fileCount = 0

      # Variable to store the query result generated by the Tool
      queryResult = 0

      # Method to read .txt files generated by the Tool
      def readFile():
      global fileCount
      global queryResult
      # Path where .txt files are created by the Tool
      path = "<path>"
      tempFileCount = len(fnmatch.filter(os.listdir(path), '*.txt'))
      if (fileCount != tempFileCount):
      fileCount = tempFileCount
      list_of_files = glob.iglob(path + '*.txt')
      latest_file = max(list_of_files, key=os.path.getctime)
      print("nLast modified file: " + latest_file)
      with open(latest_file, "r") as myfile:
      queryResult = myfile.readlines()
      print(queryResult) # I would like to return this queryResult to the client

      scheduler = BackgroundScheduler()
      scheduler.add_job(func=readFile, trigger="interval", seconds=10)
      scheduler.start()

      # Shut down the scheduler when exiting the app
      atexit.register(lambda: scheduler.shutdown())

      # Method to write url parameters in JSON to a file
      def write_file(response):
      time_stamp = str(time.strftime("%Y-%m-%d_%H-%M-%S"))
      with open('data' + time_stamp + '.json', 'w') as outfile:
      json.dump(response, outfile)
      print("JSON File created!")


      class GetParams(Resource):
      def get(self):
      response = json.loads(list(dict(request.args).keys())[0])
      write_file(response)

      api.add_resource(GetParams, '/data') # Route for GetJSON()

      if __name__ == '__main__':
      app.run(port='5890', threaded=True)



      • Client Code


      data = 
      'query': 'SELECT * FROM table_name'


      url = 'http://127.0.0.1:5890/data'

      session = requests.Session()
      retry = Retry(connect=3, backoff_factor=0.5)
      adapter = HTTPAdapter(max_retries=retry)
      session.mount('http://', adapter)
      session.mount('https://', adapter)

      resp = session.get(url, params=json.dumps(data))
      print(resp)



      Can anyone please help me as to how to send this queryResult back to the Client?



      EDIT: I would like the server to send the queryResult back to the client each time it encounters a new file in the Tool directory i.e., every time it finds a new file, it extracts the result (which it is doing currently) and send it back to the client.










      share|improve this question

















      • What I have



        I have a Client/Server in Flask. The client sends a query in JSON format to the server and the server creates a JSON file. There is another tool which takes this query, executes it on a db and writes the result to a results.txt file. The server periodically checks the 'results' directory for .txt files and if it finds a new file it extracts the result. For the periodic checking part I used APS.



      • What I want to do
        Now I want to send this data (queryResult) which the server has extracted from the .txt file back to the client.


      This is what I have done so far.



      • Server Code:


      app = Flask(__name__)
      api = Api(app)

      # Variable to store the result file count in the Tool directory
      fileCount = 0

      # Variable to store the query result generated by the Tool
      queryResult = 0

      # Method to read .txt files generated by the Tool
      def readFile():
      global fileCount
      global queryResult
      # Path where .txt files are created by the Tool
      path = "<path>"
      tempFileCount = len(fnmatch.filter(os.listdir(path), '*.txt'))
      if (fileCount != tempFileCount):
      fileCount = tempFileCount
      list_of_files = glob.iglob(path + '*.txt')
      latest_file = max(list_of_files, key=os.path.getctime)
      print("nLast modified file: " + latest_file)
      with open(latest_file, "r") as myfile:
      queryResult = myfile.readlines()
      print(queryResult) # I would like to return this queryResult to the client

      scheduler = BackgroundScheduler()
      scheduler.add_job(func=readFile, trigger="interval", seconds=10)
      scheduler.start()

      # Shut down the scheduler when exiting the app
      atexit.register(lambda: scheduler.shutdown())

      # Method to write url parameters in JSON to a file
      def write_file(response):
      time_stamp = str(time.strftime("%Y-%m-%d_%H-%M-%S"))
      with open('data' + time_stamp + '.json', 'w') as outfile:
      json.dump(response, outfile)
      print("JSON File created!")


      class GetParams(Resource):
      def get(self):
      response = json.loads(list(dict(request.args).keys())[0])
      write_file(response)

      api.add_resource(GetParams, '/data') # Route for GetJSON()

      if __name__ == '__main__':
      app.run(port='5890', threaded=True)



      • Client Code


      data = 
      'query': 'SELECT * FROM table_name'


      url = 'http://127.0.0.1:5890/data'

      session = requests.Session()
      retry = Retry(connect=3, backoff_factor=0.5)
      adapter = HTTPAdapter(max_retries=retry)
      session.mount('http://', adapter)
      session.mount('https://', adapter)

      resp = session.get(url, params=json.dumps(data))
      print(resp)



      Can anyone please help me as to how to send this queryResult back to the Client?



      EDIT: I would like the server to send the queryResult back to the client each time it encounters a new file in the Tool directory i.e., every time it finds a new file, it extracts the result (which it is doing currently) and send it back to the client.







      python json rest flask client-server






      share|improve this question















      share|improve this question













      share|improve this question




      share|improve this question








      edited Nov 12 '18 at 0:34







      rbh-93

















      asked Nov 12 '18 at 0:09









      rbh-93rbh-93

      5011




      5011






















          1 Answer
          1






          active

          oldest

          votes


















          1














          What you want to do is called a Web Worker Architecture.



          To pass in a real-time abstract queryResult from a background job to a client app you can use a combination of a Message Queue (Kafka is recommended, RabbitMQ is OK too) and a Web-Socket. When a client sends a request to the /data endpoint, you should return back some unique token (like UUID if your user is anonymous, or user id if it's authenticated). The same token you should add to the name of the resulting file. When your background worker finished processing the file it uses the token (from a file's name) to create a Kafka or RabbitMQ topic, like topic_for_user_id_1337 or topic_for_uuid_jqwfoj-123qwr, and publishes queryResult as a message.



          At the same time, your client should establish a web-socket connection (Flask is quite bad for web-sockets, but there are few fine libs to do that anyway, like socketio) and pass the token through it to your backend so it'll create a message queue subscriber, subscribed to a topic with the token's name so when a background job is finished, a web-backend will receive a message and pass it to the user through a web-socket.



          P.S. If it sounds overly complicated, you can avoid the use of MQ and WS and put the queryResult into a db and create a endpoint to check if it exists in a DB. If it's not, you return something like not ready yet and a client retries in a few seconds, if it's ready -- you return the queryResult from the DB.






          share|improve this answer























          • I did not know about the Kafka/Rabbit MQ and Web-Socket approach so I had implemented a workaround something similar to what you mentioned. Instead of a db I just wrote the queryResult to a file and the server checked whether the contents of the file were 'None' or not. If it is, it waits and retries and if not it returns it to the client. But thank you for mentioning the other approach. I will look into it.

            – rbh-93
            Nov 13 '18 at 13:40










          Your Answer






          StackExchange.ifUsing("editor", function ()
          StackExchange.using("externalEditor", function ()
          StackExchange.using("snippets", function ()
          StackExchange.snippets.init();
          );
          );
          , "code-snippets");

          StackExchange.ready(function()
          var channelOptions =
          tags: "".split(" "),
          id: "1"
          ;
          initTagRenderer("".split(" "), "".split(" "), channelOptions);

          StackExchange.using("externalEditor", function()
          // Have to fire editor after snippets, if snippets enabled
          if (StackExchange.settings.snippets.snippetsEnabled)
          StackExchange.using("snippets", function()
          createEditor();
          );

          else
          createEditor();

          );

          function createEditor()
          StackExchange.prepareEditor(
          heartbeatType: 'answer',
          autoActivateHeartbeat: false,
          convertImagesToLinks: true,
          noModals: true,
          showLowRepImageUploadWarning: true,
          reputationToPostImages: 10,
          bindNavPrevention: true,
          postfix: "",
          imageUploader:
          brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
          contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
          allowUrls: true
          ,
          onDemand: true,
          discardSelector: ".discard-answer"
          ,immediatelyShowMarkdownHelp:true
          );



          );













          draft saved

          draft discarded


















          StackExchange.ready(
          function ()
          StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53254508%2fpython-returning-query-result-from-server-to-client-in-flask%23new-answer', 'question_page');

          );

          Post as a guest















          Required, but never shown

























          1 Answer
          1






          active

          oldest

          votes








          1 Answer
          1






          active

          oldest

          votes









          active

          oldest

          votes






          active

          oldest

          votes









          1














          What you want to do is called a Web Worker Architecture.



          To pass in a real-time abstract queryResult from a background job to a client app you can use a combination of a Message Queue (Kafka is recommended, RabbitMQ is OK too) and a Web-Socket. When a client sends a request to the /data endpoint, you should return back some unique token (like UUID if your user is anonymous, or user id if it's authenticated). The same token you should add to the name of the resulting file. When your background worker finished processing the file it uses the token (from a file's name) to create a Kafka or RabbitMQ topic, like topic_for_user_id_1337 or topic_for_uuid_jqwfoj-123qwr, and publishes queryResult as a message.



          At the same time, your client should establish a web-socket connection (Flask is quite bad for web-sockets, but there are few fine libs to do that anyway, like socketio) and pass the token through it to your backend so it'll create a message queue subscriber, subscribed to a topic with the token's name so when a background job is finished, a web-backend will receive a message and pass it to the user through a web-socket.



          P.S. If it sounds overly complicated, you can avoid the use of MQ and WS and put the queryResult into a db and create a endpoint to check if it exists in a DB. If it's not, you return something like not ready yet and a client retries in a few seconds, if it's ready -- you return the queryResult from the DB.






          share|improve this answer























          • I did not know about the Kafka/Rabbit MQ and Web-Socket approach so I had implemented a workaround something similar to what you mentioned. Instead of a db I just wrote the queryResult to a file and the server checked whether the contents of the file were 'None' or not. If it is, it waits and retries and if not it returns it to the client. But thank you for mentioning the other approach. I will look into it.

            – rbh-93
            Nov 13 '18 at 13:40















          1














          What you want to do is called a Web Worker Architecture.



          To pass in a real-time abstract queryResult from a background job to a client app you can use a combination of a Message Queue (Kafka is recommended, RabbitMQ is OK too) and a Web-Socket. When a client sends a request to the /data endpoint, you should return back some unique token (like UUID if your user is anonymous, or user id if it's authenticated). The same token you should add to the name of the resulting file. When your background worker finished processing the file it uses the token (from a file's name) to create a Kafka or RabbitMQ topic, like topic_for_user_id_1337 or topic_for_uuid_jqwfoj-123qwr, and publishes queryResult as a message.



          At the same time, your client should establish a web-socket connection (Flask is quite bad for web-sockets, but there are few fine libs to do that anyway, like socketio) and pass the token through it to your backend so it'll create a message queue subscriber, subscribed to a topic with the token's name so when a background job is finished, a web-backend will receive a message and pass it to the user through a web-socket.



          P.S. If it sounds overly complicated, you can avoid the use of MQ and WS and put the queryResult into a db and create a endpoint to check if it exists in a DB. If it's not, you return something like not ready yet and a client retries in a few seconds, if it's ready -- you return the queryResult from the DB.






          share|improve this answer























          • I did not know about the Kafka/Rabbit MQ and Web-Socket approach so I had implemented a workaround something similar to what you mentioned. Instead of a db I just wrote the queryResult to a file and the server checked whether the contents of the file were 'None' or not. If it is, it waits and retries and if not it returns it to the client. But thank you for mentioning the other approach. I will look into it.

            – rbh-93
            Nov 13 '18 at 13:40













          1












          1








          1







          What you want to do is called a Web Worker Architecture.



          To pass in a real-time abstract queryResult from a background job to a client app you can use a combination of a Message Queue (Kafka is recommended, RabbitMQ is OK too) and a Web-Socket. When a client sends a request to the /data endpoint, you should return back some unique token (like UUID if your user is anonymous, or user id if it's authenticated). The same token you should add to the name of the resulting file. When your background worker finished processing the file it uses the token (from a file's name) to create a Kafka or RabbitMQ topic, like topic_for_user_id_1337 or topic_for_uuid_jqwfoj-123qwr, and publishes queryResult as a message.



          At the same time, your client should establish a web-socket connection (Flask is quite bad for web-sockets, but there are few fine libs to do that anyway, like socketio) and pass the token through it to your backend so it'll create a message queue subscriber, subscribed to a topic with the token's name so when a background job is finished, a web-backend will receive a message and pass it to the user through a web-socket.



          P.S. If it sounds overly complicated, you can avoid the use of MQ and WS and put the queryResult into a db and create a endpoint to check if it exists in a DB. If it's not, you return something like not ready yet and a client retries in a few seconds, if it's ready -- you return the queryResult from the DB.






          share|improve this answer













          What you want to do is called a Web Worker Architecture.



          To pass in a real-time abstract queryResult from a background job to a client app you can use a combination of a Message Queue (Kafka is recommended, RabbitMQ is OK too) and a Web-Socket. When a client sends a request to the /data endpoint, you should return back some unique token (like UUID if your user is anonymous, or user id if it's authenticated). The same token you should add to the name of the resulting file. When your background worker finished processing the file it uses the token (from a file's name) to create a Kafka or RabbitMQ topic, like topic_for_user_id_1337 or topic_for_uuid_jqwfoj-123qwr, and publishes queryResult as a message.



          At the same time, your client should establish a web-socket connection (Flask is quite bad for web-sockets, but there are few fine libs to do that anyway, like socketio) and pass the token through it to your backend so it'll create a message queue subscriber, subscribed to a topic with the token's name so when a background job is finished, a web-backend will receive a message and pass it to the user through a web-socket.



          P.S. If it sounds overly complicated, you can avoid the use of MQ and WS and put the queryResult into a db and create a endpoint to check if it exists in a DB. If it's not, you return something like not ready yet and a client retries in a few seconds, if it's ready -- you return the queryResult from the DB.







          share|improve this answer












          share|improve this answer



          share|improve this answer










          answered Nov 12 '18 at 17:08









          FianFian

          1,3541615




          1,3541615












          • I did not know about the Kafka/Rabbit MQ and Web-Socket approach so I had implemented a workaround something similar to what you mentioned. Instead of a db I just wrote the queryResult to a file and the server checked whether the contents of the file were 'None' or not. If it is, it waits and retries and if not it returns it to the client. But thank you for mentioning the other approach. I will look into it.

            – rbh-93
            Nov 13 '18 at 13:40

















          • I did not know about the Kafka/Rabbit MQ and Web-Socket approach so I had implemented a workaround something similar to what you mentioned. Instead of a db I just wrote the queryResult to a file and the server checked whether the contents of the file were 'None' or not. If it is, it waits and retries and if not it returns it to the client. But thank you for mentioning the other approach. I will look into it.

            – rbh-93
            Nov 13 '18 at 13:40
















          I did not know about the Kafka/Rabbit MQ and Web-Socket approach so I had implemented a workaround something similar to what you mentioned. Instead of a db I just wrote the queryResult to a file and the server checked whether the contents of the file were 'None' or not. If it is, it waits and retries and if not it returns it to the client. But thank you for mentioning the other approach. I will look into it.

          – rbh-93
          Nov 13 '18 at 13:40





          I did not know about the Kafka/Rabbit MQ and Web-Socket approach so I had implemented a workaround something similar to what you mentioned. Instead of a db I just wrote the queryResult to a file and the server checked whether the contents of the file were 'None' or not. If it is, it waits and retries and if not it returns it to the client. But thank you for mentioning the other approach. I will look into it.

          – rbh-93
          Nov 13 '18 at 13:40



















          draft saved

          draft discarded
















































          Thanks for contributing an answer to Stack Overflow!


          • Please be sure to answer the question. Provide details and share your research!

          But avoid


          • Asking for help, clarification, or responding to other answers.

          • Making statements based on opinion; back them up with references or personal experience.

          To learn more, see our tips on writing great answers.




          draft saved


          draft discarded














          StackExchange.ready(
          function ()
          StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53254508%2fpython-returning-query-result-from-server-to-client-in-flask%23new-answer', 'question_page');

          );

          Post as a guest















          Required, but never shown





















































          Required, but never shown














          Required, but never shown












          Required, but never shown







          Required, but never shown

































          Required, but never shown














          Required, but never shown












          Required, but never shown







          Required, but never shown







          Popular posts from this blog

          𛂒𛀶,𛀽𛀑𛂀𛃧𛂓𛀙𛃆𛃑𛃷𛂟𛁡𛀢𛀟𛁤𛂽𛁕𛁪𛂟𛂯,𛁞𛂧𛀴𛁄𛁠𛁼𛂿𛀤 𛂘,𛁺𛂾𛃭𛃭𛃵𛀺,𛂣𛃍𛂖𛃶 𛀸𛃀𛂖𛁶𛁏𛁚 𛂢𛂞 𛁰𛂆𛀔,𛁸𛀽𛁓𛃋𛂇𛃧𛀧𛃣𛂐𛃇,𛂂𛃻𛃲𛁬𛃞𛀧𛃃𛀅 𛂭𛁠𛁡𛃇𛀷𛃓𛁥,𛁙𛁘𛁞𛃸𛁸𛃣𛁜,𛂛,𛃿,𛁯𛂘𛂌𛃛𛁱𛃌𛂈𛂇 𛁊𛃲,𛀕𛃴𛀜 𛀶𛂆𛀶𛃟𛂉𛀣,𛂐𛁞𛁾 𛁷𛂑𛁳𛂯𛀬𛃅,𛃶𛁼

          Crossroads (UK TV series)

          ữḛḳṊẴ ẋ,Ẩṙ,ỹḛẪẠứụỿṞṦ,Ṉẍừ,ứ Ị,Ḵ,ṏ ṇỪḎḰṰọửḊ ṾḨḮữẑỶṑỗḮṣṉẃ Ữẩụ,ṓ,ḹẕḪḫỞṿḭ ỒṱṨẁṋṜ ḅẈ ṉ ứṀḱṑỒḵ,ḏ,ḊḖỹẊ Ẻḷổ,ṥ ẔḲẪụḣể Ṱ ḭỏựẶ Ồ Ṩ,ẂḿṡḾồ ỗṗṡịṞẤḵṽẃ ṸḒẄẘ,ủẞẵṦṟầṓế