Skip to main content

GenomeUtils

A Python library for working with annotated genomes. We developed GenomeUtils as an alternative/replacement for the no longer maintained pyensembl.

Object-oriented model for representing genomic features: genomes, chromosomes, genes, transcripts, and exons.

Features

  • Object model: Genome > Chromosome > Gene > Transcript > Exon (+ Locus)
  • Builder workflow: GenomeBuilder assembles a Genome from FASTA (DNA, cDNA) and GTF
  • Indexed lookups, optional scaffold separation, streaming/gzip handling
  • Downloader utilities: Fetch Ensembl DNA, cDNA, and GTF assets with EnsemblGenomeDownloader

Installation

You can install GenomeUtils via pip with the following command:

pip install GenomeUtils

Requires Python >= 3.10. Dependencies that will be installed automatically by pip are: biopython, gffutils, requests, gget.

Quickstart

1) Download and build a genome (complete workflow)

from pathlib import Path
from GenomeUtils.Downloaders import EnsemblGenomeDownloader
from GenomeUtils.Genome import GenomeBuilder

# Download Ensembl assets
destinations = {
    "dna": Path("./data/genome.fa.gz"),
    "cdna": Path("./data/transcripts.fa.gz"),
    "annotation": Path("./data/annotation.gtf.gz"),
    "db": Path("./data/annotation.db"),
}
downloader = EnsemblGenomeDownloader(
    assembly_id="GRCh38",
    ensembl_release=114,
    species="homo_sapiens",
    destinations=destinations,
)

files = downloader.download(output_db=True)
print(files)  # Exact destination Paths under dna, cdna, annotation, and db


# Build genome from downloaded files
# The builder automatically uses species-appropriate chromosomes:
# Human: 1-22,X,Y,M,MT | Mouse: 1-19,X,Y,M,MT
genome, scaffold_genome = (
    GenomeBuilder(id="GRCh38", species="Homo sapiens", name="Human")
      .with_dna_fasta(files['dna'])
      .with_cdna_fasta(files['cdna'])
      .with_gtf_file(files['annotation'])
      .build()
)

# For other species:
# mouse_genome = GenomeBuilder(id="GRCm39", species="Mus musculus", name="Mouse")...

# Access features
chromosome = genome.chromosome_by_id("1")
first_gene = chromosome.genes[0]
print(first_gene.id, first_gene.name)

# Fast lookups (after build() the genome is indexed)
print(genome.gene_by_id(first_gene.id))

The genomes_root_dir/ensembl/{assembly}/{release} layout remains available when explicit destinations are not needed. By default, download() and get_urls() select dna, cdna, and annotation. Choose files through the public outputs parameter, for example:

downloader = EnsemblGenomeDownloader("GRCh38", 114, "homo_sapiens")
files = downloader.download(outputs=["dna", "cdna", "annotation", "ncrna"])
# Or download just the ncRNA FASTA:
files = downloader.download(outputs=["ncrna"])

In explicit mode, provide a destination for each selected output, including ncrna when requested. Only selected outputs are downloaded. The annotation database stays separate: use output_db=True and include annotation in outputs. An explicit db destination is required with output_db=True and rejected with output_db=False.

2) Build a genome from existing files

from pathlib import Path
from GenomeUtils.Genome import GenomeBuilder

# Prepare input files (can be .gz):
dna_fasta = Path("/path/to/genome.dna.fa.gz")
cdna_fasta = Path("/path/to/genome.cdna.fa.gz")
gtf_file  = Path("/path/to/annotations.gtf.gz")

builder = GenomeBuilder(
    id="hg38",
    species="Homo sapiens",
    name="Human Reference Genome",
    separate_scaffolds=False,  # set True to split non-main scaffolds
)

# Optional: limit to specific chromosomes (must be called before with_dna_fasta)
builder.set_chromosome_filter(["chr1", "chr2", "chrX"])  # or ["1","2","X"]

genome, _ = (
    builder
      .with_dna_fasta(dna_fasta)
      .with_cdna_fasta(cdna_fasta)
      .with_gtf_file(gtf_file)
      .build()
)

# Access features
chromosome = genome.chromosome_by_id("chr1")
first_gene = chromosome.genes[0]
print(first_gene.id, first_gene.name)

# Fast lookups (after build() the genome is indexed)
print(genome.gene_by_id(first_gene.id))

3) Minimal toy example (no files)

from Bio.Seq import Seq
from Bio.SeqRecord import SeqRecord
from GenomeUtils.Genome import Genome, Chromosome, Gene, Transcript, Exon

# Create a tiny in-memory genome
genome = Genome(id="toy", species="Test species", name="Toy Genome")
chr1_seq = SeqRecord(Seq("AGCATGATGCATGCATGCATGCATGCATGCATGCATGCATGCATGCATGCATGC"), id="chr1")
chromosome = Chromosome("chr1", seq_index={"chr1": chr1_seq}, genome=genome, length=len(chr1_seq.seq))

genome.add_chromosome(chromosome)

gene = Gene(id="GENE001", chr=chromosome.id, name="MYGENE", start=5, end=35, strand='+', genome=genome, chromosome=chromosome)
chromosome.add_gene(gene)

transcript = Transcript(
    id="TRANSCRIPT001",
    chr=chromosome.id,
    start=5,
    end=35,
    strand='+',
    sequence=Seq("CATGATGCATGCATGCATGCATGCATGC"),
    gene=gene,
    genome=genome,
)

gene.add_transcript(transcript)

exon1 = Exon(id="EXON001", chr=chromosome.id, start=5, end=15, strand='+', gene=gene, genome=genome)
exon1.add_transcript(transcript)
transcript.add_exon(exon1)

exon2 = Exon(id="EXON002", chr=chromosome.id, start=25, end=35, strand='+', gene=gene, genome=genome)
exon2.add_transcript(transcript)
transcript.add_exon(exon2)


genome.index()
print(genome.gene_by_id("GENE001").name)

4) Species-specific examples

from pathlib import Path
from GenomeUtils.Downloaders import EnsemblGenomeDownloader
from GenomeUtils.Genome import GenomeBuilder

# Human genome (uses chromosomes 1-22, X, Y, M, MT)
human_genome, _ = GenomeBuilder(
    id="GRCh38", 
    species="Homo sapiens", 
    name="Human Reference Genome"
).with_dna_fasta(human_dna).with_gtf_file(human_gtf).build()

# Mouse genome (uses chromosomes 1-19, X, Y, M, MT)  
mouse_genome, _ = GenomeBuilder(
    id="GRCm39", 
    species="Mus musculus", 
    name="Mouse Reference Genome"
).with_dna_fasta(mouse_dna).with_gtf_file(mouse_gtf).build()


# Override default chromosomes if needed
custom_genome, _ = GenomeBuilder(
    id="custom", 
    species="Custom species", 
    name="Custom Genome",
    main_chromosomes=["chr1", "chr2", "chrX"]  # Only these chromosomes
).with_dna_fasta(custom_dna).with_gtf_file(custom_gtf).build()

Technical Documentation

Find the technical documentation here. APIs may evolve.

Contributing

Issues and PRs are welcome.

Copyright 2026, Alexander Schliep

Metadata

Release files for GenomeUtils 0.2.1

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for GenomeUtils 0.2.1
File Size Uploaded Provenance Actions
genomeutils-0.2.1.tar.gz 32.7 kB Without provenance Details for genomeutils-0.2.1.tar.gz

Built distribution (wheel)

Table of built distributions (wheels) for GenomeUtils 0.2.1
File Interpreter ABI Platform Actions
genomeutils-0.2.1-py3-none-any.whl Python 3 none any Details for genomeutils-0.2.1-py3-none-any.whl

Total release size: 74.3 kB

Release files / genomeutils-0.2.1.tar.gz

Download URL genomeutils-0.2.1.tar.gz
Size 32.7 kB
Tags Source
SHA-256 checksum
How to use checksums
2f9e956d54390caca77cd17089d7ee678c88fd5fa35fc89e9cd1dd8e5ed28e63
BLAKE2b-256 checksum
How to use checksums
0a14c252fac6a6b37c11221c94bb9594b56cc200b0e006dd7b64386ee14ca04b
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.12.4

Release files / genomeutils-0.2.1-py3-none-any.whl

Download URL genomeutils-0.2.1-py3-none-any.whl
Size 41.6 kB
Tags Python 3
SHA-256 checksum
How to use checksums
827e9913cc8dbc9032f5ac8497d104e9a4292f92678ea82232f64dc2a567a10f
BLAKE2b-256 checksum
How to use checksums
d6f458b72b4f41a5c364df174fb986196614b61dbe7d07fbd1b406d3eb4e0562
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.12.4

Security for GenomeUtils 0.2.1

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.

No provenance found

None of the files in this release were uploaded with provenance metadata.

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

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