pythonforbio.
[WASM idle]
HGVS Nomenclature11/11

hgvs easy

Starting sandbox…
Beginnerlesson

hgvs easy

In one line: a convenience module that pre-builds every object you need against the public remote data sources — ideal for learning, wrong for pipelines.

The fastest possible start

from hgvs.easy import *

var_c = parse("NM_000546.6:c.215C>G")
var_g = am38.c_to_g(var_c)
var_p = am38.c_to_p(var_c)

print(var_g)      # NC_000017.11:g.7676154G>C
print(var_p)      # NP_000537.3:p.(Pro72Arg)

Three lines from a string to genomic and protein coordinates, with no database setup. That is genuinely useful for learning and for one-off lookups.

What you get

from hgvs.easy import (
    parser, hdp, am37, am38, hn, hv,           # objects
    parse, normalize, validate, g_to_t, t_to_p, c_to_g, c_to_p,   # functions
)
Name What
parser a Parser instance
hdp a UTA data provider, connected to the public remote instance
am37 AssemblyMapper for GRCh37
am38 AssemblyMapper for GRCh38
hn a Normalizer
hv a Validator
parse, normalize, validate, g_to_t, t_to_p, ... module-level function wrappers

The shell

hgvs-shell

Drops you into an interactive Python session with from hgvs.easy import * already executed. Genuinely the fastest way to explore the library or check a single variant.

>>> var = parse("NM_000546.6:c.215C>G")
>>> am38.relevant_transcripts(am38.c_to_g(var))
>>> normalize(var)
>>> validate(var)

Common one-liners

from hgvs.easy import *

# projections
var_c = parse("NM_000546.6:c.215C>G")
var_g = am38.c_to_g(var_c)
var_p = am38.c_to_p(var_c)

# the other direction
var_g = parse("NC_000017.11:g.7676154G>C")
am38.relevant_transcripts(var_g)          # which transcripts overlap?
var_c = am38.g_to_c(var_g, "NM_000546.6")

# GRCh37 vs GRCh38 — the same locus has different coordinates
am37.c_to_g(var_c)      # NC_000017.10:g.7579472G>C
am38.c_to_g(var_c)      # NC_000017.11:g.7676154G>C

# normalize and validate
normalize(var_c)
validate(var_c)

That GRCh37/GRCh38 pair is worth running once yourself. The same variant, two assemblies, ~97,000 bp apart in coordinates. It makes concrete why a genomic position without an assembly is meaningless.

Configuration

export UTA_DB_URL=postgresql://anonymous@localhost:5432/uta/uta_20210129
export HGVS_SEQREPO_DIR=/usr/local/share/seqrepo/2024-02-20

hgvs.easy honours these, so you can point it at local data sources and keep the convenient API. That combination — easy's brevity with local data — is a reasonable setup for interactive work.

When not to use it

hgvs.easy connects to the public remote UTA at import time. That has consequences:

  • Importing is slow — it opens a network database connection.
  • Every operation is a network round-trip unless you have set the environment variables.
  • The remote service is rate-limited and shared. Batch work through it is slow for you and antisocial to everyone else.
  • from hgvs.easy import * dumps a dozen names into your namespace, including parse and validate, which collide with common names.
  • The data version is whatever the remote happens to be, so results are not reproducible.

The explicit form for pipelines

import hgvs.parser
import hgvs.dataproviders.uta
import hgvs.assemblymapper
import hgvs.normalizer
import hgvs.validator

hp  = hgvs.parser.Parser()
hdp = hgvs.dataproviders.uta.connect(pooling=True)
am  = hgvs.assemblymapper.AssemblyMapper(
    hdp,
    assembly_name="GRCh38",
    alt_aln_method="splign",
    replace_reference=True,
    normalize=True,
)
hn = hgvs.normalizer.Normalizer(hdp)
hv = hgvs.validator.Validator(hdp)

print(f"UTA: {hdp.data_version()}")        # ← record this

More lines, but you get: explicit configuration, a recorded data version, connection pooling, no namespace pollution, and control over alt_aln_method and replace_reference.

Build these objects once, at module level or in a factory, and pass them down. Constructing AssemblyMapper per variant is the most common performance mistake in hgvs code.

from functools import lru_cache

@lru_cache(maxsize=1)
def get_tools(assembly="GRCh38"):
    hdp = hgvs.dataproviders.uta.connect(pooling=True)
    return (hgvs.parser.Parser(),
            hgvs.assemblymapper.AssemblyMapper(hdp, assembly_name=assembly,
                                               alt_aln_method="splign",
                                               replace_reference=True),
            hgvs.normalizer.Normalizer(hdp),
            hgvs.validator.Validator(hdp))

The progression

  1. Learning: hgvs-shell and hgvs.easy. No setup, immediate feedback.
  2. Prototyping: hgvs.easy with UTA_DB_URL and HGVS_SEQREPO_DIR pointed at local data.
  3. Production: explicit construction, local data, recorded versions, cached objects, structured error handling.

Do not skip step 1. Understanding what the library does is easier when setup is not in the way.

Common mistakes

  • Using hgvs.easy in a pipeline against the remote instance.
  • from hgvs.easy import * shadowing parse, validate, normalize.
  • Not recording the data version.
  • Reconstructing tools per variant.
  • Assuming am38 means your data is GRCh38 — it means the mapper targets GRCh38. If your input coordinates are GRCh37, you need am37 or a liftover.
  • Forgetting hgvs.easy respects the env vars and setting up local data but never using it.

See also

biocommons hgvs · AssemblyMapper · UTA and Data Providers · SeqRepo · hgvs Parser · Applied - Variant Normalization Pipeline

lesson example

No output yet — run the code to populate this drawer.

hgvs Validatorend of path