gget: one-line queries against a dozen genomic databases
🧬 gget enables efficient querying of genomic reference databases
At a glance
- What is it?
- gget is a Python package and command line tool that wraps a collection of reference databases, from Ensembl and UniProt to PDB, BLAST, Enrichr and cellxgene, behind one consistent interface. It suits a researcher who needs a gene identifier turned into a sequence or a structure in one command, and it is a thin client whose behaviour is bounded by what the upstream APIs allow.
- Who is it for?
- gget fits a researcher or a student who needs one specific fact from one specific database and does not want to write an API client, because the same call works from the shell, from Python, from a notebook and from R, and because the setup step for the heavier modules is a single command.
- Can I use it commercially?
- Yes. BSD-2-Clause is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
- Is it still maintained?
- Yes. The repository last received commits 1 day ago.
- What is it written in?
- Mainly Python, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on October 23, 2026, and from our analysis. They are not legal advice.
Editorial analysis
A collection of modules, not one tool with a big API
gget is a free, open-source command-line tool and Python package that enables efficient querying of genomic databases. It consists of a collection of separate but interoperable modules, each designed to facilitate one type of database querying in a single line of code.
That phrase, one type of database querying in a single line of code, is the design contract. Every module does one thing and does it in a way that matches how a biologist would phrase the question. There is a module to fetch reference files, one to search for genes by name, one to look up information about an identifier, one to fetch sequences, one to find a sequence's genomic location, one to run a BLAST search, one to align sequences, one to run an ontology enrichment, one to get tissue expression, one to fetch a protein structure, one to download viral genomes, one to find linear motifs in a protein, and one to pull a single cell count matrix.
The quick start guide makes the shape concrete. The command line examples are a tour of the whole set:
# Fetch all Homo sapiens reference and annotation FTPs from the latest Ensembl release
$ gget ref homo_sapiens
# Get Ensembl IDs of human genes with "ace2" or "angiotensin converting enzyme 2" in their name/description
$ gget search -s homo_sapiens 'ace2' 'angiotensin converting enzyme 2'
# Look up gene ENSG00000130234 (ACE2) and its transcript ENST00000252519
$ gget info ENSG00000130234 ENST00000252519
# Fetch the amino acid sequence of the canonical transcript of gene ENSG00000130234
$ gget seq --translate ENSG00000130234The Python API is the same set of calls with the same arguments:
import gget
gget.ref("homo_sapiens")
gget.search(["ace2", "angiotensin converting enzyme 2"], "homo_sapiens")
gget.info(["ENSG00000130234", "ENST00000252519"])
gget.seq("ENSG00000130234", translate=True)And there is a third front end, which is the one that makes the tool usable from a language the authors did not write it in. Calling gget from R using reticulate is a documented workflow, with the R syntax mapping onto the Python one:
system("pip install gget")
install.packages("reticulate")
library(reticulate)
gget <- import("gget")
gget$ref("homo_sapiens")
gget$search(list("ace2", "angiotensin converting enzyme 2"), "homo_sapiens")The R examples in the documentation are noticeably thinner than the Python ones, which tells you the R path is supported but is the second-class citizen. The reticulate bridge also means an R user needs a working Python environment, which is a real setup cost for an R-first lab.
The heavier modules need a setup step before they work
Two modules in the quick start have an extra line in front of them, and the reason is worth understanding.
# Find Eukaryotic Linear Motifs (ELMs) in a protein sequence
$ gget setup elm # setup only needs to be run once
$ gget elm -o results MSSSSWLLLSLVAVTAAQSTIEEQAKTFLDKFNHEAEDLFYQSSLAS
# Fetch a scRNAseq count matrix (AnnData format) based on specified gene(s), tissue(s), and cell type(s) (default species: human)
$ gget setup cellxgene # setup only needs to be run once
$ gget cellxgene --gene ACE2 SLC5A1 --tissue lung --cell_type 'mucus secreting cell' -o example_adata.h5adThe comment is the same in both, setup only needs to be run once, which tells you the setup is not trivial. The cellxgene module is the clearest case, because the dependency explanation in the package manifest describes exactly what has to be downloaded and why it is awkward.
The optional dependency is `cellxgene-census` plus `scanpy>=1.10`, and the manifest explains the pinning in detail. The scanpy pin is defensive, not because gget uses scanpy directly, but because tiledbsoma, which is a dependency of cellxgene-census, declares only `scanpy>=1.9.2`. Under certain resolver paths, uv lands on scanpy 1.9.8, which transitively pins numba 0.53.1 and llvmlite 0.36.x, and both of those only support Python 3.6 to 3.9.
That is a very specific problem, and it is the kind that only shows up on a fresh machine with a particular resolver, which is exactly why it is written down in the dependency file.
The comment also notes that there are no wheels for the newest Python versions yet, for example 3.14 via tiledbsoma, which lines up with the comment about needing Python 3.14 support in the classifiers while the native dependency is not there yet.
The design choice is sound. Putting the heavy native dependencies behind an extra and the core package behind none means `pip install gget` gives you a working tool for the modules that need nothing more than an HTTP request, and the module that needs a compiled stack is opt in.
Licences shaped the dependency list
The dependency list in the manifest is worth reading closely, because two of the entries carry an explanation and both are about licences rather than about features.
The first is the `search` module. The optional dependency for `gget search` is `mysql-connector-python`, and the comment is that it is GPL-2.0 licensed, so it is kept out of the core dependencies to avoid imposing GPL. The rest of the comment is truncated in what is available here, but the reasoning is clear and it is a good one.
A tool that anyone might install for a quick query should not, by default, pull in a GPL dependency and impose those terms on every user. The alternative would be to reimplement the MySQL access, which is what a permissive-licence project has to do if it wants the feature. Putting it behind an extra keeps the core install clean and lets a user who needs it opt in knowingly.
The second entry is the cellxgene one described above, where the licence is not the problem but the resolver behaviour is, and the answer is a defensive pin with a comment explaining exactly what breaks.
The core dependencies are otherwise unremarkable for the domain: beautifulsoup4 and lxml for parsing the HTML that some of these databases return, requests for the HTTP, pandas and numpy for the tabular results, matplotlib for the plots that the enrichment module produces, tqdm for progress bars on the file downloads, and ipython with ipywidgets for the notebook integration.
The package is BSD-2-Clause licensed, which is the same permissive choice the core dependency list implies, and the project is part of the scverse project and is fiscally sponsored by NumFOCUS, with the NumFOCUS badge in the README. The build backend is hatchling and the package requires Python 3.12 or newer, with classifiers for 3.12, 3.13 and 3.14.
The manifest version is 0.30.9 while the most recent tagged release listed is v0.30.8, so the development version is ahead of the last release, and the release notes for the recent ones are informative about the maintenance style: v0.30.8 with opentargets and g2p fixes, v0.30.7 with a change described as modernize gget, and v0.30.6 with bugs and fallbacks.
What the modules actually cover
The topic list and the quick start together give the full map, and it is worth sorting the modules by what kind of question they answer.
Reference and identifier lookups come first. `gget ref` fetches reference and annotation FTP files from an Ensembl release for a species. `gget search` finds Ensembl IDs by name or description, and it is the module with the GPL-2.0 dependency behind it. `gget info` looks up an Ensembl gene or transcript identifier and returns the record, including the PDB identifier when there is one, which is how the structure workflow chains together.
Sequence work follows. `gget seq` fetches the sequence of a gene or transcript, with a translate option for the amino acid sequence. `gget blat` finds where a sequence sits in the genome. `gget blast` runs a BLAST search for a sequence. `gget muscle` aligns several nucleotide or amino acid sequences against each other, and it accepts paths to FASTA files as well as raw sequences. `gget diamond` aligns one or more sequences against a reference using DIAMOND, which is the faster local BLAST.
Analysis and context modules. `gget enrichr` runs an ontology enrichment over a list of genes against Enrichr, with a plot option. `gget archs4` returns tissue expression for a gene, with a tissue mode in the quick start. `gget pdb` fetches a protein structure in PDB format. `gget virus` downloads viral genome datasets from NCBI Virus, with a host and a nucleotide completeness filter. `gget elm` finds Eukaryotic Linear Motifs in a protein sequence, and it returns two dataframes, one orthogonal and one regex based. `gget cellxgene` fetches a single cell RNA sequencing count matrix in AnnData format, filtered by gene, tissue and cell type.
The topic list names the databases behind these: alphafold and alphafold2, archs4, blast, cellxgene, enrichr, ensembl, ncbi, proteomics, rna-seq, transcriptomics and uniprot.
Two things stand out about that list. First, the tools are chosen to compose. The quick start runs them in sequence on the same gene, ACE2, from the Ensembl identifier through the amino acid sequence, through locating it, through the structure, through the expression and through the enrichment. Each step consumes the output of the last.
Second, the scope is deliberately reference databases and public archives, not patient data or proprietary sources. That is a sensible boundary for a tool that a student can install without a data access agreement.
Where a thin client over live APIs falls short
The honest limitations of gget follow from its architecture, and it is worth being clear about them before you build a pipeline on it.
The first is that the answers are not fixed. Most of these modules call live public APIs, and the underlying databases get revised. An Ensembl release moves, a UniProt record is updated, a PDB entry is superseded. A result that is correct today may differ next month, and there is no version pin on the data itself. The `ref` module at least names a release, but the identifier lookups do not carry a release stamp into their output.
The second is that a shared public API is a shared point of failure. Rate limits, maintenance windows and the occasional outage are all outside the tool's control, and the quick start's own examples reflect that with modules that have a setup step and a note that the service may be down.
The third is that gget is a client, so its data is only as good as the source. It does not reconcile Ensembl identifiers with UniProt accessions, it does not tell you which of two annotations is the one you want, and it does not check that the transcript you looked up is the canonical one. The paper this project published makes that point in its framing, efficient querying of genomic reference databases, and the enrichment module's reliance on a gene symbol list is a good illustration. Passing `ACE2` to an enrichment tool and getting back a list of related ontology terms is only as good as the symbol mapping underneath it.
The alternative approaches are worth naming. A local tool like the NCBI command line utilities or Ensembl's REST client gives you more control and, for a repeat pipeline, reproducibility, at the cost of writing the glue. A Bioconductor package for a specific task does one thing properly. And for large scale work, a workflow manager with pinned container images and cached reference files is the right answer, and gget is a reasonable component inside such a workflow rather than a replacement for one.
For a one-off question, a thesis figure, or a course demonstration, gget is exactly right, and the one-line interface is a genuine advantage over writing a client.
On maintenance, the project is well resourced for its size. It was developed by Laura Luebbert in the Pachter Lab, it is part of scverse, it is fiscally sponsored by NumFOCUS, and there is a CITATION.cff file and a published paper in Bioinformatics, Luebbert and Pachter, 2023, with a DOI. The citation request in the README, if you use gget in a publication please cite, is the kind of request that is usually ignored and usually matters.
Editorial conclusion
gget fits a researcher or a student who needs one specific fact from one specific database and does not want to write an API client, because the same call works from the shell, from Python, from a notebook and from R, and because the setup step for the heavier modules is a single command. Skip it if you need a reproducible offline pipeline, since most modules query live APIs and the databases move, and skip it if the licence of a dependency rules it out, because the maintainers have already had to move one out of the core dependencies for exactly that reason. Before you build on it, run the `gget setup` step for the modules you need and pin a version, since the package is at 0.30.9 in the manifest and moves quickly. The last push was on 2026-10-15.
Frequently asked questions
What is gget?
It is a free, open-source command-line tool and Python package that enables efficient querying of genomic databases, consisting of a collection of separate but interoperable modules, each designed to facilitate one type of database querying in a single line of code.
How do I install gget?
Run `uv pip install gget` or `pip install --upgrade gget`, or install from source with `git clone https://github.com/scverse/gget.git`, `cd gget` and `uv pip install .`. The package requires Python 3.12 or newer.
Why do the elm and cellxgene modules need a setup step?
They depend on heavier native dependencies that are not installed with the core package, so `gget setup elm` and `gget setup cellxgene` fetch them. The cellxgene extra pulls in cellxgene-census and scanpy, and the manifest notes there are no wheels for the newest Python versions yet via tiledbsoma.
Can I use gget from R?
Yes, through reticulate. Run `system("pip install gget")`, install reticulate, then `gget <- import("gget")` and call the modules with the R syntax, for example `gget$search(list("ace2"), "homo_sapiens")`.
What licence is gget under and what are its dependencies?
The package itself is BSD-2-Clause licensed. The core dependencies are beautifulsoup4, ipython, ipywidgets, lxml, matplotlib, numpy, pandas, requests and tqdm, with cellxgene and search extras kept out of the core, the latter because mysql-connector-python is GPL-2.0 licensed.
Official sources
Add this badge to your README
If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.
[](https://hysenlabs.com/projects/scverse-gget)Was this useful?