Search code examples
rreticulate

Dynamically change conda environment in reticulate


Is it possible to dynamically change the conda environment through reticulate?

use_condaenv(condaenv='env1', conda='/path/to/conda')
package1 = import('pack1')
package1$do_smth

use_condaenv(condaenv='env2', conda='/path/to/conda')
package2 = import('pack2')
package2$do_smth2

Currently I get an import error here:

package2 = import('pack2')

ModuleNotFoundError: No module named pack2


Solution

  • You're facing the problem because reticulate can not change python interpreter within a single R session. You get ModuleNotFoundError: No module named pack2 because reticulate is still using env1 which doesn't have pack2. Try that:

    use_condaenv(condaenv='env1', conda='/path/to/conda')
    use_condaenv(condaenv='env2', conda='/path/to/conda', required = TRUE) # should throw an error
    

    As a workaround, what you can do is to use callr package to run python code as if it would be running in a standalone R session:

    library(callr)
    
    # change variables accordindly:
    venv <- "env2" # env1 or env2
    
    # (optional) a python script containing a function which you would like to run from R
    python_script_path <- "some_python_script.py"
    # (optional)
    some_other_parameter <- "foobar"
    
    result <- r(function(venv, python_script_path, some_other_parameter){
        library(reticulate)
        use_condaenv(venv, conda='/path/to/conda', required = T)
    
        # try to import package
        package = import('pack2') # pack1 or pack2
        return(package$do_smth())
    
        # (oprional) or even to source a python script
        # source_python(python_script_path)
        # run a python function which is sourced from `python_script_path`
        # result <- run_calculations(some_other_parameter)
        # return(result)
      }, args = list(venv, python_script_path, some_other_parameter))
    

    You should be able to run this code for env1 with pack1 and for env2 with pack2 within single session without a problem.

    Note: the anonymous function will have it's own environment and in order to access variables from the global environment you need to pass them as parameters to the function (although probably you can pass the global environment itself, but I didn't try that).