Using R packages from Python with rpy2

rpy2 is a Python package that provides an interface to R, allowing you to call R functions and use R packages directly from Python code. Posit Connect supports deploying Python content that uses rpy2 to access R packages.

This is useful when you want to use R’s statistical libraries from Python content without rewriting the R logic in Python.

WarningRequired configuration setting

To use rpy2 today, your Connect administrator must add the following to the server configuration file:

[Python]
Flag = rpy2-cffi-mode-auto

This setting works around a bug in rpy2. Once the upstream fix is accepted and released, this setting will no longer be needed and should be removed.

Requirements

Beyond the Python installation configuration, deploying Python content that uses rpy2 on Connect requires:

  • An R installation configured on the Connect server. See the R installation guide for details.
  • The R packages your content depends on declared in the deployment manifest (via an renv.lock file).
  • The rpy2 Python package listed in your requirements.txt.

How it works

When Connect detects that a Python deployment declares R package dependencies in its manifest, it:

  1. Installs the declared R packages during the content build phase.
  2. Sets the R_LIBS environment variable so the running process can locate the installed R packages.
  3. Sets the R_HOME environment variable so rpy2 can locate the R installation and load libR.

When Connect detects that a Python deployment declares R package dependencies in its manifest, it ensures that there is also a working R runtime and installs the dependencies declared in the renv.lock file. This means your Python code can import and use rpy2 without any additional runtime configuration.

Creating an renv.lock file

By default, renv uses static analysis to scan your project for functions like library(package) or require(package). If it doesn’t see those explicit calls, as is likely the case for a Python project using rpy2, it assumes the package isn’t a project dependency.

The cleanest, most idiomatic way to handle this is to create a script file that tells renv exactly what to look for. renv automatically scans all .R files in your project directory.

_dependencies.R
# This file exists solely to point renv toward hidden R dependencies.
library(packageA)
library(packageB)

Once this file is created, run renv::snapshot(). Because renv finds these explicit calls during its scan, it will cleanly capture the packages and write them to your renv.lock file.

Publishing

Python content that uses rpy2 requires a manifest.json that declares both the Python environment and the R package dependencies.

Using rsconnect-python with renv.lock

The rsconnect-python CLI also detects R dependencies from an renv.lock file. When you deploy Python content that also uses R, rsconnect-python reads the lockfile and adds the R version and packages to the manifest so Connect can restore the R library.

To set this up:

  1. Generate your Python requirements.txt which should include the rpy2 package along with any others used in your project.
  2. Initialize renv in your project and install the R packages your content uses.
  3. Create a _dependencies.R script file that declares your R packages.
  4. Run renv::snapshot() to create or update renv.lock.
  5. Deploy as normal:
Terminal
rsconnect deploy fastapi -n myServer ./

rsconnect-python reads renv.lock and includes the R version and package declarations in the generated manifest automatically.

The lockfile location honors the RENV_PATHS_LOCKFILE environment variable. To opt out of R dependency detection, pass --exclude-renv.

Example: FastAPI application with rpy2

This example creates a FastAPI endpoint that uses rpy2 to call R’s jsonlite package.

Project structure

my-app/
├── app.py
├── manifest.json
└── requirements.txt

Application code

app.py
from fastapi import FastAPI
import rpy2.robjects as ro
from rpy2.robjects.packages import importr

app = FastAPI()

jsonlite = importr("jsonlite")


@app.get("/to-json")
def to_json():
    """Use R's jsonlite to serialize an R list to JSON."""
    result = jsonlite.toJSON(ro.ListVector({"x": 1, "y": 2}), auto_unbox=True)
    return {"r_json": str(result[0])}

Python dependencies

requirements.txt
fastapi
uvicorn
rpy2

Deploying

After setting up your R dependencies through renv.lock as described above, deploy using Posit Publisher or rsconnect-python:

Terminal
rsconnect deploy manifest -n myServer ./manifest.json

Troubleshooting

Editing the manifest by hand

While using renv with Posit Publisher or rsconnect-python is the recommended workflow, you can also add R package declarations to manifest.json manually. This is not recommended because it is error-prone and harder to maintain.

To do so, add the following fields to your generated manifest.json:

  • platform: A top-level field specifying the R version to use (e.g., "4.4.2"). This must match an R version installed on the Connect server.

  • packages: A top-level object where each key is an R package name. Each value must include Source and Repository fields:

    "packages": {
      "jsonlite": {
        "Source": "CRAN",
        "Repository": "https://cran.rstudio.com"
      }
    }

To pin a specific version, add a description field with Package and Version entries:

"packages": {
  "jsonlite": {
    "Source": "CRAN",
    "Repository": "https://cran.rstudio.com",
    "description": {
      "Package": "jsonlite",
      "Version": "1.8.8"
    }
  }
}

R packages fail to install during build

Verify the following:

  • The R version specified in platform is installed on the Connect server.
  • The R packages are available from the specified repository.
  • The Connect server has network access to the package repository.

Contact your Connect administrator to confirm R is properly configured. See the R package management guide for details about how Connect resolves and installs R packages.

rpy2 cannot find R at runtime

If you see errors like R_HOME is not set or cannot load libR, this typically means the manifest does not properly declare R dependencies. Ensure the following:

  • The platform field is set to a valid R version in your manifest.json.
  • At least one R package is listed in the packages field.

Both conditions signal to Connect that R should be made available to the running process.

R package not found at runtime

If rpy2 raises an error that an R package is not installed, verify that the package is listed in the packages section of your manifest.json. Only packages explicitly declared in the manifest are installed by Connect.