nestjs 下与 python 通信调用

302 阅读2分钟

有时, 可能或者会调用 python 脚本做一些事情, 所以会用到 python. 这里, 做个记录吧. 记下 nestjs 怎么去调用 python, 并且它们之间是怎么通信的.

首先, 安装 python-shell, 并且电脑要安装 python, 怎么安装, 去看官网就是了.

npm install python-shell

先准备好 python 脚本

src 下面创建个 python 目录放代码, 创建文件 script.py

import json
import sys

# 访问命令行参数
args = sys.argv[1:]
# 获取当前脚本的路径
pyPath = sys.argv[0]

# 将参数转换为 JSON 格式的字符串,并输出, json.dumps
print(json.dumps({"pyPath": pyPath}))
print(json.dumps({"args": args}))

nestjs 参数会专到 args, 并且用 print 输出到控制台, 在另一边, nestjs 会接收到. 可以多少输出

当然, 也可以用别的方法输出到控制台, 或者输出到本地一个 json 文件也行. nestjs 去读这个 json 就是了.

nestjs

import { Options, PythonShell } from 'python-shell';

    @Get('/test')
    async test() {
        return new Promise((resolve, reject) => {
            const args = ['value1', 'value2', 'value3']
            const options: Options = {
                mode: 'json', // "json" | "text" | "binary", 选择适合你的数据交换模式
                // pythonPath: 'path/to/python', // 指定 Python 路径,更加灵活
                pythonOptions: ['-u'], // 实时获取打印结果,更加高效
                scriptPath: 'src/python', // 设置脚本路径,更加便捷
                args: args // 向 Python脚本传递参数,更加实用
            };
            const shell = new PythonShell('script.py', options);
            const messages = [];
            // 可以多次接收
            shell.on('message', messages.push.bind(messages));
            shell.on('error', reject);
            shell.on('stderr', reject);
            // 这里接收完后, 用 api 返回到前端等
            shell.end((err) => {
                err ? reject(err) : resolve(messages);
            });
            
        })
    }

更多详情可以看 github.com/extrabacon/…

child_process 调用 python 也行, 好的是不用安装第三方库. 这个 nodejs 自带.

import { spawn } from 'child_process';
import * as path from 'path';

@Get('/test')
    async test() {
        return new Promise((resolve, reject) => {
            // 定义要执行的 Python 脚本路径和参数
            const pythonScriptPath = path.join(__dirname, '../../../src/python/script.py');  // 使用绝对路径
            const scriptArgs = ['arg1', 'arg2'];

            // 使用 spawn 方法启动子进程并执行 Python 脚本
            const pythonProcess = spawn('python3', [pythonScriptPath, ...scriptArgs]);
            // 监听子进程的标准输出流
            pythonProcess.stdout.on('data', (data) => {
                // resolve(data);
                //  data = {"type":"Buffer","data":[123,34,110,97,109,101,34,58,34,106,97,110,101,34,125]}
                const jsonString = `${data}`;  // 将 Buffer 对象转换为字符串
                const jsonStrings = jsonString.split('\n');  // 将字符串分割为多个部分
                // 去掉最后一个数组'\n'
                jsonStrings.pop();
                const jsons = jsonStrings.map(jsonString => {
                    return JSON.parse(jsonString);
                });
                resolve(jsons);
            });

            // 监听子进程的标准错误流
            pythonProcess.stderr.on('data', (data) => {
                reject(data);
            });

            // 监听子进程退出事件
            pythonProcess.on('close', (code) => {
                console.log(`Python process exited with code ${code}`);
            });
        })
    }

到这里, 基本通信就可以了, 其它的就是怎么去用 python 做一些大数据分析, 或者 AI 之类的了.