library(reticulate)
BiocBook::setup_python()
## ✔ Using the `python` already configured for this session: '/opt/R-cache/R/BiocBook/envs/BiocBookDemo-faf828c9fe1d/bin/python'4 Executing python code
-
BiocBooks can executepythoncode, not justRcode; - The code runs on every render, including when the Bioconductor Build System builds the book;
- The
pythonpackages the book needs are therefore installed at build time, by the book itself, in the environment declared ininst/requirements.yml:pythonand command-line tools fromconda, the packages thatpythonchunks import from PyPI; -
Keep at least one
Rchunk on apythonpage: it is what keepsquartoon theknitrengine.
4.1 Declaring and installing the python environment
The environment is declared, with pinned versions, in inst/requirements.yml – a plain conda environment file. This book’s is:
name:
BiocBookDemo
channels:
- conda-forge
- bioconda
- nodefaults
dependencies:
- python=3.12
- samtools=1.24
- pip:
- numpy==2.5.4conda provides python itself and command-line tools, such as samtools from bioconda. The packages that python chunks import go under pip:, and come from PyPI. python chunks run inside the R session, and conda builds of these packages link libraries that R may already have loaded, in an older version: on the Bioconductor builders, h5py and matplotlib >= 3.11 then fail to import. PyPI wheels carry their own (see ?BiocBook::BiocBook-python).
Note the presence of the nodefaults channel: the defaults channel is covered by the Anaconda Terms of Service, which require a paid licence for many organisations. conda-forge and bioconda are community channels that are free to use.
Any page that needs python would need to have this chunk at the top:
setup_python() finds inst/requirements.yml and creates the environment if it does not exist yet: its conda packages, then its pip: section, with the environment’s own pip. It then activates the environment, addressing it by full path rather than by name, and puts its command-line tools on the PATH. If RETICULATE_PYTHON is already set (as it is inside the book’s Docker image), setup_python() only puts that interpreter’s folder on the PATH.
Environments are cached, and keyed on the contents of requirements.yml: an environment is re-used rather than resolved again as long as requirements.yml is unchanged. Editing the file (adding, removing or re-pinning a package) gives a new environment on the next render, including on machines that build the book every day, and two books only share an environment when they declare exactly the same thing. BiocBook::python_envs() lists the environments cached on a machine, and python_envs(remove = ...) deletes the ones that are no longer needed.
4.2 Where conda itself comes from
Building a conda environment needs a conda implementation, and the machines that build this book do not necessarily have one. Bioconductor’s current builders may, and the r-universe build image ships quarto, python3 and pip, but no conda at all. So BiocBook brings its own.
micromamba is a single self-contained binary: no conda installation, no base environment, no python.
BiocBook::micromamba() resolves it in order:
-
RETICULATE_CONDA, if you have set it; - a
micromambaalready on thePATH; - a copy previously downloaded into
BiocBook’s cache (this book’sDockerimage keeps the one it downloads while it is built); - failing all of those, it downloads a pinned release and checks it against a recorded
SHA256before using it.
R chunk on the page
quarto chooses its execution engine per file. A page with at least one R chunk uses knitr, and runs its python chunks through reticulate. A page whose only code is python uses jupyter instead. However, the Bioconductor builders do not provide jupyter, so a jupyter page cannot be rendered there at all.
To force quarto to use knitr, keep at least one R chunk on the page, even if it is empty.
4.3 A worked example
reticulate hosts a single, persistent python session that is shared with R, so objects can be passed in both directions.
Start from an R object:
The R object is reachable from python through the r object:
import numpy as np
counts = np.array(r.counts)
print("shape:", counts.shape)
## shape: (3, 3)
print("library sizes:", counts.sum(axis = 0))
## library sizes: [ 57. 101. 38.]State persists from one python chunk to the next, exactly as it would in a notebook:
cpm = counts / counts.sum(axis = 0) * 1e6
print("CPM values:")
## CPM values:
print(np.round(cpm, 1))
## [[210526.3 29703. 0. ]
## [ 0. 69306.9 131578.9]
## [789473.7 900990.1 868421.1]]Finally, the python object can be passed back to R:
cpm <- reticulate::py$cpm
cpm
## [,1] [,2] [,3]
## [1,] 210526.3 29702.97 0.0
## [2,] 0.0 69306.93 131578.9
## [3,] 789473.7 900990.10 868421.1
4.4 Command-line tools from bioconda
The conda part of the environment can hold any command-line tool from the bioconda channel, e.g. samtools. A tool runs in its own process, with its own libraries, so it cannot clash with the R session. setup_python() puts it on the PATH, for bash chunks…
bash
samtools --version | head -n 1
## samtools 1.24… as well as for system2() in R, and for subprocess in python:
import subprocess
v = subprocess.run(["samtools", "--version"], capture_output = True, text = True).stdout.splitlines()[0]Then read that in R:
reticulate::py$v
## [1] "samtools 1.24"4.5 Session info
sessioninfo::session_info()
## ─ Session info ────────────────────────────────────────────────────────────
## setting value
## version R version 4.6.1 (2026-06-24)
## os Ubuntu 24.04.5 LTS
## system x86_64, linux-gnu
## ui X11
## language (EN)
## collate C
## ctype en_US.UTF-8
## tz Etc/UTC
## date 2026-10-30
## pandoc 3.12.1 @ /usr/bin/ (via rmarkdown)
## quarto 1.11.5 @ /usr/local/bin/quarto
##
## ─ Packages ────────────────────────────────────────────────────────────────
## package * version date (UTC) lib source
## askpass 1.2.1 2024-10-04 [2] RSPM (R 4.6.0)
## BiocBook 1.11.7 2026-10-30 [2] Github (js2264/BiocBook@504d3a6)
## BiocGenerics 0.59.12 2026-08-11 [2] Bioconductor 3.24 (R 4.6.1)
## cli 3.6.6 2026-04-09 [2] RSPM (R 4.6.0)
## credentials 2.0.3 2025-09-12 [2] RSPM (R 4.6.0)
## digest 0.6.39 2025-11-19 [2] RSPM (R 4.6.0)
## dplyr 1.2.1 2026-04-03 [2] RSPM (R 4.6.0)
## evaluate 1.0.5 2025-08-27 [2] RSPM (R 4.6.0)
## fastmap 1.2.0 2024-05-15 [2] RSPM (R 4.6.0)
## fs 2.1.0 2026-04-18 [2] RSPM (R 4.6.0)
## generics 0.1.4 2025-05-09 [2] RSPM (R 4.6.0)
## gert 2.5.0 2026-10-14 [2] RSPM (R 4.6.0)
## gh 1.6.1 2026-07-20 [2] RSPM (R 4.6.0)
## gitcreds 0.1.2 2022-09-08 [2] RSPM (R 4.6.0)
## glue 1.8.1 2026-04-17 [2] RSPM (R 4.6.0)
## htmltools 0.5.9 2025-12-04 [2] RSPM (R 4.6.0)
## htmlwidgets 1.6.4 2023-12-06 [2] RSPM (R 4.6.0)
## httr 1.4.9 2026-09-01 [2] RSPM (R 4.6.0)
## jsonlite 2.0.0 2025-03-27 [2] RSPM (R 4.6.0)
## knitr 1.52 2026-09-06 [2] RSPM (R 4.6.0)
## lattice 0.23-1 2026-08-12 [2] RSPM (R 4.6.1)
## lifecycle 1.0.5 2026-01-08 [2] RSPM (R 4.6.0)
## magrittr 2.0.5 2026-04-04 [2] RSPM (R 4.6.0)
## Matrix 1.7-6 2026-07-25 [2] RSPM (R 4.6.1)
## openssl 2.4.2 2026-06-09 [2] RSPM (R 4.6.0)
## otel 0.2.0 2025-08-29 [2] RSPM (R 4.6.0)
## pak 0.11.1 2026-07-22 [2] RSPM (R 4.6.0)
## pillar 1.11.1 2025-09-17 [2] RSPM (R 4.6.0)
## pkgconfig 2.0.3 2019-09-22 [2] RSPM (R 4.6.0)
## png 0.1-9 2026-03-15 [2] RSPM (R 4.6.0)
## purrr 1.2.2 2026-04-10 [2] RSPM (R 4.6.0)
## R6 2.6.1 2025-02-15 [2] RSPM (R 4.6.0)
## Rcpp 1.1.2 2026-07-05 [2] RSPM (R 4.6.0)
## renv 1.3.1 2026-10-06 [2] RSPM (R 4.6.0)
## reticulate * 1.47.0 2026-09-03 [2] RSPM (R 4.6.0)
## rlang 1.3.0 2026-07-05 [2] RSPM (R 4.6.0)
## rmarkdown 2.32 2026-09-01 [2] RSPM (R 4.6.0)
## rprojroot 2.1.1 2025-08-26 [2] RSPM (R 4.6.0)
## sessioninfo 1.2.4 2026-06-04 [2] RSPM (R 4.6.0)
## stringi 1.8.9 2026-08-04 [2] RSPM (R 4.6.0)
## stringr 1.6.0 2025-11-04 [2] RSPM (R 4.6.0)
## sys 3.4.3 2024-10-04 [2] RSPM (R 4.6.0)
## tibble 3.3.1 2026-01-11 [2] RSPM (R 4.6.0)
## tidyselect 1.2.1 2024-03-11 [2] RSPM (R 4.6.0)
## usethis 3.2.2 2026-09-10 [2] RSPM (R 4.6.0)
## vctrs 0.7.3 2026-04-11 [2] RSPM (R 4.6.0)
## withr 3.0.3 2026-06-19 [2] RSPM (R 4.6.0)
## xfun 0.62 2026-10-16 [2] RSPM (R 4.6.0)
## yaml 2.3.12 2025-12-10 [2] RSPM (R 4.6.0)
##
## [1] /tmp/Rtmp2UlXxq/Rinstb7a8b5f19
## [2] /usr/local/lib/R/site-library
## [3] /usr/local/lib/R/library
## * ── Packages attached to the search path.
##
## ─ Python configuration ────────────────────────────────────────────────────
## python: /opt/R-cache/R/BiocBook/envs/BiocBookDemo-faf828c9fe1d/bin/python
## libpython: /opt/R-cache/R/BiocBook/envs/BiocBookDemo-faf828c9fe1d/lib/libpython3.12.so
## pythonhome: /opt/R-cache/R/BiocBook/envs/BiocBookDemo-faf828c9fe1d:/opt/R-cache/R/BiocBook/envs/BiocBookDemo-faf828c9fe1d
## version: 3.12.16 (main, Oct 26 2026, 11:37:43) [GCC 15.3.0]
## numpy: /opt/R-cache/R/BiocBook/envs/BiocBookDemo-faf828c9fe1d/lib/python3.12/site-packages/numpy
## numpy_version: 2.5.4
##
## NOTE: Python version was forced by RETICULATE_PYTHON
##
## ───────────────────────────────────────────────────────────────────────────