Skip to main content

biotapy

Tests Documentation

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 (.qza artifacts, no QIIME 2 install needed), bt.io.read_dada2 (CSV/TSV/.rds sequence tables), bt.io.read_phyloseq (.rds/.RData, no R needed) and bt.io.read_metaphlan (MetaPhlAn 3 and 4 profiles) all read into one TreeData. bt.io.read_humann and bt.io.read_picrust2 read function tables into a MuData with a community and a per-taxon modality; bt.io.read_picrust2_traits reads PICRUSt2's per-ASV gene copy numbers.
  • Writer: bt.io.write_biom writes a BIOM 2.1 or 1.0 table back out.
  • Datasets: bt.datasets.toy and bt.datasets.toy_humann (in-memory, for examples and tests), bt.datasets.global_patterns, bt.datasets.enterotype and bt.datasets.esophagus (phyloseq's example datasets), bt.datasets.hmp2 (the HMP2 inflammatory bowel disease cohort) and bt.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_samples and bt.pp.rarefy.
  • Function: bt.fn.load_hierarchy, bt.fn.func_glom and bt.fn.renorm (checked against HUMAnN's own output), bt.fn.contributions and bt.fn.functional_redundancy.
  • Tools: bt.tl.alpha, bt.tl.beta, bt.tl.unifrac, bt.tl.pcoa, bt.tl.nmds and bt.tl.permanova, each checked against R on real data.
  • Plots: bt.pl.bar, bt.pl.richness, bt.pl.ordination, bt.pl.scree, bt.pl.heatmap and bt.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)

Source distribution for biotapy 0.2.0
File Size Uploaded
biotapy-0.2.0.tar.gz 1.1 MB Details

Built distribution (wheel)

Table of built distributions (wheels) for biotapy 0.2.0
File Interpreter ABI Platform
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 log

Release 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

Release history Release notifications | RSS feed

This release

0.2.0 This release

2 release files

0.1.0

2 release files

0.0.1

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page