Running multipl long running scripts from streamlit

Here’s a quick example of running long running scripts using our lovely Steamlit:

import subprocess
import psutil
import datetime

fname = "procs.csv"
class ProcessManager:    
    def processes(self):        # rslt = None        
        if not os.path.exists(fname):
            df = pd.DataFrame(columns = ['filename','proc_id'])
            df.to_csv(fname)
        df = pd.read_csv(fname)
        df = df.loc[:,~df.columns.str.match("Unnamed")]
        return df

    def append_row(self, filename, pid):
        new_row = pd.Series({'filename': filename, 'proc_id': pid})
        df = append_row(self.processes(), new_row)
        df.to_csv(fname)
    def start_process(self, filename):
        process = subprocess.Popen(['python', 'client_main.py', filename])
        print(f"start process.pid = {process.pid}")
        self.append_row(filename, process.pid)

    def stop_process_v2(self, pid):
        try:
            pid = int(pid)
            psutil_process = psutil.Process(pid)
            psutil_process.terminate()
            st.write(f"stop process.id = {pid}")
        except Exception as xcp:
            print_exception(xcp)
        self.remove_pid(pid) 
        st.write(f"remove_pid = {pid}")

    def remove_pid(self, pid):
        df = self.processes()
        cond_pid = df['proc_id']==pid
        if len(df.loc[cond_pid])>0:
            df = df.loc[df['proc_id']!=pid]    
            df.to_csv(fname)       
            st.write(f"pid = {pid} removed successfully in local file")
        else:
            st.write(f"pid = {pid} not in local file")

manager = ProcessManager()
def on_start_all_processes():
    df = manager.processes()
    c1, c2 = st.columns(2)
    for filename in filenames_inputs_csv_for_proc_mon : #filenames:
        manager.start_process(filename)
    df = manager.processes()

filenames_inputs_csv_for_proc_mon = None
def proc_manager_v2():
    manager = ProcessManager()
    inputs_file = 'inputs.csv'

    df = ... fill with your dataframe here... #get_symbols_from_inputs(inputs_file)

    lst_fns = []
    for indx, row in df.iterrows():                 
        fn = ''
        fn += f"{indx}_{row['symbol']}_"
        fn += f"{datetime.date.today()}"
        fn += ".csv"
        fn = fn.replace('\n','')
        print(fn)   
        lst_fns.append(fn)         
        row.to_frame().T.to_csv(fn)            
    filenames = lst_fns * 5
    global filenames_inputs_csv_for_proc_mon 
    filenames_inputs_csv_for_proc_mon = filenames
    all_process_started = False
    df = manager.processes()
    st.write(df)
    if st.button('Start all'):
        on_start_all_processes()    
    if st.button('Stop all'):
        df = manager.processes()
        c1, c2 = st.columns(2)
        with c1:
            st.write(df, "df B4 Stop All")
        
        for i, row in df.iterrows():
            pid = row['proc_id']
            manager.stop_process_v2(pid)
        with c2:
            df = manager.processes()
            st.write(df, "df A4 Stop All")
    else:
        st.write('Please click button')
    lst_procs = manager.processes()
    lst_proc_ids = ['Stop All']
    df = manager.processes()
    if len(df)>0:
        for i, row in df.iterrows():
            lst_proc_ids.append(f"{row['filename']}_{row['proc_id']}")

        stm = st.multiselect('Select to stop process', lst_proc_ids)
        if stm:
            for e_fn_pid in stm:
                c1, c2 = st.columns(2)
                with c1:
                    st.write(df, f"B4 stop {stm}")
                arr = e_fn_pid.split('.csv_')
                pid = arr[1]
                st.write(f'Begin Stop process {get_current_time()}')
                manager.stop_process_v2(pid)
                st.write(f'End Stop process {get_current_time()}')
                df = manager.processes()
                with c2:
                    st.write(df, f"A4 stop {stm}")
    else:
        st.write('No Processes in progress')

if st.checkbox('Process Manager'):
    proc_manager_v2()