Pyodideを使ってみる その2(Node.jsでの実行)
はじめに
今回はNPMに公開されているPyodideのパッケージを試してみました。
Node.jsで実行できれば、Node-REDでも利用できそうです。
▼以前の記事はこちら
サンプルの実行
NPMのページにサンプルコードがあったので、パッケージをインストールして実行してみました。
▼こちらのページです。
https://www.npmjs.com/package/pyodide
先にnpm initを実行して、package.jsonを作成しておきました。
▼ノードを開発するためのGitHubのリポジトリも作成しておきました。

NPMのPyodideパッケージをインストールしました。
npm install pyodide
この状態でhello_python.jsを保存して実行したところ、エラーが起きました。
▼モジュールが見つからないというエラーが起きています。

元々のサンプルコードではindexURLが<pyodide artifacts folder>になっていました。ここを置き換える必要があります。
npmモジュールとしてインストールしたので、node_modeulesフォルダにpyodideがインストールされています。そのパスをindexURLとして渡すと実行できました。
以下のコードを実行しました。
//https://www.npmjs.com/package/pyodide
const { loadPyodide } = require("pyodide");
async function hello_python() {
let pyodide = await loadPyodide({
indexURL: "node_modules/pyodide/",
});
return pyodide.runPythonAsync("1+1");
}
hello_python().then((result) => {
console.log("Python says that 1+1 =", result);
});
▼Pythonのコードでの計算結果が出力されています。

REPLでの実行も試してみました。以下のコマンドでNode.jsのREPLが有効になります。
node --experimental-repl-await
▼pyodideを読み込んでから、実行することができています。

▼print("hello")もNode.jsで実行できました。

パッケージを利用して実行する
前回の記事ではブラウザ上でmatplotlibを利用して、グラフを表示するようにしていました。
そのコードをベースに、Node.jsで実行できるコードをChatGPTに書いてもらいました。
const { loadPyodide } = require("pyodide");
const fs = require("fs").promises;
async function plotAndSave() {
const pyodide = await loadPyodide({ indexURL: "node_modules/pyodide/" });
await pyodide.loadPackage("matplotlib");
const b64 = await pyodide.runPythonAsync(`
import matplotlib
matplotlib.use('AGG')
import matplotlib.pyplot as plt
import io, base64
fig, ax = plt.subplots()
ax.plot([1,2,3,4], [10,20,15,25], marker='o')
ax.set_title("Test Graph")
buf = io.BytesIO()
fig.savefig(buf, format='png')
buf.seek(0)
base64.b64encode(buf.read()).decode('ascii')
`);
const buffer = Buffer.from(b64, "base64");
await fs.writeFile("graph.png", buffer);
console.log("✅ graph.png saved.");
}
plotAndSave().catch(console.error);
Pyodideで出力された画像は、Base64を経由してNode.js側に渡されています。ファイルの保存のように、OSの機能を利用する部分はNode.js側で実行しています。
実際に実行してみました。
▼必要なパッケージ関連のファイルがダウンロードされました。

▼pyodideパッケージのフォルダに追加されています。

▼実行結果のグラフが、pngファイルとして保存されていました。

もう一度実行してみました。
▼ダウンロードは行われず、ダウンロード済みのものを読み込んで実行されました。

pyodideフォルダの容量を確認してみました。
▼25.8MBになっています。

数MBサイズのwhlファイルやwasmファイルがあったので、利用するパッケージが増えると容量が増えそうです。
最後に
Node.jsで実行できたので、Node-REDでも利用できるようにノード化しようかなと思っています。
functionノードのようにPyodideでPythonのコードを実行することができそうです。私が開発したpython-venvノードとは違って、Pythonのインストールが不要になります。