The error collected in the previous run raised in the current run

I run the code by using Python 3.9 and streamlit==1.32.0. I have the next code snippet -

import threading
import time
import os
import ctypes

import streamlit as st
from streamlit_option_menu import option_menu

from syngen.streamlit_app.handlers import StreamlitHandler
from syngen.streamlit_app.utils import (
    show_data,
    get_running_status,
    set_session_state,
    cleanup_artifacts
)


class ThreadWithException(threading.Thread):
    """
    A class for a thread with the ability to raise an exception
    """

    def get_id(self):
        if hasattr(self, "_ident"):
            return self._ident

    def raise_exception(self):
        thread_id = self.get_id()
        res = ctypes.pythonapi.PyThreadState_SetAsyncExc(thread_id,
                                                         ctypes.py_object(SystemExit))
        if res > 1:
            ctypes.pythonapi.PyThreadState_SetAsyncExc(thread_id, 0)


def stop_running_thread():
    """
    Stop the running thread
    """
    thread = [
        thread
        for thread in threading.enumerate()
        if thread.name == "train_and_infer"
    ]
    if thread:
        runner = thread[0]
        runner.raise_exception()
        runner.join()
        return runner
    return None


def run_basic_page():
    """
    Run the basic page of the Streamlit app
    """
    set_session_state()
    uploaded_file = st.file_uploader(
        "Upload a CSV file",
        type="csv",
        accept_multiple_files=False,
        disabled=get_running_status()
    )
    if not uploaded_file:
        runner = stop_running_thread()
        if runner and not runner.is_alive():
            st.warning("The training and the generation were interrupted")
        cleanup_artifacts()
        st.warning("Please upload a CSV file to proceed")
    if uploaded_file:
        show_data(uploaded_file)
        epochs = st.number_input(
            "Epochs",
            min_value=1,
            value=1,
            disabled=get_running_status()
        )
        size_limit = st.number_input(
            "Rows to generate",
            min_value=1,
            max_value=None,
            value=1000,
            disabled=get_running_status()
        )
        print_report = st.checkbox(
            "Create an accuracy report",
            value=False,
            key="print_report",
            disabled=get_running_status()
        )
        app = StreamlitHandler(epochs, size_limit, print_report, uploaded_file)
        if st.button(
                "Generate data", type="primary", key="gen_button", disabled=get_running_status()
        ):
            runner = ThreadWithException(name="train_and_infer", target=app.train_and_infer)
            runner.start()
            current_progress = 0
            prg = st.progress(current_progress)

            while runner.is_alive():
                with st.expander("Logs"):
                    while True:
                        if not app.log_queue.empty():
                            with st.code("logs", language="log"):
                                log = app.log_queue.get()
                                st.text(log)
                                current_progress, message = app.progress_handler.info
                                prg.progress(value=current_progress, text=message)
                        elif not app.log_error_queue.empty():
                            runner.raise_exception()
                            runner.join()
                            break
                        elif not runner.is_alive():
                            break
                        time.sleep(0.001)
            if not app.log_error_queue.empty() and not runner.is_alive():
                st.exception(app.log_error_queue.get())
            elif app.log_queue.empty() and not runner.is_alive():
                prg.progress(100)
                st.success("Data generation completed")

        with st.container():
            app.generate_buttons()


def run():
    """
    Run the Streamlit app
    """
    with st.sidebar:
        selected = option_menu("", ["Basic"],
                               icons=["'play'"],
                               default_index=0,
                               menu_icon=None,
                               styles={
                                   "container": {"font-family": "Open Sans"}
                               }
                               )
    if selected == "Basic":
        run_basic_page()


if __name__ == "__main__":
    run()

If the running thread is interrupted, it will be killed, but in the next running thread, the error log messages from the previous thread are sent and cause the error. Could you please provide the reasons why it happens?

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.