Python
 Computer >> コンピューター >  >> プログラミング >> Python

Node.jsのchild_process.spawn()メソッドを使ってPythonスクリプトを実行する方法

Node.jsとPythonは、開発者やWebデザイナーの間で最も人気のある2つのプログラミング言語です。しかし、数値計算や科学技術計算(AI、機械学習、ディープラーニングなど)の分野において、Node.jsはPythonに及ばない部分があります。一方のPythonには、科学技術計算を格段に簡単に行える豊富なライブラリが用意されています。

幸いなことに、Pythonをバックグラウンドで実行してその結果を受け取ることで、Node.jsアプリケーションの中でもこれらのPythonライブラリを活用することが可能です。

本記事では、Node.jsの標準ライブラリであるchild_processを使用して、バックグラウンドでPythonプロセスを起動(spawn)し、計算処理を行った結果をNode.jsプログラムへ返す方法を解説します。

Pythonスクリプトの作成

まず、処理の過程で標準出力にメッセージを出力する、シンプルなPythonスクリプトを作成します。

# ライブラリをインポート
import sys, getopt, time
def main(argv):
    argument = ''
    usage = 'usage: myscript.py -f <sometext>'
    # 受け取った引数を解析
    try:
        opts, args = getopt.getopt(argv,"hf:",["foo="])
    except getopt.GetoptError:
        print(usage)
        sys.exit(2)
    for opt, arg in opts:
        if opt == '-h':
            print(usage)
            sys.exit()
        elif opt in ("-f", "--foo"):
            argument = arg
    # 結果を出力
    print("Start : %s" % time.ctime())
    time.sleep( 2 )
    print('Foo is')
    time.sleep( 2 )
    print(argument)
    print("End : %s" % time.ctime())
if __name__ == "__main__":
main(sys.argv[1:])

実行結果

引数「-f」を付けてスクリプトを実行すると、以下のような出力が得られます。

>python myscript.py -f "Hello, Python"
Start : Wed Feb 20 07:52:45 2019
Foo is
Hello, Python
End : Wed Feb 20 07:52:49 2019

ロングオプション形式の「--foo」でも同じ結果になります。また、「-h」オプションを指定するとヘルプ(使用方法)が表示されます。

>python myscript.py --foo "Hello, Python"
>python myscript.py –h

実行結果

usage: myscript.py -f <Hello, Python>

Node.jsとの連携

次に、Node.jsスクリプトからPythonスクリプトを呼び出し、その出力をクライアントに渡して画面に表示する仕組みを作ります。

それでは、spawn()メソッドを使って子プロセスを生成するNode.jsスクリプトを作成してみましょう。

server.js

const path = require('path')
const {spawn} = require('child_process')
/**
    * python myscript を実行する。
    * `-u` オプションを渡すことで、コンソール出力がバッファリングされるのを防ぐ
    * @return {ChildProcess}
*/
function runScript(){
    return spawn('python', [
        "-u",
        path.join(__dirname, 'myscript.py'),
        "--foo", "some value for foo",
    ]);
}
const subprocess = runScript()
// スクリプトの出力を表示
subprocess.stdout.on('data', (data) => {
   console.log(`data:${data}`);
});
subprocess.stderr.on('data', (data) => {
   console.log(`error:${data}`);
});
subprocess.stderr.on('close', () => {
   console.log("Closed");
});

上記のスクリプトでは、.on('data', callback)を通じて出力を受け取ります。ここで重要なのが、Python側に出力バッファリングを防ぐための「-u」フラグを渡している点です。このフラグを付けないと、print()による出力がスクリプトの実行完了までNode.js側に届かず、「data」イベントが即座に発生しなくなってしまいます。

server.jsを実行すると、以下のようにPythonスクリプトからの出力がリアルタイムに表示されます。

>node server.js
data:Start : Wed Feb 20 10:56:11 2019
data:Foo is
data:some value for foo
data:End : Wed Feb 20 10:56:15 2019
Closed
  1. PythonでPOSTメソッドを使ってCGIプログラムに情報を渡す方法

    CGIプログラムへ情報を渡す方法としては、POSTメソッドの方が一般的により信頼性が高いとされています。POSTメソッドは、GETメソッドとまったく同じ形式でデータをパッケージ化しますが、URLの「?」以降にテキスト文字列として付加して送信するのではなく、独立したメッセージとして送り出す点が異なります。このメッセージは、標準入力(stdin)を通じてCGIスクリプトへ渡されます。POSTメソッドの主な特徴送信データがURLに表示されないため、GETメソッドよりも安全性が高いURLの長さ制限を受けないため、大量のデータも送信できるデータはリクエストボディに格納され、標準入力経由でCGIスクリプト

  2. PythonでGETメソッドを使用して情報を渡す方法【CGIプログラミング入門】

    GETメソッドとはGETメソッドは、エンコードされたユーザー情報をページリクエストに付加して送信する方式です。ページのURLとエンコードされた情報は「?」記号で区切られます。https://www.test.com/cgi-bin/hello.py?key1=value1&key2=value2GETメソッドは、ブラウザからWebサーバーへ情報を渡す際のデフォルトの方法であり、送信した内容はブラウザのアドレスバー(Locationボックス)に長い文字列として表示されます。そのため、パスワードなどの機密情報をサーバーに送る場合には、GETメソッドは絶対に使用しないでください。また、GET