Concurrency with streamlit

Here’s what I did to get threading working correctly – you were right with the context stuff, it just looks like you didn’t start it low enough in the call stack:

import queue
import threading
import streamlit as st
from streamlit.runtime.scriptrunner import add_script_run_ctx
from streamlit.runtime.scriptrunner.script_run_context import get_script_run_ctx

def thread_task(ctx, in_q, out_q):
    '''
    this runs in a thread, needs a context
    '''
    add_script_run_ctx(ctx) # register context on thread func
    while not in_q.empty():
        job = in_q.get()
        result = do_stuff(job)
        out_q.put(result)
        in_q.task_done()

def run_in_parallel(iterable, func, n_threads=10):
    '''
    not running in a thread; running in main context, spawns threads.
    '''
    ctx = get_script_run_ctx() # create a context
    job_q = queue.Queue()
    for thing in iterable:
        job_q.put(thing)
    out_q = queue.Queue()

    for _ in range(n_threads):
        # pass context to thread
        threading.Thread(target=thread_func, args=(ctx, job_q, out_q), daemon=True).start()

    in_q.join()

...