Turn raw genomic variants — VCF rows, rsIDs, or HGVS strings — into annotated,
consequence-predicted records, and link them to the clinical context OpenMed
extracts from text (genes, variants, oncology findings, phenotype). The workhorse
for a quick, no-install annotation is the Ensembl VEP REST API; for scale,
run VEP, SnpEff, or ANNOVAR offline.
These annotators are free and license-permissive. Restricted clinical
interpretation databases (e.g. licensed HGMD) are user-supplied — this skill
sticks to open resources (Ensembl, gnomAD, ClinVar).
stop-gain, splice), affected transcripts, and protein change.
build (GRCh38 by default; GRCh37 via the dedicated endpoint).
OpenMed pulls from notes or literature.
Base URL: https://rest.ensembl.org (GRCh38). For GRCh37 usehttps://grch37.rest.ensembl.org. Default species is human/homo_sapiens.
import requests
REST = "https://rest.ensembl.org"
HEADERS = {"Content-Type": "application/json", "Accept": "application/json"}
def vep_hgvs(hgvs: str) -> list[dict]:
"""Annotate a single HGVS variant (GET)."""
r = requests.get(f"{REST}/vep/human/hgvs/{hgvs}", headers=HEADERS, timeout=30)
r.raise_for_status()
return r.json()
# Transcript-level HGVS (coding) — note the build-aware default transcript set
ann = vep_hgvs("ENST00000269305.9:c.215C>G") # TP53 example
v = ann[0]
print(v["most_severe_consequence"]) # e.g. "missense_variant"
for tc in v.get("transcript_consequences", []):
print(tc["gene_symbol"], tc.get("hgvsp"), tc.get("sift_prediction"),
tc.get("polyphen_prediction"))
Batch many variants with the POST endpoint (region "CHROM POS ID REF ALT . . ."
format, up to 200 per request):
def vep_region_batch(variants: list[str]) -> list[dict]:
body = {"variants": variants} # ["17 7676154 . C G . . .", ...] 1-based
r = requests.post(f"{REST}/vep/human/region", headers=HEADERS,
json=body, timeout=60)
r.raise_for_status()
return r.json()
Equivalent cURL:
curl 'https://rest.ensembl.org/vep/human/hgvs/ENST00000269305.9:c.215C>G' \
-H 'Content-Type:application/json'
Response highlights per variant: most_severe_consequence,transcript_consequences[] (gene_symbol, hgvsc, hgvsp, sift_prediction,polyphen_prediction, impact), and colocated_variants[] (rsIDs and
population frequencies). Request gnomAD frequencies and ClinVar via VEP options /
plugins.
For authoritative allele frequencies, query the gnomAD GraphQL API athttps://gnomad.broadinstitute.org/api. Use variant IDs inchrom-pos-ref-alt form. Frequencies are derived from ac/an (allele count /
number) — request those, not a non-existent af on subpopulations.
GNOMAD = "https://gnomad.broadinstitute.org/api"
QUERY = """
query Variant($id: String!, $ds: DatasetId!) {
variant(variantId: $id, dataset: $ds) {
variant_id rsids
genome { ac an af homozygote_count }
exome { ac an af homozygote_count }
}
}"""
def gnomad_freq(variant_id: str, dataset: str = "gnomad_r4") -> dict:
r = requests.post(GNOMAD, json={"query": QUERY,
"variables": {"id": variant_id, "ds": dataset}}, timeout=30)
r.raise_for_status()
return r.json()["data"]["variant"]
# gnomad_freq("17-7676154-C-G") -> ac/an/af for exome and genome
For whole-VCF jobs, run a local annotator instead of per-variant REST calls:
| Tool | Strengths | Notes |
|---|---|---|
| Ensembl VEP (offline) | richest, plugin ecosystem (gnomAD, CADD, SpliceAI), HGVS | needs cache download per build |
| SnpEff | fast, self-contained genome databases | great for bulk consequence calling |
| ANNOVAR | many annotation databases | registration required; license terms apply |
All emit per-variant gene, consequence, and (with the right database) frequency
and clinical fields. Keep the reference build (GRCh38) consistent end to end.
confirm the reference transcript and build.
/vep/human/hgvs or /vep/human/region) for a handful,offline VEP/SnpEff for a VCF.
most_severe_consequence, impact, and rarity.phenotype) to assemble an interpretable record.
Genomics or Oncology model>)` extracts gene symbols, variant mentions (e.g.
"EGFR L858R"), and tumor/oncology findings from pathology or molecular reports.
Use those to (a) select which VCF variants matter and (b) attach phenotype
context to each annotation.
normalized to HGVS here, then the surrounding clinical narrative is structured by
OpenMed — linking genotype to extracted phenotype/diagnosis.
variant coordinates (public allele data), never patient identifiers — and
any narrative is de-identified with openmed.deidentify first.
(or cache) give wrong genes. Use grch37.rest.ensembl.org only for GRCh37 data;
default REST is GRCh38.
c./p. notation depends on thereference transcript (MANE Select vs others). Pin the transcript explicitly.
rows produce inconsistent annotations — decompose and normalize first
(e.g. bcftools norm).
server; switch to offline VEP for large VCFs. Honor Retry-After on 429.
ac/an (and compute AF) forsubpopulations; some schema paths reject af directly — track the current
schema version, which changes between gnomAD releases.
classification (ACMG/AMP) uses curated evidence and licensed databases the user
supplies; this skill produces annotations, not diagnoses.