0

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;
  }
}

Worker: initPydiode

https://github.com/TALCo-Team/TALightDesktop/blob/10fe1580c05840fec1fdb6f8b195430f7dd39b8f/src/app/workers/python-compiler.worker.ts#L140

Worker: onStdin

https://github.com/TALCo-Team/TALightDesktop/blob/10fe1580c05840fec1fdb6f8b195430f7dd39b8f/src/app/workers/python-compiler.worker.ts#L228

Worker: sendStdin

https://github.com/TALCo-Team/TALightDesktop/blob/10fe1580c05840fec1fdb6f8b195430f7dd39b8f/src/app/workers/python-compiler.worker.ts#L404

WorkerController ( for completeness )

https://github.com/TALCo-Team/TALightDesktop/blob/main/src/app/services/python-compiler-service/pydiode-driver.ts

Cesar
  • 4,418
  • 2
  • 31
  • 37
  • your first link doesn't seem to be working – codexistent Jan 19 '23 at 22:51
  • 1
    @codexistent fixed it, sorry – Cesar Jan 20 '23 at 09:08
  • what do you want to do with stdin exactly ? something like "await input()" or access raw stream ? await input see https://pygame-web.github.io/showroom/pypad_git.html?-i#src/test_input.py raw see : https://pygame-web.github.io/showroom/pypad_git.html?-i#src/test_nurses2.py if you target realtime interaction maybe you did not pick the right tool, pyodide's primary goal is scientific stack and notebooks – Pmp P. Jan 22 '23 at 22:26
  • @PmpP. well, what I need is to pipe stdin/stdout via a websocket. On the other end of the websocket there is another process. The 2 processes communicates via stdin/stdout, piped via a websocket. Woud that work? – Cesar Jan 24 '23 at 00:03
  • well i did not test recently, but according https://github.com/pyodide/pyodide/issues/574 websockets are not supported in current build. They should soon since 3.11 has been merged today, but meanwhile you can always try pygbag which is already 3.11 and has some websocket support ( eg it can connect to IRC ). – Pmp P. Jan 24 '23 at 17:51
  • Well, it's not really about websockets, just immagine pyodide and another process communicating using only stdin/stdout – Cesar Jan 25 '23 at 23:30
  • i think you should use different fd (handled without emscripten which anyway treats stdin in a special way) for that and a postmessage infrastructure. also I don't think it's strictly a pyodide "core" subject it looks more of a multiprocessing implementation with iframes – Pmp P. Jan 27 '23 at 21:54
  • Well, truth is that 1 process is pyodide, the one i'm working on, the otherone is on a remote server and is outside my control. I have access to the stdin/stdout streams via websocket ( build on the javascript side ) . I built the connector, so basically now have locally the remote stdin/out and i need to couple them with the one from pyodide.You can see the end result here: https://talco-team.github.io/TALightDesktop/ – Cesar Jan 28 '23 at 07:26

0 Answers0