Library Overview06/06
Starting sandbox…
Beginner

biocommons.hgvs

biocommons hgvs

Core Principle: The biocommons hgvs package 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. to g. 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:

[1]python
out1ms
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.5 and NM_000546.6 can have different coordinates. Never strip the version.
  • A variant is meaningless without its reference. c.215C>G alone is not a variant; NM_000546.6:c.215C>G is.
  • 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