| name | bio-core-biological-databases |
| description | Fetch sequences via NCBI Entrez (esearch/efetch/elink), UniProt REST, and RCSB PDB APIs with BioPython/urllib. Use when picking a database, decoding accession prefixes (NM_/XM_/GSE/SRR), or cross-linking a gene NCBI-UniProt-PDB. |
| tool_type | python |
| primary_tool | biopython |
Biological Databases
When to Use
- Deciding which database (NCBI, UniProt, PDB, Ensembl, GEO, SRA) holds the data you actually need
- Writing
Bio.Entrez esearch/efetch/elink code to pull sequences, GenBank annotations, or PubMed abstracts
- Resolving accession types (
NM_/NP_/XM_/GSE/SRR) and curated-vs-predicted status
- Fetching protein records from UniProt or 3D structures from PDB by accession/ID
- Chaining a lookup across databases: gene name -> RefSeq mRNA -> protein -> structure -> orthologs
Version Compatibility
- biopython >= 1.81, Python >= 3.10
- UniProt REST API (
rest.uniprot.org), current JSON schema (2024+)
- RCSB PDB Search API v2 and Data API v1 (
search.rcsb.org, data.rcsb.org)
- Ensembl REST API (
rest.ensembl.org), Ensembl release 110+
Prerequisites
pip install biopython
- stdlib only otherwise:
urllib.request, json, urllib.parse
- Set
Entrez.email (required by NCBI); get a free NCBI API key to raise rate limits
- Helpful follow-on skills:
bio-sequence-manipulation-seq-objects, bio-structural-biology-structure-io
Database Selector
| Need | Database | Preferred subset |
|---|
| Gene info + orthologs | NCBI Gene / Ensembl | Ensembl Compara for orthologs |
| mRNA/protein sequence | NCBI Nucleotide / Protein | RefSeq (NM_, NP_, NC_) |
| Protein function/structure refs | UniProt | SwissProt (reviewed:true) |
| 3D structure | PDB (RCSB) | check resolution + method |
| Raw sequencing reads | SRA | SRR accession |
| Processed expression data | GEO | GSE (series), GSM (sample) |
| Literature | PubMed | — |
NCBI Accession Prefixes
| Prefix | Type | Curated? |
|---|
NM_ | curated mRNA | Yes (RefSeq) |
NP_ | curated protein | Yes (RefSeq) |
NC_ | chromosome/complete genome | Yes (RefSeq) |
XM_/XP_ | predicted/model mRNA/protein | No |
NR_ | non-coding RNA | Yes (RefSeq) |
GEO accessions: GSE (series/experiment), GSM (sample), GPL (platform), GDS (curated dataset).
SRA hierarchy: Study (SRP) > Sample (SRS) > Experiment (SRX) > Run (SRR).
Goal: search, fetch, and cross-link NCBI records without exhausting rate limits.
Approach: use Entrez.esearch/efetch/elink; always batch IDs and close handles.
from Bio import Entrez, SeqIO
Entrez.email = "your.email@example.com"
def fetch_refseq_mrna(gene, organism="Homo sapiens"):
"""Find and fetch the top RefSeq mRNA GenBank record for a gene symbol."""
handle = Entrez.esearch(
db="nucleotide",
term=f"{gene}[Gene] AND {organism}[Organism] AND RefSeq[Filter] AND mRNA[Filter]",
retmax=1,
)
ids = Entrez.read(handle)["IdList"]
handle.close()
if not ids:
return None
handle = Entrez.efetch(db="nucleotide", id=ids[0], rettype="gb", retmode="text")
record = SeqIO.read(handle, "genbank")
handle.close()
return record
record = fetch_refseq_mrna("insulin")
for feat in record.features:
if feat.type == "CDS":
cds_seq = feat.location.extract(record.seq)
protein = cds_seq.translate(to_stop=True)
annotated = feat.qualifiers.get("translation", [""])[0]
handle = Entrez.elink(dbfrom="nucleotide", db="protein", =)
link_results = Entrez.read(handle)
handle.close()
handle = Entrez.efetch(db=, =,
rettype=, retmode=)
Entrez search syntax: insulin[Gene], Homo sapiens[Organism], mRNA[Filter] AND RefSeq[Filter],
2020:2024[PDAT] (date range), CRISPR AND (cancer OR tumor).
Goal: pull a protein record and its structural cross-references from UniProt.
Approach: hit the REST API directly with urllib — no extra dependency needed.
import json
import urllib.parse
import urllib.request
def fetch_uniprot(accession, fmt="json"):
"""Fetch one UniProt entry by accession (e.g. 'P01308' = human insulin)."""
url = f"https://rest.uniprot.org/uniprotkb/{accession}.{fmt}"
with urllib.request.urlopen(url) as r:
return json.loads(r.read()) if fmt == "json" else r.read().decode()
def search_uniprot(query, limit=5):
"""Search UniProt; e.g. query='hemoglobin AND organism_id:9606 AND reviewed:true'."""
encoded = urllib.parse.quote(query)
url = f"https://rest.uniprot.org/uniprotkb/search?query={encoded}&size={limit}&format=json"
with urllib.request.urlopen(url) as r:
return json.loads(r.read())
insulin = fetch_uniprot("P01308")
name = insulin["proteinDescription"]["recommendedName"]["fullName"]["value"]
seq = insulin["sequence"]["value"]
pdb_refs = [r for r in insulin.get("uniProtKBCrossReferences", []) if r["database"] == "PDB"]
Goal: fetch and parse a 3D structure once you have a PDB ID (e.g. from the UniProt cross-refs above).
Approach: RCSB search API for discovery, files.rcsb.org for the actual coordinate file.
def download_pdb(pdb_id, fmt="pdb"):
"""Download a structure file from RCSB PDB ('pdb' or 'cif' format)."""
ext = "pdb" if fmt == "pdb" else "cif"
url = f"https://files.rcsb.org/download/{pdb_id}.{ext}"
filename = f"{pdb_id}.{ext}"
urllib.request.urlretrieve(url, filename)
return filename
path = download_pdb("4INS")
Pitfalls
- GenBank vs RefSeq: GenBank has all submitted sequences (redundant, unreviewed); RefSeq is curated. Prefer RefSeq (
NM_/NP_) for analysis
- SwissProt vs TrEMBL: SwissProt (~570K entries, manually curated) vs TrEMBL (~250M, auto-annotated); filter with
reviewed:true for reliable annotations
- Rate limits: NCBI allows 3 req/s without an API key, 10/s with one (
Entrez.api_key = "..."); batch with comma-separated IDs, never loop individual efetch calls
- GI numbers deprecated: use accession.version (
NM_000207.3), not numeric GI IDs
efetch handle must be closed: always handle.close() (or use with) — unclosed handles exhaust NCBI connections
id as a list breaks efetch: pass a comma-separated string, not a Python list — a common LLM-generated bug
- PDB resolution matters: structures worse than ~3.5 Å only give reliable overall fold, not side-chain/atomic detail
See Also
bio-database-access-entrez-search, bio-database-access-entrez-fetch, bio-database-access-entrez-link
bio-database-access-uniprot-access
bio-structural-biology-structure-io
bio-database-access-geo-data, bio-database-access-sra-data