-2

I am wondering what the most simple way of running a continuous while loop in flask is.

I have a flask webserver and I have a route that is used for the user to send POST to set a range to keep some sensor values(ex. temperature ) in. My server asks a raspberry pi for the data over mqtt and the pi sends data back and the server puts the data in a text file, then the server opens the text file and some logic is performed on the data. This is the operation I want to do continuously once a POST request with the range is sent.

Currently I am using Redis and RQ. I've watched this tutorial https://www.youtube.com/watch?v=3muR5gB8x2o&t=915s and he uses Flask, Reddis, and RQ to do some tasks. This seems like a workable solution to this problem but I am curious what other people have to say about doing something like this and if redis & RQ is a good option as I am still a relative newbie.

UPDATE: Below is where I am at with redis. I need to pass multiple variables to the redis function and it is causing me problems. Below is my Flask route, redis function, and my error message.

Error:

job = q.enqueue(background_task, kwargs={"_min": ph_min, "_max": ph_max})

    depends_on, job_id, at_front, meta, args, kwargs) = Queue.parse_args(f, *args, **kwargs)
raise ValueError('Functions from the __main__ module cannot be processed 

ValueError: Functions from the __main__ module cannot be processed by workers

Function:

def background_task(_max, _min):
    while _max != "None" and _min != "None":
        publish.single("TOPIC THAT GETS DATA", 1, hostname="IP")
        time.sleep(5)
        print("Data sent to pi")
        with open("data_thread.txt", "r") as file:
            msg = file.readlines()
            msg = msg[0]
            msg = msg.rstrip()
            msg = msg.split(" ")
            ph = msg[0]
            # water_level = msg[1]
            # humidity = msg[2]
            # air_temp = msg[3]
            # timestamp = datetime.now().strftime("%m/%d/%y %I:%M:%S %p")
        if float(ph) > float(_max):  # LOWERS PH IF ITS HIGH
            publish.single("TOPIC", "pump1:on", hostname="IP")
            time.sleep(5)
            publish.single("TOPIC", "pump1:off", hostname="IP")
            print(f"PH was high...lowered at {datetime.now().strftime('%m/%d/%y %I:%M:%S %p')}")
        if float(ph) < float(_min):  # RAISES PH IF ITS LOW
            publish.single("MY TOPIC", "pump2:on", hostname="IP")
            time.sleep(5)
            publish.single("MY TOPIC", "pump2:off", hostname="IP")
            print(f"PH was low...raised at {datetime.now().strftime('%m/%d/%y %I:%M:%S %p')}")

Route:

@app.route('/settings', methods=["GET", 'POST'])
def settings():
    if request.method == "POST" and request.json['ph_range']:
        ph_range = request.json['ph_range']
        print(ph_range['ph_range']['min'])
        with open("ph_range.txt", "w") as file:
            json.dump(ph_range, file)
        ph_min = ph_range['ph_range']['min']
        ph_max = ph_range['ph_range']['max']
        job = q.enqueue(background_task, kwargs={"_min": ph_min, "_max": ph_max})
        q_len = len(q)
        return f"Task {job.id} added to queue at {job.enqueued_at}.  {q_len} tasks in queue"
    return "something went wrong i think lol"
  • It would help if you added in some of your current code. Without that, it makes it a little more difficult to understand the effort/research you have already done. For answers, are you looking for a list of possible approaches, or help with specific issues seen in your threading/looping? – eparham7861 Mar 25 at 23:29
  • my apologies, it is updated. Thank you – Mike Sandstrom Mar 26 at 0:10
  • Is there a specific reason that you are using kwargs for _min and _max? kwargs is geared towards keyword arguments. You should get by with just using args.In the case of background_task(_min, _max), args(ph_min, ph_max) will have the first value as the first argument of the method then proceed to the next value and argument. Also, (python-rq.org/docs) might be a good read for where you are at. The code looks like you are just having syntax issues. Here (github.com/rq/rq/blob/master/rq/queue.py) is a reference where you can find the code behind of the method "enqueue". – eparham7861 Mar 26 at 3:09
  • yea great thank you. I realized after reading the docs and tracescript closer I shouldnt be using kwargs. I also had to put the background task in a seperate file and import into the flask app for it to work as well. hence the "Functions from the main module cannot be processed by workers" error. Thank you for your response – Mike Sandstrom Mar 26 at 3:54

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.