Node-REDを使用していると、偶にこのPythonの処理をそのまま埋め込めればいいのになと思うことがあります。
自分も以前のエントリでwordcloudの画像生成に関して拡張ノードがなかったのでexecノードを使用して回避したことがありました。
参考
このときには、モジュールがコマンドライン(CLI)で実行できるようになっていたので、その方法が良かったのかもしれないなと思ったのですが、いろいろ調べてみるとpythonのコード記述ができるpython-functionノードというものがあるとわかりました。今回はそれの使い方について見てみようと思います。
拡張ノードのインストール
今回使用する拡張ノードはnode-red-contrib-python-functionという名前です。
このノードのドキュメントにもありますが以下の注意点があるようです。
(注意)保証されるものではないのでプロダクトでは使用しないのは前提となります。
In any case, this quick hacked node will let you write functions using Python instead of Javascript! How cool is that? Too cool to be used in production, that is for sure.
(注意)非同期的なプロセスに関しても保証はされません(スレッドなど)
Python is by default a synchronous runtime. The function is run in a dedicated child process, therefore it won't block the NodeJS main process, but in any case only 1 message is processed at a time. That is, of course, unless you use any of the concurrency features available in Python, like multithreading, multiprocessing, Tornado, Twisted...
なんとなくわかるような内容です。このモジュールですが、Pythonの2系3系どちらにも対応しているようなのですが、現状3系を使用したほうがいいかなと思います(どうやってバージョンを判別しているのだろうか?)
では、いつもどおりメニューから拡張ノードのインストールを行いましょう。メニューの【パレットの管理】からインストール作業を行いますが、特にトラブルなく処理は終わると思います。



パレットの【機能】のカテゴリの中にpython-functionノードが追加されていればOKです。

python-functionノードをつかってみる
基本ノードに含まれるfunctionノードとそれほど大きな差異はないようです。入力エリアにPythonのコードを入力していくだけです。importも動作可能なので必要なモジュールがあれば、使用することもできそうです。(venv系の動作はやめておいたほうがいいかも?)
簡単な実験を行うためのフローを作成します。以下のノードを配置して行きます。
- injectノード
- python-functionノード
- debugノード

python-functionノードをダブルクリック処理を記述していきます。

例えば下記のようなコードを動作させることができます。
import os k = 0 for x in range(10**6): k += x # 作業フォルダを取得 folder_name = os.getcwd() # msgオブジェクトに格納(文字列でないとエラーがでるようです) msg["folder_name"] = folder_name msg["payload"] = str(k) return msg
今回はdebugノードで【対象】をmsgオブジェクト全体を表示するように変更しておきます。

作成したフロー

このノードの処理の結果がある場合には、msgオブジェクト(dictionary)として返す必要があるので、結果などを文字列として格納する必要がありそうです。msg.payload以外にも値を格納できますが値をString型に変更しておきます。
実行結果

python-functionノードを使用することでNode-RED上にPythonのコードを内包することは可能となりますが、デバッグなどの容易さを考えるのであればPythonのCLIのプログラムを作成したほうが楽なのではないかと思います。execノードからそのプログラムを呼び出し、標準出力やエラー出力をうまく調整しても似た処理はできるかなと思います。もしメリットがあるとするならばフローで出てきたパラメータ使用するのが楽?かも。changeノードやexecノードを使えばそれも解決しますが。
おわりに
今回はNode-RED側からPythonのコードを記述して処理を行うpython-functionノードを使用してみました。
基本的にはあまりおすすめできる感じではないのですが、ちょっとしたPythonの動きを確認するのであればこちらを拡張ノードをつかうのもありかもしれません。
最近はPythonのモジュールがNode.js側に移植されている処理も多くなってきているので、そこまでの需要はあるのかなと思いますが、何かあったときには実験的につかってみるのもありかもしれません。