pythonpython-multithreadingbackground-thread

how to keep UI from waiting for a thread to complete in python flask?


I have a program that takes audio files and processes it.

@app.route('/', methods=['GET', 'POST'])
def hello_world():
    if request.method == 'GET':
        return render_template('upload.html')
    else:
        file = request.files['file']
        path = os.getcwd() + '\\tempFilesAudio\\'
        if not os.path.exists(os.getcwd() + '\\' + 'tempFilesAudio'):
            os.mkdir(os.getcwd() + '\\' + 'tempFilesAudio')
        if not os.path.exists(os.getcwd() + '\\' + 'tempFilesTransciption'):
            os.mkdir(os.getcwd() + '\\' + 'tempFilesTransciption')
        file.save(path + secure_filename(file.filename))
        file_path = path + file.filename
        conv_path = convert(file_path)
        print('converted:{}'.format(conv_path))
        #this is a thread
        Recogniser(conv_path)
        print('Deleting MP3')
        os.remove(file_path)
        print('Deleting WAV')
        os.remove(conv_path)
        return render_template('upload.html')

I want my UI to be re-rendered after the files have been submitted to the thread for processing in the background. But it still keeps waiting.

Below is the code for my thread:



class Recogniser:

    def __init__(self, file):
        self.executor = ThreadPoolExecutor(5)
        self.file = file
        thread = threading.Thread(target=self.run(), daemon=True, args=file)
        thread.start()

    def run(self):
       #something

Solution

  • Create the Recogniser class like this:

    class Recogniser(threading.Thread):
        def __init__(self, file):
            self.file = file
            super().__init__()
    
        def run(self):
           #something
           pass
    

    Then, start the thread like this:

    thread_list = {}
    @app.route('/', methods=['GET', 'POST'])
    def hello_world():
        global thread_list
        # ... other logic ...
        thread_id = "generate some id"
        thread_list[thread_id] = Recogniser(file)
        thread_list[thread_id].start()
        # ... more logic ...
        return render_template('upload.html')
    

    Note: The proper way would probably involve caching/saving thread IDs to the DB etc. But this should work for simpler apps.