I'm working with the pyodide library and i've ran into an issue, I need to add a handler for stdin, however I'm running pyodide in a web worker and I don't have access to the window or any sort of prompt.
pyodide.setStdin({ stdin: () => {
// code here
}})
I have tried using the postMessage() function to ask the page for input and send it back, but since I am returning this from a function I am unable to receive the input before I have to return. I have also tried using SharedArrayBuffer and Atomics to freeze the web worker until the page responds, but I was unable to figure out a solution with those, however I think it's a good starting point. Most solutions I've seen so far have just been to restructure code, but since pyodide is an external library I am forced to return from the function I set in pyodide.setStdin
-
Related: Pyodide - UI input instead of promptggorlen– ggorlen2025年03月31日 21:27:12 +00:00Commented Mar 31, 2025 at 21:27
1 Answer 1
I found out how to solve this problem, so I thought I'd post it. I did end up using SharedArrayBuffers with Atomics. Andrea Giammarchi had a great article on passing strings between threads, but basically I would pass a buffer through postMessage to the main thread asking for the length of the string, then use Atomics.wait to pause until the worker recieved the length. I then would use that to make another buffer and pass it like before but instead encode a string into the buffer and decode it from the worker. The attached Medium article explains it better than I can.
1 Comment
await so its message pump is checked. At this point the UI thread may send the prompt in a new message. Upon reception, the prompt data resolves the promise being awaited and the process resumes.