How to use RMarkdown for Python with Virtual Environments

I’m currently evaluating different publishing workflows for my academic writing. One option that seems to be increasingly popular is the use of RMarkdown as a source document, from which you then compile into HTML, LaTeX or whatever else you need.
For the code used in the document, RMarkdown not only supports the execution of R, but a whole bunch of languages, including Python, thanks to the knitr package.

One problem I had when I first came across RMarkdown a couple of years ago is that it didn’t really support using virtual environments when using Python. That was a big problem for me, because every project I work on lives in its own virtual environment. But as it turns out this is actually not a problem anymore. By using the engine.path option you can point to whatever virtual environment you want and it works splendidly. Here’s how you do it:

  1. Get Pipenv to manage your virtual environments and packages. Their description:

    “It automatically creates and manages a virtualenv for your projects, as well as adds/removes packages from your Pipfile as you install/uninstall packages. It also generates the ever-important Pipfile.lock, which is used to produce deterministic builds.”

    Seriously, Pipenv is amazing and you should use it.

  2. Create an environment for your project and install a package:

     $ cd /your/project  
     $ pipenv --three  
     $ pipenv shell  
     $ pipenv install requests  
    

    I have installed the requests package as an example.

  3. Get the path to the Python version you are using in the project:

     $ which python  
     /Users/lukas/.local/share/virtualenvs/test_rmd_env-aIwIsAj4/bin/python  
    
  4. In your .Rmd file, set the engine.path to your project’s Python version

    4.1 either in any individual chunk:

     ```{python, engine.path = '/Users/lukas/.local/share/virtualenvs/test_rmd_env-aIwIsAj4/bin/python'}   
     import requests  
     test = requests.get("http://lukaskawerau.com")  
     print(test) 
     ```
    

    4.2 or globally for the whole project:

     knitr::opts_chunk$set(engine.path = list(
     python = '/Users/lukas/.local/share/virtualenvs/test_rmd_env-aIwIsAj4/bin/python'))
    

And that’s it, now you can use Python virtual environments in your .Rmd documents.
Standard behavior for using Python in a RMarkdown document applies, I found this section in the documentation of the awesome Bookdown project really helpful.

Lukas Kawerau
Lukas Kawerau
Data Engineer, Writer

Related