python - 无法从子进程激活Conda环境

标签 python electron conda

我正在构建一个 Electron 应用程序(运行 Angular 应用程序),它充当底层 python 程序的用户界面。

python 程序使用 anaconda 进行包管理(我使用 miniconda 进行开发)。

当应用启动时,它会检查所需的 conda 环境是否存在,如果不存在,则创建它。

以下代码是 Service 的一部分,负责管理 python 程序。

public doEnvironmentSetup() {
    let stdOutSub = new Subject<string>();
    let stdErrSub = new Subject<string>();
    let completeSubject = new Subject<string>();
    this.runningSetup = true;

    const TEMP_ENV_FILE = join(tmpdir(), "env.yml");

    return Promise.resolve()
      .then(() => {

        // Copy packaged environment.yml to TEMP_ENV_FILE

      })
      .then(() => this.electron.getApplicationStoragePath())
      .then((stor) => {

        setTimeout(() => {

          let runProcess = this.electron.childProcess.spawn("conda", ["env", "create", "--file", TEMP_ENV_FILE, "--name", CONDA_ENV_NAME], {
            cwd: stor
          });

          const stdOutReaderInterface = createInterface(runProcess.stdout);
          const stdErrReaderInterface = createInterface(runProcess.stderr);

          stdOutReaderInterface.on('line', (line) => {
            stdOutSub.next(line);
          });

          stdErrReaderInterface.on('line', (line) => {
            stdErrSub.next(line);
          });

          runProcess.on('close', (code: number) => {
            this.electron.fs.unlinkSync(TEMP_ENV_FILE);
            this.runningSetup = false;
            completeSubject.next("");
          });

        }, 2000);

        return {
          stdOut: stdOutSub,
          stdErr: stdErrSub,
          onComplete: completeSubject
        };

      });

  }

现在,当我需要运行实际的 python 代码时,运行的代码片段是(没有给出整个代码,因为它对于我们的目的来说太长了):

        execCmd.push(
          `conda init ${this.electron.os.platform() === "win32" ? "powershell" : "bash"}`,
          `conda activate ${CONDA_ENV_NAME}`,
          // long python spawn command
          `conda deactivate`,
        )

        setTimeout(() => {

          logLineSubject.next({ out: "--- Setting up Execution Environment ---", err: "" });

          logLineSubject.next({ out: `Running in ${dir}`, err: "" });

          const cmd = execCmd.join(" && ");

          let runProcess = this.electron.childProcess.spawn(cmd, {
            detached: false,
            windowsHide: true,
            cwd: cwd,
            shell: this.getShell()
          });

          const stdOutInterface = createInterface(runProcess.stdout);
          const stdErrInterface = createInterface(runProcess.stderr);

          stdOutInterface.on('line', (line) => {
            // get this line back to the component
          });

          stdErrInterface.on('line', (line) => {
            // get this line back to the component
          });

          runProcess.on("error", (err) => {
            // get this back to the component
          });

          runProcess.on('close', (code: number) => {
            // get this line back to the component
          });

        }, 1000);

其中 getShell 定义为:

private getShell() {
  return process.env[this.electron.os.platform() === "win32" ? "COMSPEC" : "SHELL"];
}

但是,每当我尝试运行它时,它都会返回:

CommandNotFoundError: Your shell has not been properly configured to use 'conda activate'.
To initialize your shell, run
    $ conda init <SHELL_NAME>
blah blah blah ...

当我尝试使用source activate ${CONDA_ENV_NAME}时,它会返回:

/bin/bash: activate: No such file or directory

不太确定我在这里做错了什么。有人可以指出我正确的方向吗?

PS:它与 source $(conda info --root)/etc/profile.d/conda.sh 一起使用,但我不能真正使用它,因为我需要支持 Windows好吧!

免责声明:我是 python/anaconda 的新手。

最佳答案

我不确定需要在 Windows Powershell 中运行什么,但对于 bash,您需要运行 conda init 将 bash 配置为在启动时运行的脚本,而不是 conda初始化。也就是说,

miniconda3/etc/profile.d/conda.sh

所以应该是这样的

execCmd.push(
    `. ${CONDA_ROOT}/etc/profile.d/conda.sh`,
    `conda activate ${CONDA_ENV_NAME}`,
    // long python spawn command
     `conda deactivate`,
)

我怀疑 Windows 案例正在运行 one of the .bat or .ps1 files in the condabin directory .

或者,如果定义了 conda 并且您有一个 Python 脚本(例如 script.py),那么您也许可以使用 conda run,例如,

execCmd.push(
    `conda run -n ${CONDA_ENV_NAME} python script.py`
)

这可能可以跨平台工作。请注意,conda run 最近才添加了对交互式 I/O 的支持,并且必须使用 --live-stream 标志启用它(请参阅 v4.9.0 Release Notes )。否则,它只是缓冲所有命中 stdout/stderr 的内容,并且在进程退出之前不会返回它。

关于python - 无法从子进程激活Conda环境,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59328111/

相关文章:

python - conda环境可以访问系统模块,如何防止?

javascript - 如何将 git-hooks 与 Electron 应用程序连接起来

javascript - Uncaught ReferenceError : require is not defined (electron)

python - 在 PyTorch 中实现快速密集特征提取

python - 如何在树中顺序遍历时将值存储在列表中?

javascript - 为什么我的 CSS 背景图像无法在 Electron 中加载?

python - Python 中的路径搜索

python - 导入错误: No module named pyreadability in conda env

python - 在 matplotlib 动画中绘制不同颜色的点

python - 按可选的开始和结束日期过滤查询集