1

I have two scripts that are running in loop independently: a simple python script that generates data

myData=0
while True:
    myData = get_data() # this data is now available for Flask App

and the flask application that displays data

from flask import Flask
app = Flask(__name__)

@app.route('/')
def hello_world(myData):
    return str(myData)

app.run()

I wish to somehow connect the two scripts, so the application displays the data produced by the python script.

myData=0
app = Flask(__name__)

@app.route('/')
def hello_world(myData):
    return str(myData)

app.run()  # does not return until server is terminated

while True:
    myData = get_data()

When I combine the scripts as shown above, I can see that the execution does not get to the while loop (past app.run() line) until I terminate the app.

I found a similar question here, but not not helpful, and another question here that is identical to what I am trying to do, but it also does not give me any clue. I can not find any info that tells how to make a flask application to communicate with a separately running script. Here's a similar question with no definite answer. Please, give me an insight how these two things should run together, or an example would be greatly appreciated.

Nazar
  • 820
  • 5
  • 13
  • 36
  • 1
    `i` will be incremented to infinity, which will not allow it to be rendered as a string. Are you trying to display a listing of `range(n)`? i.e `[0, 1, 2, 3, 4, 5...]` – Ajax1234 Mar 24 '18 at 17:24
  • @Ajax1234 That was just a conceptual example. I have a python script that is running and generating data. Then I need a flask app to access that data somehow when user requests from the web interface. – Nazar Mar 24 '18 at 17:28
  • @Nazar, if it's just a "conceptual example" then make it stop after a while, say 10 steps. What about [`subprocess.check_output`](https://docs.python.org/3/library/subprocess.html#subprocess.check_output), would this be good for your use case? – Cristian Ciupitu Mar 24 '18 at 17:43
  • What is exactly what are you trying to do? The code from [revision 4](https://stackoverflow.com/revisions/49467581/4) doesn't answer this, it's just some lines of code without much meaning. – Cristian Ciupitu Mar 25 '18 at 15:28
  • @CristianCiupitu I moved on and implemented a flask app in a thread of my main code. This seems to work fine so far, however, I am having trouble properly [terminating the app in the thread](https://stackoverflow.com/questions/49469978/properly-terminate-flask-web-app-running-in-a-thread). – Nazar Mar 25 '18 at 15:44

2 Answers2

1

Since your script keeps generating data indefinitely, I would suggest transforming it into a generator and iterating over it from the web request handler:

def my_counter():
    i = 0
    while True:
        yield i    # I'm using yield instead of return
        i = i + 1

my_counter_it = my_counter()

@app.route('/')
def hello_world():
    return str(next(my_counter_it))  # return next value from generator

You can also communicate with a long running separate process (external command):

import subprocess

def my_counter():
    # run the yes command which repeatedly outputs y
    # see yes(1) or http://man7.org/linux/man-pages/man1/yes.1.html
    p = subprocess.Popen('yes', stdout=subprocess.PIPE)

    # the following can also be done with just one line: yield from p.stdout
    for line in p.stdout:
        yield line
Cristian Ciupitu
  • 20,270
  • 7
  • 50
  • 76
  • I just added the actual script. I think I run the web application in the `try` section, but I see that the entire script executes every second. And I can not terminate it using CTRL+C. Also the script and the app do not currently share the data, however, work fine if run separately. – Nazar Mar 24 '18 at 18:21
  • @Nazar, then keep them separate. Generally speaking, it's good to split an application into smaller pieces. – Cristian Ciupitu Mar 24 '18 at 18:33
  • I agree, but how do I share a dynamically changing variable between the two? I would eventually run them as separate system processes in systemd. – Nazar Mar 24 '18 at 18:35
  • See the `Listener` and `Client` examples from [multiprocessing](https://docs.python.org/3/library/multiprocessing.html) module for an easy way to communicate between two Python programs. – Cristian Ciupitu Mar 24 '18 at 21:22
0

You can create a function that will procedure the data, which can then be served on the route:

def get_data():
  i = 0
  while i < 1000:
    i += 1
  return str(i)

@app.route('/')
def hello_world(): 
   return get_data()
Ajax1234
  • 69,937
  • 8
  • 61
  • 102
  • I probably can not do that since data generation should run constantly, not only when I call `get_data()` in fact the data is being collected from some other sources. I wish I had a more precise question, but I first need to know the proper approach of implementation. – Nazar Mar 24 '18 at 17:36