biotapy
biotapy is a microbiome analysis toolkit for Python, in the style of R's mia and phyloseq, built on AnnData/TreeData. Samples are always rows, the count matrix stays sparse, the phylogenetic tree sits alongside the data as a first-class object, and every computation with an R equivalent is checked against R on real data.
Status
biotapy 0.2 is an early release. The API can still change between minor versions.
What 0.2 does (full signatures in the API reference):
- Readers:
bt.io.read_biom(BIOM 1.0/2.1),bt.io.read_qiime2(.qzaartifacts, no QIIME 2 install needed),bt.io.read_dada2(CSV/TSV/.rdssequence tables),bt.io.read_phyloseq(.rds/.RData, no R needed) andbt.io.read_metaphlan(MetaPhlAn 3 and 4 profiles) all read into oneTreeData.bt.io.read_humannandbt.io.read_picrust2read function tables into aMuDatawith a community and a per-taxon modality;bt.io.read_picrust2_traitsreads PICRUSt2's per-ASV gene copy numbers. - Writer:
bt.io.write_biomwrites a BIOM 2.1 or 1.0 table back out. - Datasets:
bt.datasets.toyandbt.datasets.toy_humann(in-memory, for examples and tests),bt.datasets.global_patterns,bt.datasets.enterotypeandbt.datasets.esophagus(phyloseq's example datasets),bt.datasets.hmp2(the HMP2 inflammatory bowel disease cohort) andbt.datasets.enzyme(the ENZYME EC hierarchy), downloaded and cached on first use. - Preprocessing:
bt.pp.relative,bt.pp.tax_glom,bt.pp.filter_features,bt.pp.filter_samplesandbt.pp.rarefy. - Function:
bt.fn.load_hierarchy,bt.fn.func_glomandbt.fn.renorm(checked against HUMAnN's own output),bt.fn.contributionsandbt.fn.functional_redundancy. - Tools:
bt.tl.alpha,bt.tl.beta,bt.tl.unifrac,bt.tl.pcoa,bt.tl.nmdsandbt.tl.permanova, each checked against R on real data. - Plots:
bt.pl.bar,bt.pl.richness,bt.pl.ordination,bt.pl.scree,bt.pl.heatmapandbt.pl.contributions.
Next, in 0.3: compositional transforms (CLR, PhILR) and differential abundance (ANCOM-BC, LinDA, ALDEx2, MaAsLin 3) behind one result format. See the roadmap; no dates are promised.
Installation
You need Python 3.12 or newer.
pip install biotapy
or, with uv:
uv add biotapy
or, with pixi, in a workspace that has Python 3.12 or newer:
pixi add "python>=3.12"
pixi add --pypi biotapy
The development version installs straight from GitHub:
pip install git+https://github.com/pedrocr83/biotapy.git.
On Python 3.14, the biom-format dependency has no wheels yet, so it is built
from source and needs a C compiler until biom-format publishes 3.14 wheels
(biocore/biom-format#1004).
Quick start
Load the bundled toy dataset, add relative abundance, and aggregate to phylum:
import biotapy as bt
tdata = bt.datasets.toy()
tdata.shape # (6, 8): 6 samples, 8 features
rel = bt.pp.relative(tdata)
rel.layers["relative"][0].sum() # 1.0, X itself is untouched
glom = bt.pp.tax_glom(tdata, "phylum")
glom.n_vars # 3: features sharing a lineage down to phylum are merged
Reading your own data
Each reader returns a TreeData following the same data model.
Only the first argument is required; the keyword arguments attach taxonomy,
sample metadata and a phylogenetic tree where the format supports them.
# BIOM 1.0 (JSON) or 2.1 (HDF5), dialect detected automatically
tdata = bt.io.read_biom("table.biom", tree="tree.nwk")
# QIIME 2 artifacts (.qza), no QIIME 2 install required
tdata = bt.io.read_qiime2(
"table.qza", taxonomy="taxonomy.qza", tree="tree.qza", metadata="sample-metadata.tsv"
)
# DADA2 sequence tables: CSV, TSV or R's .rds, with optional taxonomy and tree
tdata = bt.io.read_dada2("seqtab.rds", taxa="taxa.rds", tree="tree.nwk")
# phyloseq objects saved from R with saveRDS()/save() - no R, no rpy2
tdata = bt.io.read_phyloseq("ps.rds")
# an .RData file can hold several phyloseq objects; pick one by its R variable name
tdata = bt.io.read_phyloseq("ps.RData", name="ps_16S")
Write back out to BIOM with bt.io.write_biom(tdata, "table.biom").
Example datasets
bt.datasets.global_patterns(), bt.datasets.enterotype() and
bt.datasets.esophagus() download phyloseq's example datasets once and cache
them on disk with pooch; later calls reuse the cache with no network
access, as long as the hash still matches. Set BIOTAPY_DATA_DIR to change
the cache directory:
import biotapy as bt
gp = bt.datasets.global_patterns() # 26 samples, 19,216 OTUs
gp.shape
Saving your work
A TreeData round-trips through treedata's own format, tree included:
tdata.write_h5td("tdata.h5td")
import treedata as td
back = td.read_h5td("tdata.h5td")
Dropping down to plain AnnData (no tree) works the usual way too:
tdata.write_h5ad("tdata.h5ad") / anndata.read_h5ad("tdata.h5ad").
The data model
Every biotapy function reads and writes the same object, a TreeData (an
AnnData that also carries a phylogeny):
| Slot | Holds |
|---|---|
X |
Samples x features, sparse CSR |
obs |
Sample metadata |
var |
Taxonomy, one column per rank: kingdom, phylum, class, order, family, genus, species |
vart["phylo"] |
The phylogenetic tree, leaves named after your features |
layers["relative"] |
Relative abundance, added by pp.relative |
uns["biotapy"] |
x_kind (what X currently holds: counts, relative, ...) and provenance (which biotapy functions produced this object, in order) |
See the data model guide for the full slot list (including the ones diversity and ordination write) and the data-model-slots contract for the exact rules.
Every function is pure by default: it returns a new object or its result and
leaves the one you passed in unchanged. Only a tl function called with
inplace=True writes its result into it (obs, obsp, obsm and
uns["biotapy"]).
Coming from R
Every function's docstring names its R equivalent (phyloseq::tax_glom,
mia::agglomerateByRank, and so on) in its Notes section, and the
Coming from R page lists them all, with the phyloseq accessors
that are plain AnnData code. The phyloseq analysis vignette is
redone with biotapy in the tutorials.
Example data and licensing
bt.datasets.global_patterns, bt.datasets.enterotype and
bt.datasets.esophagus download example data from
phyloseq's repository at runtime; biotapy ships none of it.
That data stays licensed to phyloseq's authors under AGPL-3.
bt.datasets.enzyme downloads ENZYME, distributed by the SIB Swiss Institute
of Bioinformatics under CC BY 4.0. bt.datasets.hmp2 downloads the HMP2
tables from the IBDMDB, which states no licence for them; cite
Lloyd-Price et al. (2019, Nature 569:655-662) when you use them. biotapy
itself is BSD-3-Clause.
Documentation
Full documentation, including the user guide and API reference, is at biotapy.readthedocs.io.
Development
uv sync --group dev --group test --group doc
uvx prek run --all-files
uv run --group test pytest
Network and golden tests (downloads data, compares against R) are excluded by default; run them explicitly with:
uv run --group test pytest -m "network or golden"
Regenerating the R golden files themselves needs the pinned R container - see the regenerate-golden-files playbook.
All contributions follow rules.md and the knowledge bundle (decisions, contracts, roadmap).
Release notes
See the changelog.
Contact
Questions, bug reports and feature requests all go to the issue tracker.
Citation
t.b.a
Metadata
Release files for biotapy 0.2.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| biotapy-0.2.0.tar.gz | 1.1 MB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| biotapy-0.2.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 1.2 MB
Release files / biotapy-0.2.0.tar.gz
| Download URL | biotapy-0.2.0.tar.gz |
|---|---|
| Size | 1.1 MB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
324de23e5ca2173960c1f636ea86a4c3ce0fb5a2b6524a23e67cbd8fc43685fb
|
|
BLAKE2b-256 checksum How to use checksums |
8eb0da54d4e5acadd46fbaaa88b21d145a1ac7f670a276fc3d49d0fc7606dcdc
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Oct 5, 2026.
Transparency logRelease files / biotapy-0.2.0-py3-none-any.whl
| Download URL | biotapy-0.2.0-py3-none-any.whl |
|---|---|
| Size | 95.1 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
b8c4bd3c58160dd1ac7b53d28e03cc3e7868f8969825f559d7c56d1ca982dcb5
|
|
BLAKE2b-256 checksum How to use checksums |
6b09f999cddc65798a8bc29dd6f3c37c7b7bee03b1b30e86a6398ba188728400
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Oct 5, 2026.
Transparency log