A lightweight, dependency-free biological sequence processing toolkit (FASTA/FASTQ, stats, k-mer, minimizer, indexing).
Project description
bioseqkit
A lightweight, dependency-free biological sequence processing toolkit built
from scratch in pure Python. bioseqkit implements FASTA/FASTQ parsing,
sequence statistics, transformations, k-mer / minimizer analysis and FAI-like
random-access indexing, exposed both as a Python API and a command-line tool.
The project is a teaching implementation for BIO2502 (Programming Languages for Biological Computing): it deliberately re-implements the low-level I/O, streaming and indexing logic instead of relying on Biopython, so the core design patterns of bioinformatics data handling are made explicit.
Features
- Streaming FASTA/FASTQ parsers (
io) — generator based, constant memory, transparent gzip support, Phred quality decoding. - Statistics (
stats) — length distribution, N50, GC content, N-base ratio, base-composition matrix. - Transformations (
transform) — reverse complement (IUPAC aware), DNA↔RNA transcription, and six-frame translation with the standard genetic code. - k-mer analysis (
kmer) — counting, top-k, canonical k-mers, multi-process parallel counting, and minimizer sampling. - FAI-like indexing (
index) —samtools faidx-compatible index forchr:start-endrandom access without scanning the whole file. - CLI (
cli) —stats,revcomp,translate,transcribe,kmer,minimizer,index,fetch. - NCBI download (
entrez) — fetch reference sequences via E-utilities (standard-library HTTP only).
Project layout
bioseqkit/
├── pyproject.toml # src-layout, PEP 621 metadata, console script
├── README.md
├── LICENSE
├── src/bioseqkit/
│ ├── __init__.py # public API
│ ├── io.py # FASTA/FASTQ parsers
│ ├── stats.py # sequence statistics
│ ├── transform.py # revcomp + six-frame translation
│ ├── kmer.py # k-mer / minimizer (serial + parallel)
│ ├── index.py # FAI-like random-access index
│ ├── entrez.py # NCBI download helper
│ └── cli.py # argparse CLI
├── tests/ # pytest suite (io/stats/transform/kmer/index/cli)
├── benchmarks/ # benchmark driver + complexity analysis
├── workflow/ # Snakemake pipeline (Snakefile)
├── config/config.yaml # workflow configuration
├── examples/
│ ├── demo.ipynb # Jupyter demo (stats, GC, k-mer spectrum, ...)
│ └── example_data/sample.fa
├── docs/ # Sphinx documentation
├── flake.nix # Nix flake: reproducible dev shell + Docker/Apptainer images
├── flake.lock # pinned nixpkgs revision (bit-reproducible builds)
└── .github/workflows/ci.yml
Installation
Requires Python >= 3.10. The core package has no runtime dependencies.
pip install bioseqkit
# with optional extras (plots for the notebook / NCBI download / docs)
pip install "bioseqkit[viz,net,docs]"
Reproducible builds with Nix
A Nix flake is provided as a single, bit-for-bit reproducible
source of truth. Because flake.lock pins the exact nixpkgs revision, every
build — the package, the dev shell and the container images — is fully
reproducible. From the one flake you can:
nix run . # run the bioseqkit CLI
nix build .#default # build the Python package (runs the test suite)
nix develop # enter a reproducible dev shell (python + uv + typst + pytest ...)
nix build .#docker # build an OCI/Docker image -> docker load < result
nix build .#apptainer # build an Apptainer/Singularity (.sif) image
This supersedes a hand-written Dockerfile/Apptainer recipe: both container images are derived from the same pinned dependency graph, so they can never drift from the tested build.
Command-line usage
bioseqkit stats examples/example_data/sample.fa # JSON statistics
bioseqkit revcomp examples/example_data/sample.fa # reverse complement
bioseqkit translate examples/example_data/sample.fa # six-frame translation
bioseqkit transcribe examples/example_data/sample.fa # DNA -> RNA (T -> U)
bioseqkit kmer examples/example_data/sample.fa -k 5 --top 10 --canonical
bioseqkit kmer examples/example_data/sample.fa -k 5 -t 4 # parallel
bioseqkit minimizer examples/example_data/sample.fa -k 15 -w 10
bioseqkit index examples/example_data/sample.fa # write *.fai
bioseqkit fetch examples/example_data/sample.fa seq2:1-16
Understanding the output
stats prints a JSON object; each field means:
| Field | Meaning |
|---|---|
n_seqs |
number of sequences in the file |
total_length |
sum of all sequence lengths (bp) |
min_length / max_length |
shortest / longest sequence |
mean_length |
average sequence length |
n50 |
length such that sequences ≥ this length cover ≥ 50% of total_length (assembly contiguity metric) |
gc_content |
fraction of G/C bases in [0, 1] — useful for species/GC-bias assessment |
n_ratio |
fraction of ambiguous N bases — a data-quality indicator |
base_counts |
per-base counts (A/C/G/T/N/...), the base-composition matrix |
kmer prints a tab-separated kmer<TAB>count table, one line per k-mer,
sorted by descending frequency (top---top). With --canonical, a k-mer and
its reverse complement are counted together, so results are strand-independent.
revcomp / translate / transcribe emit FASTA to stdout. translate
produces six records per input sequence, suffixed _frame+1..+3 (forward
strand, offsets 0/1/2) and _frame-1..-3 (reverse-complement strand); *
denotes a stop codon and X an untranslatable codon. transcribe returns the
RNA form of each sequence (every T replaced by U).
minimizer prints seq_id<TAB>position<TAB>minimizer — the sampled k-mers
and their 0-based positions along the sequence.
index writes a <file>.fai (name, length, offset, bases-per-line,
bytes-per-line); fetch prints the requested sub-sequence as FASTA using
1-based inclusive coordinates.
Reproducible pipeline (Snakemake)
A Snakemake workflow chains the CLI into a
"data acquisition → processing → analysis" pipeline
(fetch_input → stats + kmer + index):
snakemake -c1 # run offline on the bundled example
snakemake -n # dry run: show the job DAG
snakemake -c4 --config accession=NC_012920.1 k=6 # download human chrM from NCBI, then analyse
Outputs are written to results/ (stats.json, kmers.tsv, input.fa.fai).
Configure input, accession and parameters in config/config.yaml.
Benchmarks & complexity
python benchmarks/bench.py # sweep 100 kbp .. 4 Mbp, write results.csv + scalability.png
See benchmarks/README.md for the full time/space
complexity table and measured scaling. In short: k-mer counting is O(n·k) and
scales to ~3× on four workers for inputs ≥ 1 Mbp; the FAI index builds in O(n)
and answers random fetch queries in tens of microseconds, independent of file
size. Micro-benchmarks are also runnable via pytest tests/test_benchmark.py --benchmark-only.
Python API
import bioseqkit as bsk
for rec in bsk.parse_fasta("examples/example_data/sample.fa"):
print(rec.id, len(rec), bsk.gc_content(rec.sequence))
print(bsk.reverse_complement("ATGC")) # -> GCAT
print(bsk.transcribe("ATGC")) # -> AUGC
print(bsk.translate("ATGGCCTAA")) # -> MA*
counts = bsk.count_kmers("ACGTACGTACGT", k=3, canonical=True)
print(bsk.top_kmers(counts, 3))
idx = bsk.build_faidx("examples/example_data/sample.fa")
print(idx.fetch("seq2", 1, 16))
Testing
uv run --with pytest pytest -q # 39 tests
Continuous integration (GitHub Actions) runs ruff linting, the pytest
suite with coverage on Python 3.10–3.12 for every push, and builds & deploys
the Sphinx documentation to GitHub Pages.
Data sources
- NCBI RefSeq: https://www.ncbi.nlm.nih.gov/refseq/
- NCBI Nucleotide: https://www.ncbi.nlm.nih.gov/nucleotide/
- NCBI Genome: https://www.ncbi.nlm.nih.gov/genome/
- UCSC Genome Browser: https://genome.ucsc.edu/
- Ensembl: https://www.ensembl.org/
For teaching and quick tests, a small bacterial genome or the human
mitochondrion (chrM, ~16.5 kbp) is recommended to keep files small. The
bundled examples/example_data/sample.fa is a tiny synthetic sequence for
offline testing; demo.ipynb downloads real data from NCBI when a network
connection is available and falls back to the bundled file otherwise.
License
MIT — see LICENSE.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file bioseqkit-0.2.0.tar.gz.
File metadata
- Download URL: bioseqkit-0.2.0.tar.gz
- Upload date:
- Size: 257.7 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: uv/0.11.26 {"installer":{"name":"uv","version":"0.11.26","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Arch Linux","version":null,"id":null,"libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
36a06cdbb5e5a910691bd8ff82382d051a12d263f51b33f86a85b5016f17e582
|
|
| MD5 |
3dab8d31b8cf41ed81f4601475c40344
|
|
| BLAKE2b-256 |
0417736266f7006139ba37a5809261a808ae58db48cd145b8a610d2d342fe8b2
|
File details
Details for the file bioseqkit-0.2.0-py3-none-any.whl.
File metadata
- Download URL: bioseqkit-0.2.0-py3-none-any.whl
- Upload date:
- Size: 18.3 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: uv/0.11.26 {"installer":{"name":"uv","version":"0.11.26","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Arch Linux","version":null,"id":null,"libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
28379a3b5a72d969a6abd9d3f42c8952a6ea7b94f9661931186d02aa756377de
|
|
| MD5 |
7cc0c5d7c9405d3ab95ee21ec1ae6abb
|
|
| BLAKE2b-256 |
778b5f0b9a3e7bf26ff4eb32320a8f18662f3a0c47c82c7ac1c3bfef004edf71
|