rpy-bridge
rpy-bridge is a Python-controlled R execution orchestrator (not a thin
rpy2 wrapper). It delivers deterministic, headless-safe R startup; project-root
inference; out-of-tree renv activation; isolated script namespaces; and robust
Python↔R conversions with dtype/NA normalization. Use it when you need
reproducible R execution from Python in production pipelines and CI.
Latest release: rpy-bridge on PyPI
What this is (and is not)
rpy-bridge is not a thin rpy2 wrapper. Key differences:
- Infers R project roots via markers (
.git,.Rproj,renv.lock,DESCRIPTION,.here) - Activates
renveven when it lives outside the calling directory - Executes from the inferred project root so relative paths behave as R expects
- Runs headless by default (no GUI probing), isolates scripts from
globalenv() - Normalizes return values for Python (NAs, dtypes, data.frames) and offers comparison helpers
Quickstart
Call a package function (no scripts):
from rpy_bridge import RFunctionCaller
rfc = RFunctionCaller()
samples = rfc.call("stats::rnorm", 5, mean=0, sd=1)
median_val = rfc.call("stats::median", samples)
Call a function from a local script with renv (out-of-tree allowed):
from pathlib import Path
from rpy_bridge import RFunctionCaller
project_dir = Path("/path/to/your-r-project")
script = project_dir / "scripts" / "example.R"
rfc = RFunctionCaller(path_to_renv=project_dir, scripts=script)
result = rfc.call("some_function", 42, named_arg="value")
Core capabilities
1. R execution orchestration
- Embeds R via
rpy2with deterministic startup behavior - Disables interactive and GUI-dependent hooks for headless execution
- Loads R scripts into isolated namespaces (not
globalenv())
2. Project root inference and path stability
- Infers R project roots using markers such as:
.git,.Rproj,renv.lock,DESCRIPTION,.here - Executes R code from the inferred project root regardless of Python CWD
- Preserves relative-path behavior expected by R scripts
- Supports R code using
here::here()or project-local data
3. Out-of-tree renv activation
- Activates
renvprojects located outside the calling Python directory - Sources
.Rprofileand.Renvironto reproduce R startup semantics - Does not require R scripts and
renvto live in the same directory
4. Python ↔ R data conversion
- Converts Python scalars, lists, dicts, and pandas objects into R equivalents
- Converts R vectors, lists, and data.frames back into Python-native types
- Handles nested structures, missing values, and mixed types robustly
5. Data normalization and diagnostics
- Post-processes R data.frames to fix dtype, timezone, and NA semantics
- Normalizes column types for reliable Python-side comparison
- Supports structured mismatch diagnostics between Python and R data
6. Function invocation across scripts and packages
- Calls functions defined in sourced R scripts, base R, or installed packages
- Supports qualified function names (e.g.
stats::median) - Executes functions within the active project and library context
Calling base R functions and managing packages
In addition to sourcing local R scripts, rpy-bridge supports calling functions from base R and installed packages directly from Python.
Current support includes:
- Calling base R functions without a local R script
- Executing functions from installed R packages within the active environment
Planned extensions (roadmap):
- Programmatic installation of R packages into the active
renvor system environment when explicitly enabled - Declarative package requirements at the Python call site
- Safe, opt-in package installation for CI and ephemeral environments
Package installation is intentionally not automatic by default to preserve reproducibility and avoid side effects during execution.
Installation
Prerequisites
- System R installed and available on
PATH - Python 3.11+ (tested on 3.11–3.12)
From PyPI
Install rpy-bridge with rpy2 for full R support:
python3 -m pip install rpy-bridge rpy2
Using uv:
uv add rpy-bridge rpy2
Development install
python3 -m pip install -e .
or:
uv sync
Required Python dependencies
rpy2pandasnumpy
Usage
See Quickstart above and examples in examples/basic_usage.py.
Round-trip Python ↔ R behavior
rpy-bridge attempts to convert Python objects to R and back. Most objects used in scientific and ML pipelines round-trip cleanly, but some heterogeneous Python structures may be wrapped or slightly altered due to differences in R’s type system.
| Python type | Round-trip fidelity | Notes |
|---|---|---|
int, float, bool, str |
High | Scalars convert directly |
Homogeneous list of numbers/strings |
High | Converted to atomic R vectors |
| Nested homogeneous lists | High | Converted to nested R lists |
pandas.DataFrame / pd.Series |
High | Converted to data.frame and normalized on return |
Mixed-type list or dict |
Partial | May be wrapped in single-element vectors |
None / pd.NA |
High | Converted to R NULL |
R setup helpers
Helper scripts are provided in examples/r-deps/ to prepare R environments.
- Install system R dependencies (macOS / Homebrew):
bash examples/r-deps/install_r_dev_deps_homebrew.sh
- Initialize an
renvproject:
source("examples/r-deps/setup_env.R")
- Restore the environment on a new machine:
renv::restore()
Who this is for
rpy-bridge is designed for:
- Python-first pipelines that rely on mature R code
- Teams where R logic must remain authoritative
- CI or production systems that cannot rely on interactive R sessions
- Multi-repo or multi-directory projects with non-trivial filesystem layouts
It is not intended as a convenience wrapper for exploratory R usage.
Licensing
- rpy-bridge is released under the MIT License © 2025 Victoria Cheung
- Depends on
rpy2, licensed under the GNU GPL (v2 or later)
Acknowledgements
This package was spun out of internal tooling I wrote at Revolution Medicines. Thanks to the team there for supporting its open-source release.
Metadata
Release files for rpy-bridge 0.5.3
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| rpy_bridge-0.5.3.tar.gz | 22.9 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| rpy_bridge-0.5.3-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 43.4 kB
Release files / rpy_bridge-0.5.3.tar.gz
| Download URL | rpy_bridge-0.5.3.tar.gz |
|---|---|
| Size | 22.9 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
0812014fb2e7289ecf4446a7f6aa482f17829419f69ebc3430ed1a49d9fa0ec2
|
|
BLAKE2b-256 checksum How to use checksums |
8d1c45f37893b868ef3d5b71493b216ce9b4c2317e1731ed17ed5c0fff9a27eb
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.11.11
|
Release files / rpy_bridge-0.5.3-py3-none-any.whl
| Download URL | rpy_bridge-0.5.3-py3-none-any.whl |
|---|---|
| Size | 20.5 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
f116e14e5b295769c42e11128c0dfdddc69145b2155014e4ed0018e9fd46ccf2
|
|
BLAKE2b-256 checksum How to use checksums |
dda0e88fe04fbd7a2892514d631e2400b8684fcd53c5386637e3760213053aac
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.11.11
|