biocommons.hgvs
biocommons hgvs
Core Principle: The biocommons
hgvspackage implements parsing, validation, normalization, and cross-coordinate projection of sequence variants adhering to formal Human Genome Variation Society standards.
Version at time of writing: 1.5.7 (Mar 2026) · Python ≥3.10 · pip install hgvs · pin as hgvs>=1.5,<1.6
Architectural Model
Four services, layered over two data sources.
flowchart TD
In["Variant String: NM_000546.6:c.215C>G"] --> Parser["HGVS Parser (PEG Grammar)"]
Parser --> SV["SequenceVariant Object"]
SV --> Norm["Normalizer (Canonical Form)"]
SV --> Val["Validator (Integrity Check)"]
SV --> Map["AssemblyMapper (g. ↔ c. ↔ p.)"]
SV --> Fmt["Formatter (HGVS String)"]
Norm --> DP["Data Provider Interface"]
Val --> DP
Map --> DP
DP --> UTA["UTA (Transcript Alignments)"]
DP --> SR["SeqRepo (Reference Sequences)"]
While variant syntax parsing operates offline using formal PEG grammar, semantic validation, normalization, and projection require external transcript alignments and reference sequence providers to verify reference alleles and coordinate boundaries.
Domain Challenges in Variant Representation
Variant strings look like they can be handled with regex and arithmetic. They cannot. The reasons:
- Ambiguity. In a run of identical bases, a deletion has several equally valid coordinate representations. Only one is canonical. VCF picks the leftmost; HGVS picks the 3'-most on the reference sequence's own strand. Two "different" variants can be the same event.
- Transcript geometry. Converting
c.tog.requires knowing every exon boundary, and whether the transcript is on the reverse strand, and whether the alignment has indels relative to the genome. - Non-linear coordinates.
c.numbering has no zero, uses negative numbers for 5'UTR,*for 3'UTR, and+/-offsets for intronic positions. - Clinical stakes. A misprojected variant in a diagnostic report is a patient-safety event.
Anyone writing re.match(r"c\.(\d+)([ACGT])>([ACGT])", s) is building a bug factory. Use this library.
Core Reference Modules
Understand the standard first HGVS Nomenclature · Coordinate Systems
The objects hgvs Parser · SequenceVariant
The data behind it UTA and Data Providers · SeqRepo · hgvs easy
The operations hgvs Normalizer · hgvs Validator · AssemblyMapper · Projection c to g to p
Survival guide hgvs Pitfalls
Applied Workflows
Applied - Variant Normalization Pipeline · Applied - Annotating a Variant Table
Installation and Quickstart
pip install "hgvs>=1.5,<1.6"
Rapid development can utilize the public Universal Transcript Archive (UTA) remote instance without local database configuration:
NC_000017.11:g.7676154G>C NP_000537.3:p.(Pro72Arg)
There is also an hgvs-shell command that drops you into a REPL with all of the above pre-imported.
For anything beyond exploration, run UTA and SeqRepo locally. The remote instance is a shared courtesy service; it is slow, rate-limited, and unsuitable for a pipeline over thousands of variants. See UTA and Data Providers and SeqRepo.
export UTA_DB_URL=postgresql://anonymous@localhost:5432/uta/uta_20210129
export HGVS_SEQREPO_DIR=/usr/local/share/seqrepo/2024-02-20
Essential API Patterns
import hgvs.parser, hgvs.dataproviders.uta, hgvs.assemblymapper
import hgvs.normalizer, hgvs.validator
hp = hgvs.parser.Parser()
hdp = hgvs.dataproviders.uta.connect()
am = hgvs.assemblymapper.AssemblyMapper(
hdp, assembly_name="GRCh38", alt_aln_method="splign", replace_reference=True
)
hn = hgvs.normalizer.Normalizer(hdp)
hv = hgvs.validator.Validator(hdp)
var_c = hp.parse_hgvs_variant("NM_000546.6:c.215C>G")
hv.validate(var_c) # raises HGVSError subclasses on failure
var_c = hn.normalize(var_c)
var_g = am.c_to_g(var_c)
var_p = am.c_to_p(var_c)
am.relevant_transcripts(var_g) # which transcripts overlap this genomic variant
Build hdp and am once and reuse them. Constructing them per variant re-opens the database connection and destroys performance.
Common Pitfalls & Behavioral Edge Cases
- Accession versions matter.
NM_000546.5andNM_000546.6can have different coordinates. Never strip the version. - A variant is meaningless without its reference.
c.215C>Galone is not a variant;NM_000546.6:c.215C>Gis. p.variants from projection are predictions, prefixed with()by convention. They are inference, not observation.- Normalization changes with data version. Pin your UTA and SeqRepo snapshots, not just the library. See Applied - Reproducible Environment.
- HGVS and VCF shift indels in opposite directions. Round-tripping without normalization loses variants. See hgvs Pitfalls.
Related tooling worth knowing
- bioutils: Biocommons helper library containing assembly coordinate maps and sequence utilities.
- vrs-python: GA4GH Variation Representation Specification reference implementation for computed, globally unique variant identifiers.
- VariantValidator (
openvar/vv_hgvs): Extended variant validation framework providing web service and API integrations. - Mutalyzer, Ensembl VEP: Alternative independent variant annotation engines useful for cross-validation.
See also
Biopython · Ecosystem Map · Coordinate Systems · Learning Path