I'm new to pyodide, I decided to try to use it for an open-source educational software:
https://talco-team.github.io/TALightDesktop (live demo)
For the time being I've done my best following the loadPyodide
documentation:
https://pyodide.org/en/stable/usage/api/js-api.html#globalThis.loadPyodide
options.stdin (() => string) – Override the standard input callback. Should ask the user for one line of input.
However, the way the stdin: ()=>{return this.onStdin()}
works makes it hard to use, because the result must be ready before the "stdin" request is generated.
I've tried using Promise, however dyodide doesn't seam to know how to use them.
I'm currently a bit puzzled how how can I suspend execution of pyodide, prompt the user, way for the answer, and restart the execution with the new input. I'm starting to ask myself if active waiting in polling maybe is the only option left.
This is the way I've implemented it:
class PyodideWorker{
let pyodide:any
let stdinBuffer:string[]
...
async initPydiode(){
let options = {
stdin: ()=>{return this.onStdin()},
stdout: (msg:string)=>{this.onStdout(msg)},
stderr: (msg:string)=>{this.onStderr(msg)},
}
this.pyodide = await loadPyodide(options);
}
...
onStdin(){
let cnt = this.stdinBuffer.length
let msg = "";
if(cnt > 0){
let items = this.stdinBuffer.splice(0,cnt)
msg = items.join("")
}
return msg
}
...
sendStdin(request:PyodideRequest){
let response = this.responseFromRequest(request);
let data = request.message.contents[0];
console.log("sendStdin:\n",data)//,res)
if (this.stdinResolver){
this.stdinResolver(this.toString(data))
}else{
this.stdinBuffer.push(this.toString(data))
}
response.message.args = ['true']
return response;
}
}