rpy-bridge 0.5.0__py3-none-any.whl → 0.5.1__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: rpy-bridge
3
- Version: 0.5.0
3
+ Version: 0.5.1
4
4
  Summary: Python-to-R interoperability engine with environment management, type-safe conversions, data normalization, and safe R function execution.
5
5
  Author-email: Victoria Cheung <victoriakcheung@gmail.com>
6
6
  License: MIT License
@@ -52,6 +52,12 @@ Provides-Extra: r
52
52
  Requires-Dist: rpy2>=3.5; extra == "r"
53
53
  Provides-Extra: dev
54
54
  Requires-Dist: ipykernel>=7.1.0; extra == "dev"
55
+ Requires-Dist: pytest>=8.0; extra == "dev"
56
+ Requires-Dist: ruff>=0.6; extra == "dev"
57
+ Requires-Dist: build>=1.0; extra == "dev"
58
+ Requires-Dist: twine>=4.0; extra == "dev"
59
+ Requires-Dist: certifi>=2025.0; extra == "dev"
60
+ Requires-Dist: ty>=0.0.1a34; extra == "dev"
55
61
  Provides-Extra: docs
56
62
  Requires-Dist: sphinx; extra == "docs"
57
63
  Requires-Dist: myst-parser; extra == "docs"
@@ -59,17 +65,11 @@ Dynamic: license-file
59
65
 
60
66
  # rpy-bridge
61
67
 
62
- **rpy-bridge** is a Python-controlled **R execution orchestrator** that enables
63
- Python code to run R functions, scripts, and packages with **reproducible
64
- filesystem and environment semantics**.
65
-
66
- It is built on top of `rpy2`, but unlike thin wrappers, rpy-bridge stabilizes how
67
- R code is executed when invoked from Python: project roots are inferred, `renv`
68
- environments can be activated out-of-tree, relative paths behave as expected,
69
- and return values are normalized for safe Python consumption.
70
-
71
- This makes rpy-bridge suitable for production pipelines, CI, and bilingual
72
- Python/R teams where R code must run reliably outside an interactive R session.
68
+ **rpy-bridge** is a Python-controlled **R execution orchestrator** (not a thin
69
+ rpy2 wrapper). It delivers deterministic, headless-safe R startup; project-root
70
+ inference; out-of-tree `renv` activation; isolated script namespaces; and robust
71
+ Python↔R conversions with dtype/NA normalization. Use it when you need
72
+ reproducible R execution from Python in production pipelines and CI.
73
73
 
74
74
  **Latest release:** [`rpy-bridge` on PyPI](https://pypi.org/project/rpy-bridge/)
75
75
 
@@ -77,20 +77,40 @@ Python/R teams where R code must run reliably outside an interactive R session.
77
77
 
78
78
  ## What this is (and is not)
79
79
 
80
- rpy-bridge **is not a thin rpy2 wrapper**.
80
+ rpy-bridge **is not a thin rpy2 wrapper**. Key differences:
81
81
 
82
- Typical rpy2 usage assumes:
83
- - the Python working directory is the R project root
84
- - `renv` lives next to the executing script
85
- - relative paths resolve correctly by default
86
- - all R code executes in `globalenv()`
82
+ - Infers R project roots via markers (`.git`, `.Rproj`, `renv.lock`, `DESCRIPTION`, `.here`)
83
+ - Activates `renv` even when it lives outside the calling directory
84
+ - Executes from the inferred project root so relative paths behave as R expects
85
+ - Runs headless by default (no GUI probing), isolates scripts from `globalenv()`
86
+ - Normalizes return values for Python (NAs, dtypes, data.frames) and offers comparison helpers
87
87
 
88
- These assumptions break quickly in real-world Python workflows.
88
+ ---
89
89
 
90
- rpy-bridge instead provides a **controlled R runtime** with explicit guarantees
91
- around execution context, filesystem behavior, and environment activation.
90
+ ## Quickstart
92
91
 
93
- ---
92
+ Call a package function (no scripts):
93
+
94
+ ```python
95
+ from rpy_bridge import RFunctionCaller
96
+
97
+ rfc = RFunctionCaller()
98
+ samples = rfc.call("stats::rnorm", 5, mean=0, sd=1)
99
+ median_val = rfc.call("stats::median", samples)
100
+ ```
101
+
102
+ Call a function from a local script with `renv` (out-of-tree allowed):
103
+
104
+ ```python
105
+ from pathlib import Path
106
+ from rpy_bridge import RFunctionCaller
107
+
108
+ project_dir = Path("/path/to/your-r-project")
109
+ script = project_dir / "scripts" / "example.R"
110
+
111
+ rfc = RFunctionCaller(path_to_renv=project_dir, scripts=script)
112
+ result = rfc.call("some_function", 42, named_arg="value")
113
+ ```
94
114
 
95
115
  ## Core capabilities
96
116
 
@@ -161,7 +181,7 @@ reproducibility and avoid side effects during execution.
161
181
  ### Prerequisites
162
182
 
163
183
  - System R installed and available on `PATH`
164
- - Python 3.12+
184
+ - Python 3.11+ (tested on 3.11–3.12)
165
185
 
166
186
  ### From PyPI
167
187
 
@@ -199,33 +219,7 @@ uv sync
199
219
 
200
220
  ## Usage
201
221
 
202
- ### Call a function from a local R script
203
-
204
- ```python
205
- from pathlib import Path
206
- from rpy_bridge import RFunctionCaller
207
-
208
- project_dir = Path("/path/to/your-r-project")
209
- script = project_dir / "scripts" / "example.R"
210
-
211
- caller = RFunctionCaller(
212
- path_to_renv=project_dir,
213
- script_path=script,
214
- )
215
-
216
- result = caller.call("some_function", 42, named_arg="value")
217
- ```
218
-
219
- ### Call base R functions (no local script)
220
-
221
- ```python
222
- from rpy_bridge import RFunctionCaller
223
-
224
- caller = RFunctionCaller(path_to_renv=None)
225
-
226
- samples = caller.call("stats::rnorm", 10, mean=0, sd=1)
227
- median_val = caller.call("stats::median", samples)
228
- ```
222
+ See Quickstart above and examples in `examples/basic_usage.py`.
229
223
 
230
224
  ---
231
225
 
@@ -8,8 +8,8 @@ rpy_bridge/logging.py,sha256=9U2RJHmxLqrXEwS38TkrSqeETXxn1AAfL8BGTjnzSGY,1360
8
8
  rpy_bridge/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
9
9
  rpy_bridge/renv.py,sha256=BYBFXP8SslKzD-GZ0yi7T-nMwqcIx2hYPY3BC_xSSZU,4511
10
10
  rpy_bridge/rpy2_loader.py,sha256=rQEnAiJbzkTzb4UlcOsG8D4MXZ0LWtYLMP8DequBNzg,1874
11
- rpy_bridge-0.5.0.dist-info/licenses/LICENSE,sha256=JwbWVcSfeoLfZ2M_ZiyygKVDvhBDW3zbqTWwXOJwmrA,1276
12
- rpy_bridge-0.5.0.dist-info/METADATA,sha256=6bkzCM7gFr1gtOUF007Zrhhjy9vvNtduX9Vq4o7_YN4,10188
13
- rpy_bridge-0.5.0.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
14
- rpy_bridge-0.5.0.dist-info/top_level.txt,sha256=z9UZ77ZuUPoLqMDQEpP4btstsaM1IpXb9Cn9yBVaHmU,11
15
- rpy_bridge-0.5.0.dist-info/RECORD,,
11
+ rpy_bridge-0.5.1.dist-info/licenses/LICENSE,sha256=JwbWVcSfeoLfZ2M_ZiyygKVDvhBDW3zbqTWwXOJwmrA,1276
12
+ rpy_bridge-0.5.1.dist-info/METADATA,sha256=6AbvKbd8fOgmfoRn2s5D2tqFo_vkZjK4S-eKhRJbNEw,10256
13
+ rpy_bridge-0.5.1.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
14
+ rpy_bridge-0.5.1.dist-info/top_level.txt,sha256=z9UZ77ZuUPoLqMDQEpP4btstsaM1IpXb9Cn9yBVaHmU,11
15
+ rpy_bridge-0.5.1.dist-info/RECORD,,