Hi all. I wanted to share a Python interface I’ve been building for brms that may be useful for anyone who works across both R and Python environments.
brmspy provides a Python-side API for fitting brms models via cmdstanr, returning results directly as ArviZ InferenceData while still exposing the underlying brmsfit object when needed.
It’s designed for production pipelines where models are authored in the brms formula language but the rest of the workflow (data processing, prediction, dashboards, etc.) is Python-based.
What it does
- Calls brms functions through rpy2 with correct parameter translation
- Delegates all modeling logic to real brms. No Python-side reimplementation, no divergence from native behavior. Opinionated wrappers that rebuild formulas or stancode in Python inevitably drift from brms and accumulate their own bugs.
- Preserves full brms parameter names
(e.g.b_Intercept,b_x,sd_group__Intercept, etc.) - Returns ArviZ
InferenceDataby default for downstream analysis in Python - Still provides access to the R-side
brmsfitobject (model.r) - Includes helpers like
prior(),formula(),make_stancode(), and summary utilities - Tested against multiple brms workflows (priors, prediction functions, stancode generation, etc.)
- Works well with various algorithms. Tested with NUTS sampling, fullrank optimization and meanfield optimization.
I’m using this in production (several daily pipelines), so the focus has been stability and predictable behavior rather than feature breadth.
Test coverage & stability
The current release has:
- 77% test coverage (Python-side)
- 54 tests covering priors, model fitting,
get_stancode, summary paths, predictions, and no-sampling modes - Continuous testing across Python 3.10–3.14
The interface is still early (0.1.x), but the core fitting, prior handling, and prediction paths have been hardened through adaptation in production systems.
Example
pip install brmspy
from brmspy import brms, prior
epilepsy = brms.get_brms_data("epilepsy")
model = brms.fit(
formula="count ~ zAge + zBase * Trt + (1|patient)",
data=epilepsy,
family="poisson",
priors=[
prior("normal(0, 1)", "b"),
prior("exponential(1)", "sd", group="patient"),
prior("student_t(3, 0, 2.5)", "Intercept"),
],
chains=4,
iter=2000
)
# Python-side analysis
idata = model.idata
Documentation
Docs:
https://kaitumisuuringute-keskus.github.io/brmspy/