Where the Data Lives

You rarely generate data from scratch - you download it. Meet the handful of public databases that hold the world's biology, and learn to pull from them in code.

🟢 Beginner ⏱️ ~45 min 🐍 Python 🌐 Mostly browser

Before you start

  • A little basic Python from Python Basics helps when you reach the code-fetching part, but is not strictly required.
  • Any term new? The Glossary has it.

Learning objectives

By the end of this lesson you will be able to: name the big public repositories such as NCBI, Ensembl, SRA, GEO, and UniProt, fetch data from them in code rather than by clicking, and search a database instead of only downloading from it.

One of the best things about bioinformatics is how much data is free and public. Decades of experiments from labs worldwide sit in a few major databases, waiting for you to analyze them. Knowing which database holds what is half the battle.

The big five

NCBI

The U.S. hub for sequences, genes, and genomes. Home of GenBank and the Entrez search system - your first stop for a gene or a sequence.

ncbi.nlm.nih.gov →

Ensembl

Beautifully annotated genomes for humans and many species, with a genome browser. Great for "what genes are near this position?"

ensembl.org →

GEO

Gene Expression Omnibus - a giant archive of expression experiments (including RNA-seq) you can re-analyze, like the dataset in our flagship project.

GEO →

SRA

The Sequence Read Archive - the raw FASTQ reads behind published studies. This is where you go for the original sequencing data.

SRA →

UniProt

The reference for protein sequences and what they do - function, structure links, and disease associations.

uniprot.org →

Decode the jargon: accession numbers

Every record has a unique ID called an accession - like NM_000207 (the insulin mRNA) or GSE52778 (a GEO dataset). Accessions are how you (and your code) ask for one exact record. Collect the accession from a paper or a search, and you can fetch the data anywhere.

Fetching data in code (not by clicking)

You can download by hand from these websites, but the real power is pulling data programmatically so your analysis is reproducible. Biopython's Entrez module talks to NCBI for you. (NCBI just asks for an email so they can contact you about heavy usage.)

▶ Code along

In Colab, run !pip install biopython first.

Open a blank Colab →
from Bio import Entrez, SeqIO

Entrez.email = "your.email@example.com"   # any email works

# fetch the human beta-globin mRNA (the sickle-cell gene) by accession
handle = Entrez.efetch(db="nucleotide", id="NM_000518",
                       rettype="fasta", retmode="text")
record = SeqIO.read(handle, "fasta")
handle.close()

print(record.description)
print("Length:", len(record.seq), "bases")

That's the same pattern from the Python project - and it works for any accession. Swap the id and you can fetch any gene, on demand, in two lines.

Network blocked? Some school or work networks block NCBI. If the fetch fails, download the FASTA by hand from ncbi.nlm.nih.gov/nuccore/NM_000518 (Send to → File → FASTA) and load it with SeqIO.read("file.fasta", "fasta").

Searching, not just fetching

Don't have an accession yet? Entrez.esearch finds matching records first:

search = Entrez.esearch(db="nucleotide", term="BRCA1 Homo sapiens mRNA", retmax=5)
results = Entrez.read(search)
print(results["IdList"])   # a list of matching record IDs

Search to find IDs, then fetch those IDs - that two-step dance is the heart of programmatic data access.

Check your understanding

You want the raw FASTQ reads from a published study. Which database?
The SRA (Sequence Read Archive). GEO holds processed expression data; SRA holds the raw reads behind it.
What's an accession number, and why does it matter?
A unique ID for one record (e.g., NM_000518). It lets you - or your code - request that exact record reproducibly, from anywhere.
Why fetch data in code rather than clicking download?
Reproducibility. A script that fetches by accession can be re-run by anyone to get the identical data, and it scales to hundreds of records without manual clicking.
Why does Biopython's Entrez ask you to set Entrez.email before fetching?
NCBI just asks for an email so they can reach you about heavy usage. Any working email address is fine.
You have a paper that mentions accession NM_000518. What is the two-step pattern if you instead only had a gene name?
When you lack an accession, Entrez.esearch finds matching record IDs first, then you fetch those IDs. Search to find, then fetch is the heart of programmatic access.
Last in Track 1 - the payoff

Pandas for biologists + your Track 1 project →