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()
...