웹 어셈블리를 사용하여 브라우저에서 Python 실행



게시물Running Python in the Browser with Web AssemblyQvault에 처음 등장했습니다.

우리는 확장Qvault’s course curriculum을 원했고 가장 많이 요청된 프로그래밍 언어 중 하나는 Python이었습니다. 우리 과정을 통해 학생들은 웹 브라우저에서 바로 코드를 작성하고 실행할 수 있으므로 웹 어셈블리를 사용하여 브라우저에서 Python 인터프리터를 실행할 수 있는 기존 프로젝트를 조사하기로 결정했습니다. 우리는 Pyodide 이라는 도구를 사용했습니다.

실제로 작동하는 것을 보려면 finished product, a Python playground 을 확인하십시오.

파이오다이드란?



Pyodide는 웹 어셈블리로 컴파일된 Python 인터프리터로 구성된 오픈 소스 프로젝트입니다.

WebAssembly (abbreviated Wasm) is a binary instruction format for a stack-based virtual machine. Wasm is designed as a portable compilation target for programming languages, enabling deployment on the web for client and server applications.

webassembly.org



즉, 일반적으로 JavaScript만 브라우저에서 실행할 수 있지만 소스 코드를 Wasm으로 컴파일할 수 있으면 브라우저에서 모든 프로그래밍 언어를 실행할 수 있습니다. (이 글을 쓰는 시점에 우리는 playgroundcourses에서 Python, Rust 및 Go를 이런 방식으로 실행합니다.)

Pyodide brings the Python 3.8 runtime to the browser via WebAssembly, along with the Python scientific stack including NumPy, Pandas, Matplotlib, parts of SciPy, and NetworkX. The packages directory lists over 35 packages which are currently available.

Github Project



우리는 그것을 어떻게 했습니까?



Python 실행 계획은 브라우저에서 Go 코드를 실행하는 방식과 매우 유사합니다. 기본적으로 세 단계가 있습니다.
  • 코드 실행 방법을 정의하는 작업자 파일 작성
  • 작업자 가동, 통신 및 종료의 세부 사항을 추상화하는 작업자 도우미 작성
  • 사용자가 코드를 실행하고 코드의 출력을 볼 수 있도록 보기에서 도우미를 구현합니다
  • .

    모든 작동 방식을 알고 싶다면 this article about Web Workers and WASM in Go before continuing.을 읽어 보십시오.

    Web Workers에 대한 첫 번째 기사를 마쳤다면 Python과 Go 로직의 차이점을 이해하기 위해 필요한 것은 작업자 파일 자체뿐입니다.

    // pull down pyodide from the public CDN
    importScripts('https://pyodide-cdn2.iodide.io/v0.15.0/full/pyodide.js');
    
    addEventListener('message', async (e) => {
      // wait for the interpreter to be fully loaded
      await languagePluginLoader;
    
      self.runPythonWithStdout = () => {
        try {
          // execute the code passed to the worker
          pyodide.runPython(e.data);
        } catch (err){
          postMessage({
            error: err
          });
          return;
        }
    
        // capture the code's standard output
        // and send it back to the main thread
        let stdout = pyodide.runPython("sys.stdout.getvalue()")
        if (stdout) {
          stdout = stdout.split('\n')
          for (line of stdout){
            postMessage({
              message: line
            });
          }
        }
      }
    
      // redirect stdout to io.StringIO so that we can get it later
      pyodide.runPython(`
        import io, code, sys
        from js import runPythonWithStdout
        sys.stdout = io.StringIO()
        sys.stderr = io.StringIO()
        ## This runs self.runPythonWithStdout defined in the JS
        runPythonWithStdout()
      `)
    
      postMessage({
        done: true
      });
    }, false);
    


    보시다시피 우리 사용 사례에서 특별히 어려운 부분은 코드의 표준 출력을 적절하게 캡처하기 위해 접착제를 추가하는 것이었습니다.

    읽어 주셔서 감사합니다!



    질문이나 의견이 있으면 Twitter에서 팔로우하세요.

    좀 가져가 coding courses on our new platform

    Subscribe 더 많은 프로그래밍 기사를 보려면 뉴스레터로

    좋은 웹페이지 즐겨찾기