Pyodideは、CPythonをWebAssembly(WASM)/Emscriptenにポーティングしたソフトウェア。
PythonがWASMとして動作するので、ブラウザ上でPythonを動かせる。
ドキュメントには実際に動作するREPLのリンクがある。
https://pyodide.org/en/stable/console.html
Pyodideをウェブサイト上で動かす
PyodideはWASMなので、JavaScriptから呼び出して利用可能。
また、CDNでホストされたバージョンもあるため、少し組み込んで使うくらいであれば、少量のコードでできる。
https://pyodide.org/en/stable/usage/quickstart.html
サンプルコード(ドキュメントより抜粋):
<!doctype html> <html> <head> <script src="https://cdn.jsdelivr.net/pyodide/v0.24.1/full/pyodide.js"></script> </head> <body> Pyodide test page <br> Open your browser console to see Pyodide output <script type="text/javascript"> async function main(){ let pyodide = await loadPyodide(); console.log(pyodide.runPython(` import sys sys.version `)); pyodide.runPython("print(1 + 2)"); } main(); </script> </body> </html>
CDNからスクリプトをロードし、 loadPyodide()
でWASMをロード、初期化。その後は runPython()
でPythonコードを実行できる。
サードパーティ製パッケージを動かす
Pyodideでは、micropipというAPIを使って、外部のPythonパッケージを動かすことができる。
Pyodideが標準モジュールをある程度サポートしていることもあり、Pure Pythonで書かれたパッケージであれば、動かすハードルは低め。
標準モジュールの互換性についてもドキュメントに記載がある。
JS側、Python側どちらからでもmicropipを使える。柔軟性は高いように見える。
<script type="text/javascript"> async function main(){ const pyodide = await loadPyodide(); await pyodide.loadPackage("micropip"); const micropip = pyodide.pyimport("micropip"); await micropip.install("regex") } </script>
DjangoのIt works画面をうごかしてみる
では、Djangoを無理矢理うごかしてみる。
<!doctype html> <html> <head> <script src="https://cdn.jsdelivr.net/pyodide/v0.24.1/full/pyodide.js"></script> </head> <body> <script type="text/javascript"> async function main(){ // setup const pyodide = await loadPyodide(); await pyodide.FS.writeFile("/home/pyodide/urls.py", "urlpatterns=[]"); await pyodide.loadPackage("micropip"); const micropip = pyodide.pyimport("micropip"); await micropip.install("Django") // run django app const output = pyodide.runPython(` import io import sys import django from wsgiref.handlers import BaseCGIHandler from django.conf import settings from django.core.handlers.wsgi import WSGIHandler settings.configure( ROOT_URLCONF="urls", SECRET_KEY="dummy", DEBUG=True, ) django.setup() app = WSGIHandler() output = io.BytesIO() env = { "REQUEST_METHOD": "GET", "SERVER_NAME": "pyodide", "SERVER_PORT": "8000", } BaseCGIHandler( sys.stdin.buffer, output, sys.stderr, env, multithread=False ).run(app) response = output.getvalue().decode("utf-8") "".join(response.splitlines()[2:]) `); document.open(); document.write(output); document.close(); } main(); </script> </body> </html>
Pyodideを初期化してからDjangoをインストール、その後WSGIハンドラを実行している。
実行すると、ブラウザ上でDjangoを実行して、It worksの画面が表示される。