节点Python-Shell无法获得脚本输出

时间:2019-06-11 13:58:07

标签: angular python-3.x electron

我正在开发一个包含电子角度前端的应用程序,该应用程序调用一些Python任务(使用RobotFramework)。整个Typescript代码与Python代码之间的通信由节点模块Python-shell处理。我到达了该项目,试图使事情变得“干净”,并希望创建一个虚拟环境,以便我们能够更轻松地管理Python版本和应用程序的Python依赖关系。

问题在于,它显然引入了一个新的错误,除此以外,我们真的无法以其他方式重现该错误:

第一次对项目运行npm start,然后单击特定的按钮(启动Python后台任务)时,您会看到作业按预期执行,但是按钮保持“锁定”状态,就好像它仍在等待Python给出其输出。

这是MyService服务中按钮调用的代码:

executePython(robotScriptFilePath: string): Observable<RobotMessage> {
    const path = this.electronService.remote.require('path');
    process.env.PATH = process.env.PATH + ';' + path.join(this.electronService.remote.app.getAppPath(), environment.driverPath);
    // process.env.PYTHONDONTWRITEBYTECODE = 'true';
    process.env.PYTHONUNBUFFERED = 'true';
    const options = {
      env: process.env,
      pythonPath: this.pythonPath, // points to the virtualenv's python.exe 
      scriptPath: this.robotFolderPath, // points to virtualenv's site-packages
      args: ['--pythonpath', this.externalLibrariesPath, '--outputdir', this.logsFolderPath, robotScriptFilePath]
    };
    return new Observable(observer => {
      PythonShell.run('run.py', options, (err, stdout) => {
        if (err) {
          observer.next(new RobotMessage(false, err.message));
          observer.complete();
        } else {
          observer.next(new RobotMessage(true, stdout.toString()));
          observer.complete();
        }
      });
      return { unsubscribe() {} };
    });
}

我首先认为它与 pycache 有某种关系,因为它仅发生一次,因此我设置了env-var PYTHONDONTWRITEBYTECODE以查看它是否正在复制bug可靠,但是它没有任何改变,所以我认为它与我们认为Python-shell处理通信的方式有关,因此设置了PYTHONUNBUFFERED env-var。

我在两台计算机上尝试了后者:在一台计算机上工作,但在另一台计算机上什么都没有改变。

我是否错过了一些有关虚拟环境的东西,或者会阻止我使用这种设置?但最重要的是,你们对导致这种奇怪行为的原因有任何线索吗?

此外,请注意,除了虚拟环境之外,Python也没有“花哨的东西”:我们只是按原样使用RobotFramework的库。


RobotMessage类定义:

export class RobotMessage {
  isSuccess: boolean;
  message: string;

  constructor(isSucess: boolean, message: string) {
    this.isSuccess = isSucess;
    this.message = message;
  }
}

MyService定义:

export class MyService {
  private robotFolderPath: string;
  private externalLibrariesPath: string;
  private logsFolderPath: string;
  private robotScriptsFolderPath: string;
  private libraries: string[];
  private resources: string[];
  private scriptFileExtension: string;
  private separator: string;
  private pythonPath: string;
  private chromedriverPath: string;

  constructor(private electronService: ElectronService, private stepService: StepService) {
    this.robotFolderPath = environment.robotFramework.robotFolderPath;
    this.externalLibrariesPath = environment.robotFramework.externalLibrariesPath;
    this.logsFolderPath = environment.robotFramework.logsPath;
    this.robotScriptsFolderPath = environment.robotFramework.robotScriptsFolderPath;
    this.libraries = ['SeleniumLibrary'];
    this.resources = [];
    this.scriptFileExtension = '.robot';
    this.separator = '    ';

    this.pythonPath = this.electronService.isWindows ? environment.winPythonPath : environment.nixPythonPath;
  }

0 个答案:

没有答案