Search code examples
pythonnode.jsnx-monorepo

Python virtual environment in NX monorepo


I am using NX monorepo for one of my large javascript projects and one part of it relies on an external project that creates its own python virtual environment. Parts of my nodejs code are executing python commands and then retrieve the data required for the rest of JS build process.

In order to run NX scripts or tests, that virtualenv needs to be turned on, but the problem is that NX spawns its own processes that are isolated from the rest of operating system.

If I try to add NPM script that starts virtualenv conda activate testenv with nx:run-script

    "virtualenv-conda": {
      "executor": "nx:run-script",
      "options": {
          "script": "venv-conda"
      }
    }

or set it with nx:run-commands with

    "virtualenv-conda": {
      "executor": "nx:run-commands",
      "options": {
        "commands": [
          "conda activate testenv"
        ],
        "parallel": false
      }
    }

I get the following error:

CommandNotFoundError: Your shell has not been properly configured to use 'conda activate'.
To initialize your shell, run
    $ conda init <SHELL_NAME>
Currently supported shells are:
  - bash
  - fish
  - tcsh
  - xonsh
  - zsh
  - powershell

I am using ZSH on MacOS.

My questions are:

  1. How do I start python virtual environment before specific tests?
  2. How do I set up custom environment that will be used in these spawned processes?

Solution

  • Easiest solution that I could find was to set env variable that leads to virtual envoronment's bin folder (on nix systems) or Scripts on Windows, and then prefix all commands with that specific path.

    In short, just an idea if anyone else needs to develop their own solutions

    import { execSync } from 'child_process'
    
    const pythonPath = '/absolute/path/to/specific/python/venv/bin'
    
    const pyCmd = 'some_python_command'
    
    execSync(pythonPath + ' ' + pyCmd, { stdio: 'pipe' })