Query EBI QuickGO REST API for GO terms and protein annotations. Fetch term metadata by ID, search by keyword, walk ancestor/descendant hierarchies, download annotations filtered by taxon, evidence code, aspect. Use for GO resolution, ontology traversal, annotation retrieval before enrichment. Use gseapy-gene-enrichment for enrichment; uniprot-protein-database for proteins.
Instalar com Codex ou Claude Copie este prompt, cole no Codex, Claude ou outro assistente e deixe que ele revise a página da skill e instale para você.
Um comando direto ignora o prompt de revisão. Verifique a origem antes de executá-lo.
Instruções da origem · Visualização somente leitura
name
quickgo-database
description
Query EBI QuickGO REST API for GO terms and protein annotations. Fetch term metadata by ID, search by keyword, walk ancestor/descendant hierarchies, download annotations filtered by taxon, evidence code, aspect. Use for GO resolution, ontology traversal, annotation retrieval before enrichment. Use gseapy-gene-enrichment for enrichment; uniprot-protein-database for proteins.
license
Apache-2.0
QuickGO Database
Overview
QuickGO is the EBI's Gene Ontology annotation browser and REST API. It provides programmatic access to the GO ontology (terms, synonyms, hierarchies) and to the manually curated and electronic GO annotations for proteins across all species. The API is free, requires no authentication, and returns JSON responses. All endpoints live under https://www.ebi.ac.uk/QuickGO/services/.
When to Use
Resolving a GO term ID (e.g., GO:0006915) to its name, definition, and aspect (biological_process, molecular_function, cellular_component)
Retrieving all GO annotations for a UniProt protein, filtered by evidence code and taxon
Searching GO terms by keyword (e.g., "apoptosis") to find relevant term IDs before enrichment analysis
Walking the GO DAG upward (ancestors) or downward (descendants) from a specific term
Getting annotation counts stratified by evidence code or GO aspect for a set of proteins
Resolving multiple GO IDs in one batch request to avoid looping over individual term lookups
For enrichment analysis (ORA/GSEA) on a gene list use gseapy-gene-enrichment; QuickGO provides the raw annotation data
For comprehensive protein function annotations in Swiss-Prot format use uniprot-protein-database
Prerequisites
Python packages: requests, pandas, matplotlib
Data requirements: GO term IDs (GO:XXXXXXX) or UniProt accessions; taxon IDs (e.g., 9606 for human)
Environment: internet connection; no API key required
Rate limits: no published hard limit; use time.sleep(1.0) between requests in batch loops for polite access
pip install requests pandas matplotlib
Quick Start
import requests
import time
QUICKGO_BASE = "https://www.ebi.ac.uk/QuickGO/services"defquickgo_get(endpoint: str, params: dict = None) -> dict:
"""Send a GET request to a QuickGO endpoint and return parsed JSON."""
url = f"{QUICKGO_BASE}/{endpoint}"
headers = {"Accept": "application/json"}
r = requests.get(url, params=params, headers=headers, timeout=30)
r.raise_for_status()
return r.json()
# Fetch metadata for the apoptotic process GO term
result = quickgo_get("ontology/go/terms/GO:0006915")
term = result["results"][0]
print(f"ID : {term['id']}")
print(f"Name : {term['name']}")
print(f"Aspect : {term['aspect']}")
print(f"Def : {term['definition']['text'][:100]}...")
# ID : GO:0006915# Name : apoptotic process# Aspect : biological_process# Def : A programmed cell death process which begins when a cell receives ...
Core API
Query 1: GO Term Lookup
Fetch term metadata — name, definition, aspect, synonyms, and is-obsolete status — for one or more GO IDs.
import requests
QUICKGO_BASE = "https://www.ebi.ac.uk/QuickGO/services"defget_go_term(go_id: str) -> dict:
"""Retrieve metadata for a single GO term by ID."""
headers = {"Accept": "application/json"}
r = requests.get(
f"{QUICKGO_BASE}/ontology/go/terms/{go_id}",
headers=headers, timeout=30
)
r.raise_for_status()
results = r.json().get("results", [])
return results[0] if results else {}
term = get_go_term("GO:0005515")
print(f"Name : {term['name']}")
print(f"Aspect : {term['aspect']}")
print(f"Obsolete: {term.get('isObsolete', False)}")
print(f"Synonyms: {[s['name'] for s in term.get('synonyms', [])[:3]]}")
# Name : protein binding# Aspect : molecular_function# Obsolete: False# Synonyms: ['protein-protein interaction', 'protein binding activity']
# Batch lookup: resolve multiple GO IDs in one request
go_ids = ["GO:0006915", "GO:0005515", "GO:0016020"]
ids_param = ",".join(go_ids)
r = requests.get(
f"{QUICKGO_BASE}/ontology/go/terms/{ids_param}",
headers={"Accept": "application/json"}, timeout=30
)
r.raise_for_status()
for t in r.json().get("results", []):
print(f"{t['id']}{t['aspect']:<25}{t['name']}")
# GO:0006915 biological_process apoptotic process# GO:0005515 molecular_function protein binding# GO:0016020 cellular_component membrane
Query 2: Annotation Search
Retrieve GO annotations for a protein or a set of proteins. Filter by evidence code and taxon.
import requests
QUICKGO_BASE = "https://www.ebi.ac.uk/QuickGO/services"defget_protein_annotations(uniprot_id: str, evidence_codes: list = None,
limit: int = 100) -> list:
"""Fetch GO annotations for a UniProt protein."""
params = {
"geneProductId": f"UniProtKB:{uniprot_id}",
"limit": limit,
"page": 1,
}
if evidence_codes:
params["evidenceCode"] = ",".join(evidence_codes)
headers = {"Accept": "application/json"}
r = requests.get(
f"{QUICKGO_BASE}/annotation/search",
params=params, headers=headers, timeout=30
)
r.raise_for_status()
return r.json().get("results", [])
# Fetch experimental annotations for TP53 (P04637)
annotations = get_protein_annotations(
"P04637",
evidence_codes=["EXP", "IDA", "IPI", "IMP", "IGI", "IEP"]
)
print(f"Experimental annotations for TP53: {len(annotations)}")
for ann in annotations[:4]:
print(f" {ann['goId']}{ann['goName']:<40}{ann['evidenceCode']}")
# Experimental annotations for TP53: 87# GO:0006977 DNA damage response, ... IDA# GO:0043065 positive regulation of apoptosis IMP
# Annotations for a taxon (human, 9606) + specific GO term
params = {
"goId": "GO:0006915",
"taxonId": "9606",
"evidenceCode": "EXP,IDA,IPI,IMP,IGI,IEP",
"limit": 100,
"page": 1,
}
r = requests.get(
f"{QUICKGO_BASE}/annotation/search",
params=params,
headers={"Accept": "application/json"},
timeout=30
)
r.raise_for_status()
data = r.json()
print(f"Total annotations: {data.get('numberOfHits', 'N/A')}")
print(f"Retrieved : {len(data.get('results', []))}")
for ann in data["results"][:3]:
print(f" {ann['geneProductId']}{ann['goId']}{ann['evidenceCode']}")
Query 3: Term Hierarchy
Get ancestors (terms more general than the query term) or descendants (more specific terms) by traversing the GO DAG.
import requests
QUICKGO_BASE = "https://www.ebi.ac.uk/QuickGO/services"defget_ancestors(go_id: str, relations: str = "is_a,part_of") -> list:
"""Return ancestor GO IDs for a term via the ontology hierarchy."""
r = requests.get(
f"{QUICKGO_BASE}/ontology/go/terms/{go_id}/ancestors",
params={"relations": relations},
headers={"Accept": "application/json"},
timeout=30
)
r.raise_for_status()
results = r.json().get("results", [])
return results[0].get("ancestors", []) if results else []
defget_descendants(go_id: str, relations: str = "is_a,part_of") -> list:
"""Return descendant GO IDs for a term via the ontology hierarchy."""
r = requests.get(
f"{QUICKGO_BASE}/ontology/go/terms/{go_id}/descendants",
params={"relations": relations},
headers={"Accept": "application/json"},
timeout=30
)
r.raise_for_status()
results = r.json().get("results", [])
return results[0].get("descendants", []) if results else []
ancestors = get_ancestors("GO:0006915")
descendants = get_descendants("GO:0006915")
print(f"Ancestors of GO:0006915 (apoptotic process): {len(ancestors)}")
print(f"Descendants of GO:0006915 : {len(descendants)}")
print(f"First 5 ancestors : {ancestors[:5]}")
# Ancestors of GO:0006915 (apoptotic process): 6# Descendants of GO:0006915 : 53# First 5 ancestors : ['GO:0008219', 'GO:0009987', ...]
Query 4: Ontology Search
Text-search for GO terms by keyword. Useful for discovering relevant GO IDs before building annotation queries.
import requests
QUICKGO_BASE = "https://www.ebi.ac.uk/QuickGO/services"defsearch_go_terms(query: str, limit: int = 20) -> list:
"""Search GO terms by keyword; returns list of term dicts."""
r = requests.get(
f"{QUICKGO_BASE}/ontology/go/search",
params={"query": query, "limit": limit, "page": 1},
headers={"Accept": "application/json"},
timeout=30
)
r.raise_for_status()
return r.json().get("results", [])
hits = search_go_terms("autophagy")
print(f"GO terms matching 'autophagy': {len(hits)}")
for h in hits[:5]:
print(f" {h['id']}{h['aspect']:<25}{h['name']}")
# GO terms matching 'autophagy': 20# GO:0006914 biological_process autophagy# GO:0016236 biological_process macroautophagy# GO:0061709 biological_process reticulophagy
Query 5: Annotation Statistics
Get counts of annotations grouped by evidence code, GO aspect, or taxon for a gene product or GO term.
import requests
QUICKGO_BASE = "https://www.ebi.ac.uk/QuickGO/services"defget_annotation_stats(uniprot_id: str) -> dict:
"""Retrieve annotation counts by evidence type and GO aspect."""
params = {
"geneProductId": f"UniProtKB:{uniprot_id}",
"limit": 200,
"page": 1,
}
r = requests.get(
f"{QUICKGO_BASE}/annotation/search",
params=params,
headers={"Accept": "application/json"},
timeout=30
)
r.raise_for_status()
results = r.json().get("results", [])
by_evidence = {}
by_aspect = {}
for ann in results:
ec = ann.get("evidenceCode", "unknown")
asp = ann.get("goAspect", "unknown")
by_evidence[ec] = by_evidence.get(ec, 0) + 1
by_aspect[asp] = by_aspect.get(asp, 0) + 1return {"by_evidence": by_evidence, "by_aspect": by_aspect,
"total": len(results)}
stats = get_annotation_stats("P04637") # TP53print(f"Total annotations (first page): {stats['total']}")
print("\nBy evidence code:")
for ec, n insorted(stats["by_evidence"].items(), key=lambda x: -x[1]):
print(f" {ec:<5} : {n}")
print("\nBy GO aspect:")
for asp, n in stats["by_aspect"].items():
print(f" {asp}: {n}")
Query 6: Batch GO Term Query
Resolve a list of GO IDs to their names and aspects in a single API call (up to ~200 IDs per request).
import requests
QUICKGO_BASE = "https://www.ebi.ac.uk/QuickGO/services"defbatch_resolve_go_terms(go_ids: list) -> dict:
"""Resolve a list of GO IDs → {id: {name, aspect, definition}} in one call."""
ids_param = ",".join(go_ids)
r = requests.get(
f"{QUICKGO_BASE}/ontology/go/terms/{ids_param}",
headers={"Accept": "application/json"},
timeout=60
)
r.raise_for_status()
return {
t["id"]: {
"name": t["name"],
"aspect": t["aspect"],
"definition": t.get("definition", {}).get("text", ""),
"obsolete": t.get("isObsolete", False),
}
for t in r.json().get("results", [])
}
go_ids = ["GO:0006915", "GO:0005515", "GO:0016020", "GO:0006281", "GO:0051301"]
resolved = batch_resolve_go_terms(go_ids)
print(f"Resolved {len(resolved)}/{len(go_ids)} GO IDs")
for gid, info in resolved.items():
print(f" {gid} [{info['aspect'][:2].upper()}] {info['name']}")
# Resolved 5/5 GO IDs# GO:0006915 [BI] apoptotic process# GO:0005515 [MO] protein binding# GO:0016020 [CE] membrane
Key Concepts
GO Ontology Structure
The Gene Ontology is a directed acyclic graph (DAG) organized into three independent root aspects:
Aspect code
Aspect name
Root term
biological_process
Biological process (BP)
GO:0008150
molecular_function
Molecular function (MF)
GO:0003674
cellular_component
Cellular component (CC)
GO:0005575
Terms are connected by two primary relation types: is_a (subclass) and part_of (mereological). When filtering annotation enrichment results, always check the aspect field to avoid mixing BP, MF, and CC terms.
Evidence Code Categories
The evidence code determines annotation reliability. Filter to experimental codes for high-confidence annotations; exclude IEA in clinical or mechanistic analyses.
Category
Codes
Meaning
Experimental
EXP, IDA, IPI, IMP, IGI, IEP
Direct biochemical or genetic experiments
Computational/similarity
ISS, ISO, ISA, IBA, RCA
Inferred by sequence or phylogenetic similarity
Author statement
TAS, IC
Curator or author assertion without experiment
Electronic
IEA
Automated; no human review — lowest confidence
High throughput
HTP, HDA, HMP, HGI, HEP
High-throughput experimental methods
Pagination
QuickGO annotation searches return paginated results. The numberOfHits field in the response gives the total count. Use the page parameter to iterate through all results when numberOfHits > limit.
import requests, time
defget_all_annotations(go_id: str, taxon_id: str = "9606",
evidence_codes: str = "EXP,IDA,IPI,IMP",
page_size: int = 100) -> list:
"""Retrieve all annotation pages for a GO term + taxon combination."""
QUICKGO_BASE = "https://www.ebi.ac.uk/QuickGO/services"
all_results = []
page = 1whileTrue:
params = {"goId": go_id, "taxonId": taxon_id,
"evidenceCode": evidence_codes, "limit": page_size,
"page": page}
r = requests.get(f"{QUICKGO_BASE}/annotation/search",
params=params, headers={"Accept": "application/json"},
timeout=30)
r.raise_for_status()
data = r.json()
results = data.get("results", [])
all_results.extend(results)
total = data.get("numberOfHits", 0)
iflen(all_results) >= total ornot results:
break
page += 1
time.sleep(1.0) # polite delayreturn all_results
Common Workflows
Workflow 1: GO Annotation Profile for a Protein
Goal: Retrieve all GO annotations for a protein, split by aspect and evidence category, and visualize the evidence code distribution.
Keyword search across GO term names and definitions
Best Practices
Use batch_resolve_go_terms instead of per-ID loops: The terms endpoint accepts a comma-separated list of IDs and resolves all in one round trip. For lists of up to 200 IDs this is 100× faster than one request per term.
Exclude IEA for mechanistic conclusions: Electronic annotations (IEA) are assigned by automated pipelines without manual review. They can inflate annotation counts and introduce false positives. Set evidenceCode=EXP,IDA,IPI,IMP,IGI,IEP,TAS for curated-only results.
Add time.sleep(1.0) in batch loops: QuickGO is shared EBI infrastructure with no published hard limit. One request per second keeps your scripts well within fair-use bounds.
Use descendants for ontology-aware queries: Searching only the exact goId misses proteins annotated to more specific child terms. Retrieve descendants first, then query each or combine into an evidenceCode-filtered batch.
Check numberOfHits before assuming completeness: The default limit=25 often returns a fraction of total annotations. Always inspect numberOfHits and paginate when numberOfHits > limit.
Common Recipes
Recipe: Resolve GO IDs from an Enrichment Result
When to use: Convert a list of GO IDs returned by gseapy or another enrichment tool to human-readable names.
import requests
QUICKGO_BASE = "https://www.ebi.ac.uk/QuickGO/services"defresolve_go_names(go_ids: list) -> dict:
"""Return {go_id: name} for a list of GO IDs (single batch call)."""
ids_str = ",".join(go_ids)
r = requests.get(
f"{QUICKGO_BASE}/ontology/go/terms/{ids_str}",
headers={"Accept": "application/json"}, timeout=60
)
r.raise_for_status()
return {t["id"]: t["name"] for t in r.json().get("results", [])}
# Example: map enrichment result GO IDs
enriched_ids = ["GO:0006915", "GO:0043066", "GO:0097553", "GO:0008219", "GO:0006281"]
names = resolve_go_names(enriched_ids)
for gid, name in names.items():
print(f"{gid}{name}")
# GO:0006915 apoptotic process# GO:0043066 negative regulation of apoptotic process
Recipe: Get All Experimental Annotations for a Human Protein
When to use: Pull curated evidence for a protein before manually reviewing its GO function landscape.
import requests, time
QUICKGO_BASE = "https://www.ebi.ac.uk/QuickGO/services"
EXP_CODES = "EXP,IDA,IPI,IMP,IGI,IEP"defget_experimental_annotations(uniprot_id: str) -> list:
results, page = [], 1whileTrue:
r = requests.get(
f"{QUICKGO_BASE}/annotation/search",
params={"geneProductId": f"UniProtKB:{uniprot_id}",
"evidenceCode": EXP_CODES,
"limit": 200, "page": page},
headers={"Accept": "application/json"}, timeout=30
)
r.raise_for_status()
data = r.json()
batch = data.get("results", [])
results.extend(batch)
ifnot batch orlen(results) >= data.get("numberOfHits", 0):
break
page += 1
time.sleep(1.0)
return results
anns = get_experimental_annotations("P04637") # TP53print(f"Experimental GO annotations for TP53: {len(anns)}")
for a in anns[:5]:
print(f" {a['goId']}{a.get('goName', '')[:40]} ({a['evidenceCode']})")
Recipe: Check if a GO Term Is Experimental or Inferred
When to use: Quickly decide whether an annotation is trustworthy before including it in a pathway model.
import requests
QUICKGO_BASE = "https://www.ebi.ac.uk/QuickGO/services"
EXPERIMENTAL = {"EXP", "IDA", "IPI", "IMP", "IGI", "IEP",
"HTP", "HDA", "HMP", "HGI", "HEP"}
defannotation_is_experimental(uniprot_id: str, go_id: str) -> bool:
"""Return True if any experimental annotation exists for protein + GO term."""
r = requests.get(
f"{QUICKGO_BASE}/annotation/search",
params={"geneProductId": f"UniProtKB:{uniprot_id}",
"goId": go_id, "limit": 10, "page": 1},
headers={"Accept": "application/json"}, timeout=30
)
r.raise_for_status()
returnany(a["evidenceCode"] in EXPERIMENTAL
for a in r.json().get("results", []))
print(annotation_is_experimental("P04637", "GO:0006977")) # Trueprint(annotation_is_experimental("P04637", "GO:0016020")) # False (membrane — IEA only)
Troubleshooting
Problem
Cause
Solution
HTTP 400 on term lookup
Malformed GO ID (spaces, wrong prefix)
Ensure format is GO:XXXXXXX (7 digits, colon, uppercase GO)
results: [] for a known GO ID
Term is obsolete or merged into another
Check isObsolete field; look up the replacement in consider or replacedBy
Annotation search returns 0 hits for a protein
UniProt accession format wrong
Prefix with UniProtKB: (case-sensitive), e.g., UniProtKB:P04637
numberOfHits >> len(results)
Default limit=25 is too small
Set limit=200 and implement pagination with page parameter
Batch term resolve returns fewer than expected
Some IDs are obsolete or malformed
Check returned id set against input; missing IDs are invalid or obsolete
Rate limit / 503 Service Unavailable
Too many rapid requests
Add time.sleep(1.0) between paged calls; backoff on 5xx errors
Descendant list is very large (1000+)
Broad root term selected
Use a more specific child term, or process descendants in chunks of 100
Related Skills
gseapy-gene-enrichment — ORA and GSEA enrichment analysis against GO and other gene set databases; use QuickGO to resolve term IDs from gseapy output
uniprot-protein-database — UniProt REST API for Swiss-Prot GO annotations integrated with protein sequence and feature data
ensembl-database — Ensembl REST API for variant-level GO annotations and cross-species gene lookups
kegg-database — KEGG pathways as an alternative functional annotation vocabulary