diff --git a/.gitignore b/.gitignore index 5f1c1695..dd645d63 100644 --- a/.gitignore +++ b/.gitignore @@ -158,3 +158,6 @@ notebooks/scratch/ notes lint uta_*.pgd.gz + +# partial hgvs cache from an interrupted `make record-hgvs-cache` +tests/data/hgvs_cache.pkl.new diff --git a/Makefile b/Makefile index fcf3502b..a751e490 100644 --- a/Makefile +++ b/Makefile @@ -128,6 +128,14 @@ cleanest: cleaner clean-cassettes: find ./tests -type f -path '*/cassettes/*.yaml' -print0 | ${XRM} +#=> record-hgvs-cache: re-record tests/data/hgvs_cache.json (needs UTA_DB_URL and a running seqrepo-rest-service at SEQREPO_REST_URL; VCR cassettes are not touched) +.PHONY: record-hgvs-cache +record-hgvs-cache: + rm -f tests/data/hgvs_cache.pkl.new + HGVS_SEQREPO_URL="$${SEQREPO_REST_URL:-http://localhost:5000/seqrepo}" VRS_HGVS_CACHE_MODE=learn VRS_HGVS_CACHE_FILE=$(CURDIR)/tests/data/hgvs_cache.pkl.new pytest --disable-vcr + python tests/hgvs_cache_json.py tests/data/hgvs_cache.pkl.new tests/data/hgvs_cache.json + rm tests/data/hgvs_cache.pkl.new + ## ## Copyright 2016 Source Code Committers diff --git a/README.md b/README.md index 3e5686de..ab6d4287 100644 --- a/README.md +++ b/README.md @@ -315,6 +315,41 @@ To run tests: make test ``` +#### Recorded test data + +Tests run offline by replaying recorded data, so they don't need a SeqRepo REST +service, a UTA database, or network access. Set `SEQREPO_ROOT_DIR=tests/data/seqrepo/latest` +(as CI does) when running or recording tests. + +- **VCR cassettes** (`tests/**/cassettes/*.yaml`) replay vrs-python's HTTP requests to + the [SeqRepo REST service](https://github.com/biocommons/seqrepo-rest-service). CI + runs `pytest --vcr-record=none`, so a test making an unrecorded request fails. +- **The hgvs cache** (`tests/data/hgvs_cache.json`) replays the hgvs library's UTA + queries and sequence fetches. `tests/conftest.py` enables it by default + (`VRS_HGVS_CACHE_MODE=run`), and a lookup missing from the cache raises + `HGVSDataNotAvailableError`. hgvs itself reads and writes its cache as a pickle; + `tests/hgvs_cache_json.py` converts between the two. + +To re-record, start the external services (`docker compose up` starts +seqrepo-rest-service on port 5000 and UTA on port 5432). With an existing local SeqRepo +snapshot, you can instead run just the REST service with it mounted: +`docker run -p 5000:5000 -v /path/to/seqrepo:/usr/local/share/seqrepo:ro biocommons/seqrepo-rest-service:0.2.2 seqrepo-rest-service /usr/local/share/seqrepo/2024-12-20`. +When a change needs new data in both, re-record the hgvs cache first, since cassette +recording reads hgvs data from it: + +```shell +# hgvs cache: needs UTA and seqrepo-rest-service; does not touch cassettes +export UTA_DB_URL=postgresql://anonymous@localhost:5432/uta/uta_20241220 +make record-hgvs-cache + +# VCR cassettes: needs seqrepo-rest-service +make clean-cassettes +pytest --vcr-record=once +``` + +`SEQREPO_REST_URL` (default `http://localhost:5000/seqrepo`) sets the REST service used +by both. + ## Running the Notebooks The notebooks **do not** require you to setup SeqRepo or UTA from diff --git a/tests/conftest.py b/tests/conftest.py index 4c843539..fd3d5d9a 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -1,10 +1,68 @@ import os +from collections.abc import Iterator +from pathlib import Path +import hgvs.dataproviders.uta import pytest from biocommons.seqrepo import SeqRepo +from hgvs_cache_json import json_to_pickle from ga4gh.vrs.dataproxy import SeqRepoDataProxy, SeqRepoRESTDataProxy +HGVS_CACHE_MODES = ("learn", "run", "verify") +HGVS_CACHE_JSON = Path(__file__).parent / "data" / "hgvs_cache.json" + + +@pytest.fixture(scope="session", autouse=True) +def hgvs_cached_data_provider( + tmp_path_factory: pytest.TempPathFactory, +) -> Iterator[hgvs.dataproviders.uta.UTABase | None]: + """Serve hgvs data provider lookups (UTA queries and hgvs sequence fetches) from a + recorded cache, so tests don't need a UTA database or network access. + + Every `HgvsTools` gets this one data provider, so in learn mode they cannot + overwrite each other's cache entries. `VRS_HGVS_CACHE_MODE` is `run` (default), + `learn`, or `verify`, or empty to query UTA directly without the cache. In run + mode, a lookup missing from the cache raises `HGVSDataNotAvailableError`. + + hgvs keeps its cache as a pickle, so in run and verify modes the committed + `tests/data/hgvs_cache.json` is converted to a temporary pickle for hgvs to load + (see `hgvs_cache_json.py`). Learn mode records a new cache, starting empty, into + the pickle file named by `VRS_HGVS_CACHE_FILE`. To re-record, run + `make record-hgvs-cache` with UTA_DB_URL pointing at a UTA instance and a + seqrepo-rest-service running at SEQREPO_REST_URL; it converts the recorded pickle + to `tests/data/hgvs_cache.json`. + + Learn and verify modes, and an empty mode, query UTA and fetch sequences live. The + VCR cassettes don't contain those hgvs sequence requests (to HGVS_SEQREPO_URL), so + run these modes with `pytest --disable-vcr`. + """ + mode = os.environ.get("VRS_HGVS_CACHE_MODE", "run") + if not mode: + yield None + return + if mode not in HGVS_CACHE_MODES: + msg = f"VRS_HGVS_CACHE_MODE must be one of {HGVS_CACHE_MODES} or empty, got {mode!r}" + raise pytest.UsageError(msg) + if mode == "learn": + cache_file = os.environ.get("VRS_HGVS_CACHE_FILE") + if not cache_file: + msg = "VRS_HGVS_CACHE_FILE must name the pickle file to record into in learn mode" + raise pytest.UsageError(msg) + else: + cache_file = str(tmp_path_factory.mktemp("hgvs_cache") / "hgvs_cache.pkl") + json_to_pickle(HGVS_CACHE_JSON, Path(cache_file)) + + provider = hgvs.dataproviders.uta.connect(mode=mode, cache=cache_file) + with pytest.MonkeyPatch.context() as mp: + mp.setattr( + hgvs.dataproviders.uta, "connect", lambda *_args, **_kwargs: provider + ) + # HgvsTools.close() closes its data provider, but this one is shared + mp.setattr(provider, "close", lambda: None) + yield provider + provider.close() + def remove_request_headers(request): """Remove all headers from VCR request before recording.""" diff --git a/tests/data/hgvs_cache.json b/tests/data/hgvs_cache.json new file mode 100644 index 00000000..878d4239 --- /dev/null +++ b/tests/data/hgvs_cache.json @@ -0,0 +1,1457 @@ +[ + { + "func": "get_seq", + "args": [ + "NC_000007.14", + 55181219, + 55181220 + ], + "value": "T" + }, + { + "func": "get_seq", + "args": [ + "NC_000007.14", + 55181219, + 55181240 + ], + "value": "TGGAAGGGGTCCATGTGCCCC" + }, + { + "func": "get_seq", + "args": [ + "NC_000007.14", + 55181226, + 55181230 + ], + "value": "GGTC" + }, + { + "func": "get_seq", + "args": [ + "NC_000007.14", + 55181229, + 55181250 + ], + "value": "CCATGTGCCCCTCCTTCTGGC" + }, + { + "func": "get_seq", + "args": [ + "NC_000007.14", + 55181230, + 55181231 + ], + "value": "C" + }, + { + "func": "get_seq", + "args": [ + "NC_000007.14", + 55181319, + 55181320 + ], + "value": "A" + }, + { + "func": "get_seq", + "args": [ + "NC_000007.14", + 55181319, + 55181340 + ], + "value": "AACCCCCACGTGTGCCGCCTG" + }, + { + "func": "get_seq", + "args": [ + "NC_000013.11", + 32316466, + 32316467 + ], + "value": "A" + }, + { + "func": "get_seq", + "args": [ + "NC_000013.11", + 32316466, + 32316487 + ], + "value": "ATTGGATCCAAAGAGAGGCCA" + }, + { + "func": "get_seq", + "args": [ + "NC_000013.11", + 32331042, + 32331094 + ], + "value": "TTTAGTTGAACTACAGGTTTTTTTGTTGTTGTTGTTTTGATTTTTTTTTTTT" + }, + { + "func": "get_seq", + "args": [ + "NC_000013.11", + 32331042, + 32331114 + ], + "value": "TTTAGTTGAACTACAGGTTTTTTTGTTGTTGTTGTTTTGATTTTTTTTTTTTGAGGTGGAGTCTTGCTCTGT" + }, + { + "func": "get_seq", + "args": [ + "NC_000013.11", + 32331082, + 32331094 + ], + "value": "TTTTTTTTTTTT" + }, + { + "func": "get_seq", + "args": [ + "NC_000013.11", + 32331082, + 32331114 + ], + "value": "TTTTTTTTTTTTGAGGTGGAGTCTTGCTCTGT" + }, + { + "func": "get_seq", + "args": [ + "NC_000013.11", + 32331092, + 32331094 + ], + "value": "TT" + }, + { + "func": "get_seq", + "args": [ + "NC_000013.11", + 32331093, + 32331094 + ], + "value": "T" + }, + { + "func": "get_seq", + "args": [ + "NC_000013.11", + 32936731, + 32936732 + ], + "value": "C" + }, + { + "func": "get_seq", + "args": [ + "NC_000019.10", + 289462, + 289466 + ], + "value": "CTCA" + }, + { + "func": "get_seq", + "args": [ + "NC_000019.10", + 289464, + 289466 + ], + "value": "CA" + }, + { + "func": "get_seq", + "args": [ + "NC_000019.10", + 289464, + 289486 + ], + "value": "CAGCACTTTGGGAGGCCGAGGC" + }, + { + "func": "get_seq", + "args": [ + "NC_000019.10", + 289465, + 289466 + ], + "value": "A" + }, + { + "func": "get_seq", + "args": [ + "NC_000019.10", + 289480, + 289501 + ], + "value": "CGAGGCGGGCAGATCACGAGG" + }, + { + "func": "get_seq", + "args": [ + "NC_000019.10", + 289480, + 289521 + ], + "value": "CGAGGCGGGCAGATCACGAGGTCAGGAGATCGAGACCATCC" + }, + { + "func": "get_seq", + "args": [ + "NC_000019.10", + 289500, + 289501 + ], + "value": "G" + }, + { + "func": "get_seq", + "args": [ + "NM_001331029.1", + 871, + 872 + ], + "value": "A" + }, + { + "func": "get_seq", + "args": [ + "NM_001331029.1", + 871, + 892 + ], + "value": "ATGAACTCAATGTTCAGGATT" + }, + { + "func": "get_seq", + "args": [ + "NM_181798.1", + 1262, + 1263 + ], + "value": "G" + }, + { + "func": "get_seq", + "args": [ + "NM_181798.1", + 1262, + 1268 + ], + "value": "GTTCTG" + }, + { + "func": "get_seq", + "args": [ + "NR_040711.1", + 1262, + 1263 + ], + "value": "G" + }, + { + "func": "get_seq", + "args": [ + "XM_017001344.1", + 871, + 872 + ], + "value": "A" + }, + { + "func": "get_tx_exons", + "args": [ + "NM_001331029.1", + "NC_000001.10", + "splign" + ], + "value": [ + { + "psycopg2_dictrow": { + "symbol": "PPP1R12B", + "hgnc": "PPP1R12B", + "gene_id": "4660", + "tx_ac": "NM_001331029.1", + "alt_ac": "NC_000001.10", + "alt_aln_method": "splign", + "alt_strand": 1, + "ord": 0, + "tx_start_i": 0, + "tx_end_i": 441, + "alt_start_i": 202317829, + "alt_end_i": 202318270, + "cigar": "441=", + "tx_aseq": null, + "alt_aseq": null, + "tx_exon_set_id": 808849, + "alt_exon_set_id": 810341, + "tx_exon_id": 6895004, + "alt_exon_id": 6911773, + "exon_aln_id": 4375364 + } + }, + { + "psycopg2_dictrow": { + "symbol": "PPP1R12B", + "hgnc": "PPP1R12B", + "gene_id": "4660", + "tx_ac": "NM_001331029.1", + "alt_ac": "NC_000001.10", + "alt_aln_method": "splign", + "alt_strand": 1, + "ord": 1, + "tx_start_i": 441, + "tx_end_i": 572, + "alt_start_i": 202385914, + "alt_end_i": 202386045, + "cigar": "131=", + "tx_aseq": null, + "alt_aseq": null, + "tx_exon_set_id": 808849, + "alt_exon_set_id": 810341, + "tx_exon_id": 6895005, + "alt_exon_id": 6911774, + "exon_aln_id": 4375329 + } + }, + { + "psycopg2_dictrow": { + "symbol": "PPP1R12B", + "hgnc": "PPP1R12B", + "gene_id": "4660", + "tx_ac": "NM_001331029.1", + "alt_ac": "NC_000001.10", + "alt_aln_method": "splign", + "alt_strand": 1, + "ord": 2, + "tx_start_i": 572, + "tx_end_i": 691, + "alt_start_i": 202391747, + "alt_end_i": 202391866, + "cigar": "119=", + "tx_aseq": null, + "alt_aseq": null, + "tx_exon_set_id": 808849, + "alt_exon_set_id": 810341, + "tx_exon_id": 6895006, + "alt_exon_id": 6911775, + "exon_aln_id": 4375326 + } + }, + { + "psycopg2_dictrow": { + "symbol": "PPP1R12B", + "hgnc": "PPP1R12B", + "gene_id": "4660", + "tx_ac": "NM_001331029.1", + "alt_ac": "NC_000001.10", + "alt_aln_method": "splign", + "alt_strand": 1, + "ord": 3, + "tx_start_i": 691, + "tx_end_i": 851, + "alt_start_i": 202394693, + "alt_end_i": 202394853, + "cigar": "160=", + "tx_aseq": null, + "alt_aseq": null, + "tx_exon_set_id": 808849, + "alt_exon_set_id": 810341, + "tx_exon_id": 6895007, + "alt_exon_id": 6911776, + "exon_aln_id": 4375339 + } + }, + { + "psycopg2_dictrow": { + "symbol": "PPP1R12B", + "hgnc": "PPP1R12B", + "gene_id": "4660", + "tx_ac": "NM_001331029.1", + "alt_ac": "NC_000001.10", + "alt_aln_method": "splign", + "alt_strand": 1, + "ord": 4, + "tx_start_i": 851, + "tx_end_i": 996, + "alt_start_i": 202396167, + "alt_end_i": 202396312, + "cigar": "145=", + "tx_aseq": null, + "alt_aseq": null, + "tx_exon_set_id": 808849, + "alt_exon_set_id": 810341, + "tx_exon_id": 6895008, + "alt_exon_id": 6911777, + "exon_aln_id": 4375320 + } + }, + { + "psycopg2_dictrow": { + "symbol": "PPP1R12B", + "hgnc": "PPP1R12B", + "gene_id": "4660", + "tx_ac": "NM_001331029.1", + "alt_ac": "NC_000001.10", + "alt_aln_method": "splign", + "alt_strand": 1, + "ord": 5, + "tx_start_i": 996, + "tx_end_i": 1071, + "alt_start_i": 202397982, + "alt_end_i": 202398057, + "cigar": "75=", + "tx_aseq": null, + "alt_aseq": null, + "tx_exon_set_id": 808849, + "alt_exon_set_id": 810341, + "tx_exon_id": 6895009, + "alt_exon_id": 6911778, + "exon_aln_id": 4375342 + } + }, + { + "psycopg2_dictrow": { + "symbol": "PPP1R12B", + "hgnc": "PPP1R12B", + "gene_id": "4660", + "tx_ac": "NM_001331029.1", + "alt_ac": "NC_000001.10", + "alt_aln_method": "splign", + "alt_strand": 1, + "ord": 6, + "tx_start_i": 1071, + "tx_end_i": 1151, + "alt_start_i": 202399858, + "alt_end_i": 202399938, + "cigar": "80=", + "tx_aseq": null, + "alt_aseq": null, + "tx_exon_set_id": 808849, + "alt_exon_set_id": 810341, + "tx_exon_id": 6895010, + "alt_exon_id": 6911779, + "exon_aln_id": 4375348 + } + }, + { + "psycopg2_dictrow": { + "symbol": "PPP1R12B", + "hgnc": "PPP1R12B", + "gene_id": "4660", + "tx_ac": "NM_001331029.1", + "alt_ac": "NC_000001.10", + "alt_aln_method": "splign", + "alt_strand": 1, + "ord": 7, + "tx_start_i": 1151, + "tx_end_i": 1291, + "alt_start_i": 202400607, + "alt_end_i": 202400747, + "cigar": "140=", + "tx_aseq": null, + "alt_aseq": null, + "tx_exon_set_id": 808849, + "alt_exon_set_id": 810341, + "tx_exon_id": 6895011, + "alt_exon_id": 6911780, + "exon_aln_id": 4375321 + } + }, + { + "psycopg2_dictrow": { + "symbol": "PPP1R12B", + "hgnc": "PPP1R12B", + "gene_id": "4660", + "tx_ac": "NM_001331029.1", + "alt_ac": "NC_000001.10", + "alt_aln_method": "splign", + "alt_strand": 1, + "ord": 8, + "tx_start_i": 1291, + "tx_end_i": 1404, + "alt_start_i": 202403783, + "alt_end_i": 202403896, + "cigar": "113=", + "tx_aseq": null, + "alt_aseq": null, + "tx_exon_set_id": 808849, + "alt_exon_set_id": 810341, + "tx_exon_id": 6895012, + "alt_exon_id": 6911781, + "exon_aln_id": 4375354 + } + }, + { + "psycopg2_dictrow": { + "symbol": "PPP1R12B", + "hgnc": "PPP1R12B", + "gene_id": "4660", + "tx_ac": "NM_001331029.1", + "alt_ac": "NC_000001.10", + "alt_aln_method": "splign", + "alt_strand": 1, + "ord": 9, + "tx_start_i": 1404, + "tx_end_i": 1608, + "alt_start_i": 202406948, + "alt_end_i": 202407152, + "cigar": "204=", + "tx_aseq": null, + "alt_aseq": null, + "tx_exon_set_id": 808849, + "alt_exon_set_id": 810341, + "tx_exon_id": 6895013, + "alt_exon_id": 6911782, + "exon_aln_id": 4375356 + } + }, + { + "psycopg2_dictrow": { + "symbol": "PPP1R12B", + "hgnc": "PPP1R12B", + "gene_id": "4660", + "tx_ac": "NM_001331029.1", + "alt_ac": "NC_000001.10", + "alt_aln_method": "splign", + "alt_strand": 1, + "ord": 10, + "tx_start_i": 1608, + "tx_end_i": 1691, + "alt_start_i": 202409833, + "alt_end_i": 202409916, + "cigar": "83=", + "tx_aseq": null, + "alt_aseq": null, + "tx_exon_set_id": 808849, + "alt_exon_set_id": 810341, + "tx_exon_id": 6895014, + "alt_exon_id": 6911783, + "exon_aln_id": 4375355 + } + }, + { + "psycopg2_dictrow": { + "symbol": "PPP1R12B", + "hgnc": "PPP1R12B", + "gene_id": "4660", + "tx_ac": "NM_001331029.1", + "alt_ac": "NC_000001.10", + "alt_aln_method": "splign", + "alt_strand": 1, + "ord": 11, + "tx_start_i": 1691, + "tx_end_i": 1817, + "alt_start_i": 202411574, + "alt_end_i": 202411700, + "cigar": "126=", + "tx_aseq": null, + "alt_aseq": null, + "tx_exon_set_id": 808849, + "alt_exon_set_id": 810341, + "tx_exon_id": 6895015, + "alt_exon_id": 6911784, + "exon_aln_id": 4375357 + } + }, + { + "psycopg2_dictrow": { + "symbol": "PPP1R12B", + "hgnc": "PPP1R12B", + "gene_id": "4660", + "tx_ac": "NM_001331029.1", + "alt_ac": "NC_000001.10", + "alt_aln_method": "splign", + "alt_strand": 1, + "ord": 12, + "tx_start_i": 1817, + "tx_end_i": 2000, + "alt_start_i": 202414173, + "alt_end_i": 202414356, + "cigar": "183=", + "tx_aseq": null, + "alt_aseq": null, + "tx_exon_set_id": 808849, + "alt_exon_set_id": 810341, + "tx_exon_id": 6895016, + "alt_exon_id": 6911785, + "exon_aln_id": 4375347 + } + }, + { + "psycopg2_dictrow": { + "symbol": "PPP1R12B", + "hgnc": "PPP1R12B", + "gene_id": "4660", + "tx_ac": "NM_001331029.1", + "alt_ac": "NC_000001.10", + "alt_aln_method": "splign", + "alt_strand": 1, + "ord": 13, + "tx_start_i": 2000, + "tx_end_i": 2183, + "alt_start_i": 202418116, + "alt_end_i": 202418299, + "cigar": "183=", + "tx_aseq": null, + "alt_aseq": null, + "tx_exon_set_id": 808849, + "alt_exon_set_id": 810341, + "tx_exon_id": 6895017, + "alt_exon_id": 6911786, + "exon_aln_id": 4375333 + } + }, + { + "psycopg2_dictrow": { + "symbol": "PPP1R12B", + "hgnc": "PPP1R12B", + "gene_id": "4660", + "tx_ac": "NM_001331029.1", + "alt_ac": "NC_000001.10", + "alt_aln_method": "splign", + "alt_strand": 1, + "ord": 14, + "tx_start_i": 2183, + "tx_end_i": 2274, + "alt_start_i": 202457660, + "alt_end_i": 202457751, + "cigar": "91=", + "tx_aseq": null, + "alt_aseq": null, + "tx_exon_set_id": 808849, + "alt_exon_set_id": 810341, + "tx_exon_id": 6895018, + "alt_exon_id": 6911787, + "exon_aln_id": 4375343 + } + }, + { + "psycopg2_dictrow": { + "symbol": "PPP1R12B", + "hgnc": "PPP1R12B", + "gene_id": "4660", + "tx_ac": "NM_001331029.1", + "alt_ac": "NC_000001.10", + "alt_aln_method": "splign", + "alt_strand": 1, + "ord": 15, + "tx_start_i": 2274, + "tx_end_i": 2478, + "alt_start_i": 202462241, + "alt_end_i": 202462445, + "cigar": "204=", + "tx_aseq": null, + "alt_aseq": null, + "tx_exon_set_id": 808849, + "alt_exon_set_id": 810341, + "tx_exon_id": 6895019, + "alt_exon_id": 6911788, + "exon_aln_id": 4375336 + } + }, + { + "psycopg2_dictrow": { + "symbol": "PPP1R12B", + "hgnc": "PPP1R12B", + "gene_id": "4660", + "tx_ac": "NM_001331029.1", + "alt_ac": "NC_000001.10", + "alt_aln_method": "splign", + "alt_strand": 1, + "ord": 16, + "tx_start_i": 2478, + "tx_end_i": 2668, + "alt_start_i": 202464420, + "alt_end_i": 202464610, + "cigar": "190=", + "tx_aseq": null, + "alt_aseq": null, + "tx_exon_set_id": 808849, + "alt_exon_set_id": 810341, + "tx_exon_id": 6895020, + "alt_exon_id": 6911789, + "exon_aln_id": 4375334 + } + }, + { + "psycopg2_dictrow": { + "symbol": "PPP1R12B", + "hgnc": "PPP1R12B", + "gene_id": "4660", + "tx_ac": "NM_001331029.1", + "alt_ac": "NC_000001.10", + "alt_aln_method": "splign", + "alt_strand": 1, + "ord": 17, + "tx_start_i": 2668, + "tx_end_i": 2781, + "alt_start_i": 202464697, + "alt_end_i": 202464810, + "cigar": "113=", + "tx_aseq": null, + "alt_aseq": null, + "tx_exon_set_id": 808849, + "alt_exon_set_id": 810341, + "tx_exon_id": 6895021, + "alt_exon_id": 6911790, + "exon_aln_id": 4375322 + } + }, + { + "psycopg2_dictrow": { + "symbol": "PPP1R12B", + "hgnc": "PPP1R12B", + "gene_id": "4660", + "tx_ac": "NM_001331029.1", + "alt_ac": "NC_000001.10", + "alt_aln_method": "splign", + "alt_strand": 1, + "ord": 18, + "tx_start_i": 2781, + "tx_end_i": 2823, + "alt_start_i": 202465908, + "alt_end_i": 202465950, + "cigar": "42=", + "tx_aseq": null, + "alt_aseq": null, + "tx_exon_set_id": 808849, + "alt_exon_set_id": 810341, + "tx_exon_id": 6895022, + "alt_exon_id": 6911791, + "exon_aln_id": 4375330 + } + }, + { + "psycopg2_dictrow": { + "symbol": "PPP1R12B", + "hgnc": "PPP1R12B", + "gene_id": "4660", + "tx_ac": "NM_001331029.1", + "alt_ac": "NC_000001.10", + "alt_aln_method": "splign", + "alt_strand": 1, + "ord": 19, + "tx_start_i": 2823, + "tx_end_i": 2840, + "alt_start_i": 202528004, + "alt_end_i": 202528021, + "cigar": "17=", + "tx_aseq": null, + "alt_aseq": null, + "tx_exon_set_id": 808849, + "alt_exon_set_id": 810341, + "tx_exon_id": 6895023, + "alt_exon_id": 6911792, + "exon_aln_id": 4375360 + } + }, + { + "psycopg2_dictrow": { + "symbol": "PPP1R12B", + "hgnc": "PPP1R12B", + "gene_id": "4660", + "tx_ac": "NM_001331029.1", + "alt_ac": "NC_000001.10", + "alt_aln_method": "splign", + "alt_strand": 1, + "ord": 20, + "tx_start_i": 2840, + "tx_end_i": 2985, + "alt_start_i": 202531905, + "alt_end_i": 202532050, + "cigar": "145=", + "tx_aseq": null, + "alt_aseq": null, + "tx_exon_set_id": 808849, + "alt_exon_set_id": 810341, + "tx_exon_id": 6895024, + "alt_exon_id": 6911793, + "exon_aln_id": 4375335 + } + }, + { + "psycopg2_dictrow": { + "symbol": "PPP1R12B", + "hgnc": "PPP1R12B", + "gene_id": "4660", + "tx_ac": "NM_001331029.1", + "alt_ac": "NC_000001.10", + "alt_aln_method": "splign", + "alt_strand": 1, + "ord": 21, + "tx_start_i": 2985, + "tx_end_i": 3090, + "alt_start_i": 202533570, + "alt_end_i": 202533675, + "cigar": "105=", + "tx_aseq": null, + "alt_aseq": null, + "tx_exon_set_id": 808849, + "alt_exon_set_id": 810341, + "tx_exon_id": 6895025, + "alt_exon_id": 6911794, + "exon_aln_id": 4375323 + } + }, + { + "psycopg2_dictrow": { + "symbol": "PPP1R12B", + "hgnc": "PPP1R12B", + "gene_id": "4660", + "tx_ac": "NM_001331029.1", + "alt_ac": "NC_000001.10", + "alt_aln_method": "splign", + "alt_strand": 1, + "ord": 22, + "tx_start_i": 3090, + "tx_end_i": 3144, + "alt_start_i": 202536905, + "alt_end_i": 202536959, + "cigar": "54=", + "tx_aseq": null, + "alt_aseq": null, + "tx_exon_set_id": 808849, + "alt_exon_set_id": 810341, + "tx_exon_id": 6895026, + "alt_exon_id": 6911795, + "exon_aln_id": 4375325 + } + }, + { + "psycopg2_dictrow": { + "symbol": "PPP1R12B", + "hgnc": "PPP1R12B", + "gene_id": "4660", + "tx_ac": "NM_001331029.1", + "alt_ac": "NC_000001.10", + "alt_aln_method": "splign", + "alt_strand": 1, + "ord": 23, + "tx_start_i": 3144, + "tx_end_i": 3195, + "alt_start_i": 202538274, + "alt_end_i": 202538325, + "cigar": "51=", + "tx_aseq": null, + "alt_aseq": null, + "tx_exon_set_id": 808849, + "alt_exon_set_id": 810341, + "tx_exon_id": 6895027, + "alt_exon_id": 6911796, + "exon_aln_id": 4375346 + } + }, + { + "psycopg2_dictrow": { + "symbol": "PPP1R12B", + "hgnc": "PPP1R12B", + "gene_id": "4660", + "tx_ac": "NM_001331029.1", + "alt_ac": "NC_000001.10", + "alt_aln_method": "splign", + "alt_strand": 1, + "ord": 24, + "tx_start_i": 3195, + "tx_end_i": 11291, + "alt_start_i": 202549601, + "alt_end_i": 202557697, + "cigar": "8096=", + "tx_aseq": null, + "alt_aseq": null, + "tx_exon_set_id": 808849, + "alt_exon_set_id": 810341, + "tx_exon_id": 6895028, + "alt_exon_id": 6911797, + "exon_aln_id": 4375324 + } + } + ] + }, + { + "func": "get_tx_exons", + "args": [ + "NM_181798.1", + "NC_000011.10", + "splign" + ], + "value": [ + { + "psycopg2_dictrow": { + "symbol": "KCNQ1", + "hgnc": "KCNQ1", + "gene_id": "3784", + "tx_ac": "NM_181798.1", + "alt_ac": "NC_000011.10", + "alt_aln_method": "splign", + "alt_strand": 1, + "ord": 0, + "tx_start_i": 0, + "tx_end_i": 261, + "alt_start_i": 2461453, + "alt_end_i": 2461714, + "cigar": "261=", + "tx_aseq": null, + "alt_aseq": null, + "tx_exon_set_id": 83331, + "alt_exon_set_id": 792010, + "tx_exon_id": 773599, + "alt_exon_id": 6791722, + "exon_aln_id": 3977791 + } + }, + { + "psycopg2_dictrow": { + "symbol": "KCNQ1", + "hgnc": "KCNQ1", + "gene_id": "3784", + "tx_ac": "NM_181798.1", + "alt_ac": "NC_000011.10", + "alt_aln_method": "splign", + "alt_strand": 1, + "ord": 1, + "tx_start_i": 261, + "tx_end_i": 352, + "alt_start_i": 2527927, + "alt_end_i": 2528018, + "cigar": "91=", + "tx_aseq": null, + "alt_aseq": null, + "tx_exon_set_id": 83331, + "alt_exon_set_id": 792010, + "tx_exon_id": 773600, + "alt_exon_id": 6791723, + "exon_aln_id": 3977803 + } + }, + { + "psycopg2_dictrow": { + "symbol": "KCNQ1", + "hgnc": "KCNQ1", + "gene_id": "3784", + "tx_ac": "NM_181798.1", + "alt_ac": "NC_000011.10", + "alt_aln_method": "splign", + "alt_strand": 1, + "ord": 2, + "tx_start_i": 352, + "tx_end_i": 479, + "alt_start_i": 2570627, + "alt_end_i": 2570754, + "cigar": "127=", + "tx_aseq": null, + "alt_aseq": null, + "tx_exon_set_id": 83331, + "alt_exon_set_id": 792010, + "tx_exon_id": 773601, + "alt_exon_id": 6791724, + "exon_aln_id": 3977799 + } + }, + { + "psycopg2_dictrow": { + "symbol": "KCNQ1", + "hgnc": "KCNQ1", + "gene_id": "3784", + "tx_ac": "NM_181798.1", + "alt_ac": "NC_000011.10", + "alt_aln_method": "splign", + "alt_strand": 1, + "ord": 3, + "tx_start_i": 479, + "tx_end_i": 558, + "alt_start_i": 2571324, + "alt_end_i": 2571403, + "cigar": "79=", + "tx_aseq": null, + "alt_aseq": null, + "tx_exon_set_id": 83331, + "alt_exon_set_id": 792010, + "tx_exon_id": 773602, + "alt_exon_id": 6791725, + "exon_aln_id": 3977778 + } + }, + { + "psycopg2_dictrow": { + "symbol": "KCNQ1", + "hgnc": "KCNQ1", + "gene_id": "3784", + "tx_ac": "NM_181798.1", + "alt_ac": "NC_000011.10", + "alt_aln_method": "splign", + "alt_strand": 1, + "ord": 4, + "tx_start_i": 558, + "tx_end_i": 655, + "alt_start_i": 2572012, + "alt_end_i": 2572109, + "cigar": "97=", + "tx_aseq": null, + "alt_aseq": null, + "tx_exon_set_id": 83331, + "alt_exon_set_id": 792010, + "tx_exon_id": 773603, + "alt_exon_id": 6791726, + "exon_aln_id": 3977805 + } + }, + { + "psycopg2_dictrow": { + "symbol": "KCNQ1", + "hgnc": "KCNQ1", + "gene_id": "3784", + "tx_ac": "NM_181798.1", + "alt_ac": "NC_000011.10", + "alt_aln_method": "splign", + "alt_strand": 1, + "ord": 5, + "tx_start_i": 655, + "tx_end_i": 796, + "alt_start_i": 2572845, + "alt_end_i": 2572986, + "cigar": "141=", + "tx_aseq": null, + "alt_aseq": null, + "tx_exon_set_id": 83331, + "alt_exon_set_id": 792010, + "tx_exon_id": 773604, + "alt_exon_id": 6791727, + "exon_aln_id": 3977802 + } + }, + { + "psycopg2_dictrow": { + "symbol": "KCNQ1", + "hgnc": "KCNQ1", + "gene_id": "3784", + "tx_ac": "NM_181798.1", + "alt_ac": "NC_000011.10", + "alt_aln_method": "splign", + "alt_strand": 1, + "ord": 6, + "tx_start_i": 796, + "tx_end_i": 907, + "alt_start_i": 2583434, + "alt_end_i": 2583545, + "cigar": "111=", + "tx_aseq": null, + "alt_aseq": null, + "tx_exon_set_id": 83331, + "alt_exon_set_id": 792010, + "tx_exon_id": 773605, + "alt_exon_id": 6791728, + "exon_aln_id": 3977793 + } + }, + { + "psycopg2_dictrow": { + "symbol": "KCNQ1", + "hgnc": "KCNQ1", + "gene_id": "3784", + "tx_ac": "NM_181798.1", + "alt_ac": "NC_000011.10", + "alt_aln_method": "splign", + "alt_strand": 1, + "ord": 7, + "tx_start_i": 907, + "tx_end_i": 1003, + "alt_start_i": 2585211, + "alt_end_i": 2585307, + "cigar": "96=", + "tx_aseq": null, + "alt_aseq": null, + "tx_exon_set_id": 83331, + "alt_exon_set_id": 792010, + "tx_exon_id": 773606, + "alt_exon_id": 6791729, + "exon_aln_id": 3977779 + } + }, + { + "psycopg2_dictrow": { + "symbol": "KCNQ1", + "hgnc": "KCNQ1", + "gene_id": "3784", + "tx_ac": "NM_181798.1", + "alt_ac": "NC_000011.10", + "alt_aln_method": "splign", + "alt_strand": 1, + "ord": 8, + "tx_start_i": 1003, + "tx_end_i": 1126, + "alt_start_i": 2587569, + "alt_end_i": 2587692, + "cigar": "123=", + "tx_aseq": null, + "alt_aseq": null, + "tx_exon_set_id": 83331, + "alt_exon_set_id": 792010, + "tx_exon_id": 773607, + "alt_exon_id": 6791730, + "exon_aln_id": 3977809 + } + }, + { + "psycopg2_dictrow": { + "symbol": "KCNQ1", + "hgnc": "KCNQ1", + "gene_id": "3784", + "tx_ac": "NM_181798.1", + "alt_ac": "NC_000011.10", + "alt_aln_method": "splign", + "alt_strand": 1, + "ord": 9, + "tx_start_i": 1126, + "tx_end_i": 1268, + "alt_start_i": 2588712, + "alt_end_i": 2588854, + "cigar": "142=", + "tx_aseq": null, + "alt_aseq": null, + "tx_exon_set_id": 83331, + "alt_exon_set_id": 792010, + "tx_exon_id": 773608, + "alt_exon_id": 6791731, + "exon_aln_id": 3977801 + } + }, + { + "psycopg2_dictrow": { + "symbol": "KCNQ1", + "hgnc": "KCNQ1", + "gene_id": "3784", + "tx_ac": "NM_181798.1", + "alt_ac": "NC_000011.10", + "alt_aln_method": "splign", + "alt_strand": 1, + "ord": 10, + "tx_start_i": 1268, + "tx_end_i": 1389, + "alt_start_i": 2661960, + "alt_end_i": 2662081, + "cigar": "121=", + "tx_aseq": null, + "alt_aseq": null, + "tx_exon_set_id": 83331, + "alt_exon_set_id": 792010, + "tx_exon_id": 773609, + "alt_exon_id": 6791732, + "exon_aln_id": 3977804 + } + }, + { + "psycopg2_dictrow": { + "symbol": "KCNQ1", + "hgnc": "KCNQ1", + "gene_id": "3784", + "tx_ac": "NM_181798.1", + "alt_ac": "NC_000011.10", + "alt_aln_method": "splign", + "alt_strand": 1, + "ord": 11, + "tx_start_i": 1389, + "tx_end_i": 1465, + "alt_start_i": 2768843, + "alt_end_i": 2768919, + "cigar": "76=", + "tx_aseq": null, + "alt_aseq": null, + "tx_exon_set_id": 83331, + "alt_exon_set_id": 792010, + "tx_exon_id": 773610, + "alt_exon_id": 6791733, + "exon_aln_id": 3977796 + } + }, + { + "psycopg2_dictrow": { + "symbol": "KCNQ1", + "hgnc": "KCNQ1", + "gene_id": "3784", + "tx_ac": "NM_181798.1", + "alt_ac": "NC_000011.10", + "alt_aln_method": "splign", + "alt_strand": 1, + "ord": 12, + "tx_start_i": 1465, + "tx_end_i": 1560, + "alt_start_i": 2775959, + "alt_end_i": 2776054, + "cigar": "95=", + "tx_aseq": null, + "alt_aseq": null, + "tx_exon_set_id": 83331, + "alt_exon_set_id": 792010, + "tx_exon_id": 773611, + "alt_exon_id": 6791734, + "exon_aln_id": 3977784 + } + }, + { + "psycopg2_dictrow": { + "symbol": "KCNQ1", + "hgnc": "KCNQ1", + "gene_id": "3784", + "tx_ac": "NM_181798.1", + "alt_ac": "NC_000011.10", + "alt_aln_method": "splign", + "alt_strand": 1, + "ord": 13, + "tx_start_i": 1560, + "tx_end_i": 1607, + "alt_start_i": 2776985, + "alt_end_i": 2777032, + "cigar": "47=", + "tx_aseq": null, + "alt_aseq": null, + "tx_exon_set_id": 83331, + "alt_exon_set_id": 792010, + "tx_exon_id": 773612, + "alt_exon_id": 6791735, + "exon_aln_id": 3977780 + } + }, + { + "psycopg2_dictrow": { + "symbol": "KCNQ1", + "hgnc": "KCNQ1", + "gene_id": "3784", + "tx_ac": "NM_181798.1", + "alt_ac": "NC_000011.10", + "alt_aln_method": "splign", + "alt_strand": 1, + "ord": 14, + "tx_start_i": 1607, + "tx_end_i": 1669, + "alt_start_i": 2777975, + "alt_end_i": 2778037, + "cigar": "62=", + "tx_aseq": null, + "alt_aseq": null, + "tx_exon_set_id": 83331, + "alt_exon_set_id": 792010, + "tx_exon_id": 773613, + "alt_exon_id": 6791736, + "exon_aln_id": 3977783 + } + }, + { + "psycopg2_dictrow": { + "symbol": "KCNQ1", + "hgnc": "KCNQ1", + "gene_id": "3784", + "tx_ac": "NM_181798.1", + "alt_ac": "NC_000011.10", + "alt_aln_method": "splign", + "alt_strand": 1, + "ord": 15, + "tx_start_i": 1669, + "tx_end_i": 3013, + "alt_start_i": 2847766, + "alt_end_i": 2849110, + "cigar": "1344=", + "tx_aseq": null, + "alt_aseq": null, + "tx_exon_set_id": 83331, + "alt_exon_set_id": 792010, + "tx_exon_id": 773614, + "alt_exon_id": 6791737, + "exon_aln_id": 3977787 + } + } + ] + }, + { + "func": "get_tx_identity_info", + "args": [ + "NM_001331029.1" + ], + "value": { + "psycopg2_dictrow": { + "tx_ac": "NM_001331029.1", + "alt_ac": "NM_001331029.1", + "alt_aln_method": "transcript", + "cds_start_i": 150, + "cds_end_i": 3282, + "lengths": [ + 441, + 131, + 119, + 160, + 145, + 75, + 80, + 140, + 113, + 204, + 83, + 126, + 183, + 183, + 91, + 204, + 190, + 113, + 42, + 17, + 145, + 105, + 54, + 51, + 8096 + ], + "hgnc": "PPP1R12B" + } + } + }, + { + "func": "get_tx_identity_info", + "args": [ + "NM_181798.1" + ], + "value": { + "psycopg2_dictrow": { + "tx_ac": "NM_181798.1", + "alt_ac": "NM_181798.1", + "alt_aln_method": "transcript", + "cds_start_i": 256, + "cds_end_i": 1906, + "lengths": [ + 261, + 91, + 127, + 79, + 97, + 141, + 111, + 96, + 123, + 142, + 121, + 76, + 95, + 47, + 62, + 1344 + ], + "hgnc": "KCNQ1" + } + } + }, + { + "func": "get_tx_info", + "args": [ + "NM_001331029.1", + "NC_000001.10", + "splign" + ], + "value": { + "psycopg2_dictrow": { + "hgnc": "PPP1R12B", + "cds_start_i": 150, + "cds_end_i": 3282, + "tx_ac": "NM_001331029.1", + "alt_ac": "NC_000001.10", + "alt_aln_method": "splign" + } + } + }, + { + "func": "get_tx_info", + "args": [ + "NM_181798.1", + "NC_000011.10", + "splign" + ], + "value": { + "psycopg2_dictrow": { + "hgnc": "KCNQ1", + "cds_start_i": 256, + "cds_end_i": 1906, + "tx_ac": "NM_181798.1", + "alt_ac": "NC_000011.10", + "alt_aln_method": "splign" + } + } + }, + { + "func": "get_tx_mapping_options", + "args": [ + "NM_001331029.1" + ], + "value": [ + { + "psycopg2_dictrow": { + "tx_ac": "NM_001331029.1", + "alt_ac": "NC_000001.10", + "alt_aln_method": "splign" + } + }, + { + "psycopg2_dictrow": { + "tx_ac": "NM_001331029.1", + "alt_ac": "NC_000001.11", + "alt_aln_method": "splign" + } + } + ] + }, + { + "func": "get_tx_mapping_options", + "args": [ + "NM_181798.1" + ], + "value": [ + { + "psycopg2_dictrow": { + "tx_ac": "NM_181798.1", + "alt_ac": "NC_000011.10", + "alt_aln_method": "splign" + } + }, + { + "psycopg2_dictrow": { + "tx_ac": "NM_181798.1", + "alt_ac": "NC_000011.9", + "alt_aln_method": "blat" + } + }, + { + "psycopg2_dictrow": { + "tx_ac": "NM_181798.1", + "alt_ac": "NC_000011.9", + "alt_aln_method": "splign" + } + }, + { + "psycopg2_dictrow": { + "tx_ac": "NM_181798.1", + "alt_ac": "NG_008935.1", + "alt_aln_method": "splign" + } + } + ] + }, + { + "func": "get_tx_mapping_options", + "args": [ + "NR_040711.1" + ], + "value": [] + }, + { + "func": "get_tx_mapping_options", + "args": [ + "XM_017001344.1" + ], + "value": [] + }, + { + "func": "schema_version", + "args": [], + "value": "1.2" + } +] diff --git a/tests/extras/cassettes/test_hgvs[NC_000007.14:g.55181220del-expected2].yaml b/tests/extras/cassettes/test_hgvs[NC_000007.14:g.55181220del-expected2].yaml index 01a253d4..9515082d 100644 --- a/tests/extras/cassettes/test_hgvs[NC_000007.14:g.55181220del-expected2].yaml +++ b/tests/extras/cassettes/test_hgvs[NC_000007.14:g.55181220del-expected2].yaml @@ -59,40 +59,4 @@ interactions: status: code: 200 message: OK -- request: - body: null - headers: {} - method: GET - uri: https://eutils.ncbi.nlm.nih.gov/entrez/eutils/efetch.fcgi?db=nucleotide&id=NC_000007.14&rettype=fasta&seq_start=55181220&seq_stop=55181220&tool=bioutils&email=biocommons-dev@googlegroups.com - response: - body: - string: '>NC_000007.14:55181220-55181220 Homo sapiens chromosome 7, GRCh38.p14 - Primary Assembly - - T - - - ' - headers: {} - status: - code: 200 - message: OK -- request: - body: null - headers: {} - method: GET - uri: https://eutils.ncbi.nlm.nih.gov/entrez/eutils/efetch.fcgi?db=nucleotide&id=NC_000007.14&rettype=fasta&seq_start=55181220&seq_stop=55181240&tool=bioutils&email=biocommons-dev@googlegroups.com - response: - body: - string: '>NC_000007.14:55181220-55181240 Homo sapiens chromosome 7, GRCh38.p14 - Primary Assembly - - TGGAAGGGGTCCATGTGCCCC - - - ' - headers: {} - status: - code: 200 - message: OK version: 1 diff --git a/tests/extras/cassettes/test_hgvs[NC_000007.14:g.55181230_55181231insGGCT-expected3].yaml b/tests/extras/cassettes/test_hgvs[NC_000007.14:g.55181230_55181231insGGCT-expected3].yaml index dbf9fef6..8e01ba90 100644 --- a/tests/extras/cassettes/test_hgvs[NC_000007.14:g.55181230_55181231insGGCT-expected3].yaml +++ b/tests/extras/cassettes/test_hgvs[NC_000007.14:g.55181230_55181231insGGCT-expected3].yaml @@ -35,58 +35,4 @@ interactions: status: code: 200 message: OK -- request: - body: null - headers: {} - method: GET - uri: https://eutils.ncbi.nlm.nih.gov/entrez/eutils/efetch.fcgi?db=nucleotide&id=NC_000007.14&rettype=fasta&seq_start=55181231&seq_stop=55181231&tool=bioutils&email=biocommons-dev@googlegroups.com - response: - body: - string: '>NC_000007.14:55181231-55181231 Homo sapiens chromosome 7, GRCh38.p14 - Primary Assembly - - C - - - ' - headers: {} - status: - code: 200 - message: OK -- request: - body: null - headers: {} - method: GET - uri: https://eutils.ncbi.nlm.nih.gov/entrez/eutils/efetch.fcgi?db=nucleotide&id=NC_000007.14&rettype=fasta&seq_start=55181230&seq_stop=55181250&tool=bioutils&email=biocommons-dev@googlegroups.com - response: - body: - string: '>NC_000007.14:55181230-55181250 Homo sapiens chromosome 7, GRCh38.p14 - Primary Assembly - - CCATGTGCCCCTCCTTCTGGC - - - ' - headers: {} - status: - code: 200 - message: OK -- request: - body: null - headers: {} - method: GET - uri: https://eutils.ncbi.nlm.nih.gov/entrez/eutils/efetch.fcgi?db=nucleotide&id=NC_000007.14&rettype=fasta&seq_start=55181227&seq_stop=55181230&tool=bioutils&email=biocommons-dev@googlegroups.com - response: - body: - string: '>NC_000007.14:55181227-55181230 Homo sapiens chromosome 7, GRCh38.p14 - Primary Assembly - - GGTC - - - ' - headers: {} - status: - code: 200 - message: OK version: 1 diff --git a/tests/extras/cassettes/test_hgvs[NC_000007.14:g.55181320A>T-expected1].yaml b/tests/extras/cassettes/test_hgvs[NC_000007.14:g.55181320A>T-expected1].yaml index 3c14c730..22b2d38f 100644 --- a/tests/extras/cassettes/test_hgvs[NC_000007.14:g.55181320A>T-expected1].yaml +++ b/tests/extras/cassettes/test_hgvs[NC_000007.14:g.55181320A>T-expected1].yaml @@ -34,40 +34,4 @@ interactions: status: code: 200 message: OK -- request: - body: null - headers: {} - method: GET - uri: https://eutils.ncbi.nlm.nih.gov/entrez/eutils/efetch.fcgi?db=nucleotide&id=NC_000007.14&rettype=fasta&seq_start=55181320&seq_stop=55181320&tool=bioutils&email=biocommons-dev@googlegroups.com - response: - body: - string: '>NC_000007.14:55181320-55181320 Homo sapiens chromosome 7, GRCh38.p14 - Primary Assembly - - A - - - ' - headers: {} - status: - code: 200 - message: OK -- request: - body: null - headers: {} - method: GET - uri: https://eutils.ncbi.nlm.nih.gov/entrez/eutils/efetch.fcgi?db=nucleotide&id=NC_000007.14&rettype=fasta&seq_start=55181320&seq_stop=55181340&tool=bioutils&email=biocommons-dev@googlegroups.com - response: - body: - string: '>NC_000007.14:55181320-55181340 Homo sapiens chromosome 7, GRCh38.p14 - Primary Assembly - - AACCCCCACGTGTGCCGCCTG - - - ' - headers: {} - status: - code: 200 - message: OK version: 1 diff --git a/tests/extras/cassettes/test_hgvs[NC_000013.11:g.32316467dup-expected5].yaml b/tests/extras/cassettes/test_hgvs[NC_000013.11:g.32316467dup-expected5].yaml index 7a529525..dbc79ed2 100644 --- a/tests/extras/cassettes/test_hgvs[NC_000013.11:g.32316467dup-expected5].yaml +++ b/tests/extras/cassettes/test_hgvs[NC_000013.11:g.32316467dup-expected5].yaml @@ -59,40 +59,4 @@ interactions: status: code: 200 message: OK -- request: - body: null - headers: {} - method: GET - uri: https://eutils.ncbi.nlm.nih.gov/entrez/eutils/efetch.fcgi?db=nucleotide&id=NC_000013.11&rettype=fasta&seq_start=32316467&seq_stop=32316467&tool=bioutils&email=biocommons-dev@googlegroups.com - response: - body: - string: '>NC_000013.11:32316467-32316467 Homo sapiens chromosome 13, GRCh38.p14 - Primary Assembly - - A - - - ' - headers: {} - status: - code: 200 - message: OK -- request: - body: null - headers: {} - method: GET - uri: https://eutils.ncbi.nlm.nih.gov/entrez/eutils/efetch.fcgi?db=nucleotide&id=NC_000013.11&rettype=fasta&seq_start=32316467&seq_stop=32316487&tool=bioutils&email=biocommons-dev@googlegroups.com - response: - body: - string: '>NC_000013.11:32316467-32316487 Homo sapiens chromosome 13, GRCh38.p14 - Primary Assembly - - ATTGGATCCAAAGAGAGGCCA - - - ' - headers: {} - status: - code: 200 - message: OK version: 1 diff --git a/tests/extras/cassettes/test_hgvs[NC_000013.11:g.32331093_32331094dup-expected4].yaml b/tests/extras/cassettes/test_hgvs[NC_000013.11:g.32331093_32331094dup-expected4].yaml index e61ad59e..2a9d5445 100644 --- a/tests/extras/cassettes/test_hgvs[NC_000013.11:g.32331093_32331094dup-expected4].yaml +++ b/tests/extras/cassettes/test_hgvs[NC_000013.11:g.32331093_32331094dup-expected4].yaml @@ -215,76 +215,4 @@ interactions: status: code: 200 message: OK -- request: - body: null - headers: {} - method: GET - uri: https://eutils.ncbi.nlm.nih.gov/entrez/eutils/efetch.fcgi?db=nucleotide&id=NC_000013.11&rettype=fasta&seq_start=32331083&seq_stop=32331094&tool=bioutils&email=biocommons-dev@googlegroups.com - response: - body: - string: '>NC_000013.11:32331083-32331094 Homo sapiens chromosome 13, GRCh38.p14 - Primary Assembly - - TTTTTTTTTTTT - - - ' - headers: {} - status: - code: 200 - message: OK -- request: - body: null - headers: {} - method: GET - uri: https://eutils.ncbi.nlm.nih.gov/entrez/eutils/efetch.fcgi?db=nucleotide&id=NC_000013.11&rettype=fasta&seq_start=32331094&seq_stop=32331094&tool=bioutils&email=biocommons-dev@googlegroups.com - response: - body: - string: '>NC_000013.11:32331094-32331094 Homo sapiens chromosome 13, GRCh38.p14 - Primary Assembly - - T - - - ' - headers: {} - status: - code: 200 - message: OK -- request: - body: null - headers: {} - method: GET - uri: https://eutils.ncbi.nlm.nih.gov/entrez/eutils/efetch.fcgi?db=nucleotide&id=NC_000013.11&rettype=fasta&seq_start=32331083&seq_stop=32331114&tool=bioutils&email=biocommons-dev@googlegroups.com - response: - body: - string: '>NC_000013.11:32331083-32331114 Homo sapiens chromosome 13, GRCh38.p14 - Primary Assembly - - TTTTTTTTTTTTGAGGTGGAGTCTTGCTCTGT - - - ' - headers: {} - status: - code: 200 - message: OK -- request: - body: null - headers: {} - method: GET - uri: https://eutils.ncbi.nlm.nih.gov/entrez/eutils/efetch.fcgi?db=nucleotide&id=NC_000013.11&rettype=fasta&seq_start=32331093&seq_stop=32331094&tool=bioutils&email=biocommons-dev@googlegroups.com - response: - body: - string: '>NC_000013.11:32331093-32331094 Homo sapiens chromosome 13, GRCh38.p14 - Primary Assembly - - TT - - - ' - headers: {} - status: - code: 200 - message: OK version: 1 diff --git a/tests/extras/cassettes/test_hgvs[NC_000013.11:g.32936732=-expected0].yaml b/tests/extras/cassettes/test_hgvs[NC_000013.11:g.32936732=-expected0].yaml index bded6051..ab55ae01 100644 --- a/tests/extras/cassettes/test_hgvs[NC_000013.11:g.32936732=-expected0].yaml +++ b/tests/extras/cassettes/test_hgvs[NC_000013.11:g.32936732=-expected0].yaml @@ -11,22 +11,4 @@ interactions: status: code: 200 message: OK -- request: - body: null - headers: {} - method: GET - uri: https://eutils.ncbi.nlm.nih.gov/entrez/eutils/efetch.fcgi?db=nucleotide&id=NC_000013.11&rettype=fasta&seq_start=32936732&seq_stop=32936732&tool=bioutils&email=biocommons-dev@googlegroups.com - response: - body: - string: '>NC_000013.11:32936732-32936732 Homo sapiens chromosome 13, GRCh38.p14 - Primary Assembly - - C - - - ' - headers: {} - status: - code: 200 - message: OK version: 1 diff --git a/tests/extras/cassettes/test_hgvs[NC_000019.10:g.289464_289465insCACA-expected8].yaml b/tests/extras/cassettes/test_hgvs[NC_000019.10:g.289464_289465insCACA-expected8].yaml index 3cf20e71..ff25ea33 100644 --- a/tests/extras/cassettes/test_hgvs[NC_000019.10:g.289464_289465insCACA-expected8].yaml +++ b/tests/extras/cassettes/test_hgvs[NC_000019.10:g.289464_289465insCACA-expected8].yaml @@ -71,76 +71,4 @@ interactions: status: code: 200 message: OK -- request: - body: null - headers: {} - method: GET - uri: https://eutils.ncbi.nlm.nih.gov/entrez/eutils/efetch.fcgi?db=nucleotide&id=NC_000019.10&rettype=fasta&seq_start=289465&seq_stop=289466&tool=bioutils&email=biocommons-dev@googlegroups.com - response: - body: - string: '>NC_000019.10:289465-289466 Homo sapiens chromosome 19, GRCh38.p14 - Primary Assembly - - CA - - - ' - headers: {} - status: - code: 200 - message: OK -- request: - body: null - headers: {} - method: GET - uri: https://eutils.ncbi.nlm.nih.gov/entrez/eutils/efetch.fcgi?db=nucleotide&id=NC_000019.10&rettype=fasta&seq_start=289466&seq_stop=289466&tool=bioutils&email=biocommons-dev@googlegroups.com - response: - body: - string: '>NC_000019.10:289466-289466 Homo sapiens chromosome 19, GRCh38.p14 - Primary Assembly - - A - - - ' - headers: {} - status: - code: 200 - message: OK -- request: - body: null - headers: {} - method: GET - uri: https://eutils.ncbi.nlm.nih.gov/entrez/eutils/efetch.fcgi?db=nucleotide&id=NC_000019.10&rettype=fasta&seq_start=289465&seq_stop=289486&tool=bioutils&email=biocommons-dev@googlegroups.com - response: - body: - string: '>NC_000019.10:289465-289486 Homo sapiens chromosome 19, GRCh38.p14 - Primary Assembly - - CAGCACTTTGGGAGGCCGAGGC - - - ' - headers: {} - status: - code: 200 - message: OK -- request: - body: null - headers: {} - method: GET - uri: https://eutils.ncbi.nlm.nih.gov/entrez/eutils/efetch.fcgi?db=nucleotide&id=NC_000019.10&rettype=fasta&seq_start=289463&seq_stop=289466&tool=bioutils&email=biocommons-dev@googlegroups.com - response: - body: - string: '>NC_000019.10:289463-289466 Homo sapiens chromosome 19, GRCh38.p14 - Primary Assembly - - CTCA - - - ' - headers: {} - status: - code: 200 - message: OK version: 1 diff --git a/tests/extras/cassettes/test_hgvs[NC_000019.10:g.289485_289500del-expected9].yaml b/tests/extras/cassettes/test_hgvs[NC_000019.10:g.289485_289500del-expected9].yaml index 96e65209..2a55e187 100644 --- a/tests/extras/cassettes/test_hgvs[NC_000019.10:g.289485_289500del-expected9].yaml +++ b/tests/extras/cassettes/test_hgvs[NC_000019.10:g.289485_289500del-expected9].yaml @@ -119,58 +119,4 @@ interactions: status: code: 200 message: OK -- request: - body: null - headers: {} - method: GET - uri: https://eutils.ncbi.nlm.nih.gov/entrez/eutils/efetch.fcgi?db=nucleotide&id=NC_000019.10&rettype=fasta&seq_start=289481&seq_stop=289501&tool=bioutils&email=biocommons-dev@googlegroups.com - response: - body: - string: '>NC_000019.10:289481-289501 Homo sapiens chromosome 19, GRCh38.p14 - Primary Assembly - - CGAGGCGGGCAGATCACGAGG - - - ' - headers: {} - status: - code: 200 - message: OK -- request: - body: null - headers: {} - method: GET - uri: https://eutils.ncbi.nlm.nih.gov/entrez/eutils/efetch.fcgi?db=nucleotide&id=NC_000019.10&rettype=fasta&seq_start=289501&seq_stop=289501&tool=bioutils&email=biocommons-dev@googlegroups.com - response: - body: - string: '>NC_000019.10:289501-289501 Homo sapiens chromosome 19, GRCh38.p14 - Primary Assembly - - G - - - ' - headers: {} - status: - code: 200 - message: OK -- request: - body: null - headers: {} - method: GET - uri: https://eutils.ncbi.nlm.nih.gov/entrez/eutils/efetch.fcgi?db=nucleotide&id=NC_000019.10&rettype=fasta&seq_start=289481&seq_stop=289521&tool=bioutils&email=biocommons-dev@googlegroups.com - response: - body: - string: '>NC_000019.10:289481-289521 Homo sapiens chromosome 19, GRCh38.p14 - Primary Assembly - - CGAGGCGGGCAGATCACGAGGTCAGGAGATCGAGACCATCC - - - ' - headers: {} - status: - code: 200 - message: OK version: 1 diff --git a/tests/extras/cassettes/test_hgvs[NM_001331029.1:c.722A>G-expected6].yaml b/tests/extras/cassettes/test_hgvs[NM_001331029.1:c.722A>G-expected6].yaml index 44352fa1..d86ad12f 100644 --- a/tests/extras/cassettes/test_hgvs[NM_001331029.1:c.722A>G-expected6].yaml +++ b/tests/extras/cassettes/test_hgvs[NM_001331029.1:c.722A>G-expected6].yaml @@ -16,24 +16,6 @@ interactions: status: code: 200 message: OK -- request: - body: null - headers: {} - method: GET - uri: https://eutils.ncbi.nlm.nih.gov/entrez/eutils/efetch.fcgi?db=nucleotide&id=NM_001331029.1&rettype=fasta&seq_start=872&seq_stop=872&tool=bioutils&email=biocommons-dev@googlegroups.com - response: - body: - string: '>NM_001331029.1:872-872 Homo sapiens protein phosphatase 1 regulatory - subunit 12B (PPP1R12B), transcript variant 8, mRNA - - A - - - ' - headers: {} - status: - code: 200 - message: OK - request: body: null headers: {} @@ -63,22 +45,4 @@ interactions: status: code: 200 message: OK -- request: - body: null - headers: {} - method: GET - uri: https://eutils.ncbi.nlm.nih.gov/entrez/eutils/efetch.fcgi?db=nucleotide&id=NM_001331029.1&rettype=fasta&seq_start=872&seq_stop=892&tool=bioutils&email=biocommons-dev@googlegroups.com - response: - body: - string: '>NM_001331029.1:872-892 Homo sapiens protein phosphatase 1 regulatory - subunit 12B (PPP1R12B), transcript variant 8, mRNA - - ATGAACTCAATGTTCAGGATT - - - ' - headers: {} - status: - code: 200 - message: OK version: 1 diff --git a/tests/extras/cassettes/test_hgvs[NM_181798.1:c.1007G>T-expected7].yaml b/tests/extras/cassettes/test_hgvs[NM_181798.1:c.1007G>T-expected7].yaml index 20c3a261..34775aab 100644 --- a/tests/extras/cassettes/test_hgvs[NM_181798.1:c.1007G>T-expected7].yaml +++ b/tests/extras/cassettes/test_hgvs[NM_181798.1:c.1007G>T-expected7].yaml @@ -16,24 +16,6 @@ interactions: status: code: 200 message: OK -- request: - body: null - headers: {} - method: GET - uri: https://eutils.ncbi.nlm.nih.gov/entrez/eutils/efetch.fcgi?db=nucleotide&id=NM_181798.1&rettype=fasta&seq_start=1263&seq_stop=1263&tool=bioutils&email=biocommons-dev@googlegroups.com - response: - body: - string: '>NM_181798.1:1263-1263 Homo sapiens potassium voltage-gated channel - subfamily Q member 1 (KCNQ1), transcript variant 2, mRNA - - G - - - ' - headers: {} - status: - code: 200 - message: OK - request: body: null headers: {} @@ -63,40 +45,4 @@ interactions: status: code: 200 message: OK -- request: - body: null - headers: {} - method: GET - uri: https://eutils.ncbi.nlm.nih.gov/entrez/eutils/efetch.fcgi?db=nucleotide&id=NM_181798.1&rettype=fasta&seq_start=1263&seq_stop=1268&tool=bioutils&email=biocommons-dev@googlegroups.com - response: - body: - string: '>NM_181798.1:1263-1268 Homo sapiens potassium voltage-gated channel - subfamily Q member 1 (KCNQ1), transcript variant 2, mRNA - - GTTCTG - - - ' - headers: {} - status: - code: 200 - message: OK -- request: - body: null - headers: {} - method: GET - uri: https://eutils.ncbi.nlm.nih.gov/entrez/eutils/efetch.fcgi?db=nucleotide&id=NR_040711.1&rettype=fasta&seq_start=1263&seq_stop=1263&tool=bioutils&email=biocommons-dev@googlegroups.com - response: - body: - string: '>NR_040711.1:1263-1263 Homo sapiens potassium voltage-gated channel, - KQT-like subfamily, member 1 (KCNQ1), transcript variant 2, non-coding RNA - - G - - - ' - headers: {} - status: - code: 200 - message: OK version: 1 diff --git a/tests/extras/cassettes/test_hgvs_cache_run_mode_is_offline.yaml b/tests/extras/cassettes/test_hgvs_cache_run_mode_is_offline.yaml new file mode 100644 index 00000000..34775aab --- /dev/null +++ b/tests/extras/cassettes/test_hgvs_cache_run_mode_is_offline.yaml @@ -0,0 +1,48 @@ +interactions: +- request: + body: null + headers: {} + method: GET + uri: http://localhost:5000/seqrepo/1/metadata/refseq:NM_181798.1 + response: + body: + string: "{\n \"added\": \"2016-08-24T05:03:05Z\",\n \"aliases\": [\n \"MD5:93e2dc533ba755782b3affcf53470434\",\n + \ \"NCBI:NM_181798.1\",\n \"refseq:NM_181798.1\",\n \"NCBI:NR_040711.1\",\n + \ \"refseq:NR_040711.1\",\n \"SEGUID:0nrqUDibhGAQBZ4pXR+soOiCOf0\",\n + \ \"SHA1:d27aea50389b846010059e295d1faca0e88239fd\",\n \"VMC:GS_KN07u-RFqd1dTyOWOG98HnOq87Nq-ZIg\",\n + \ \"sha512t24u:KN07u-RFqd1dTyOWOG98HnOq87Nq-ZIg\",\n \"ga4gh:SQ.KN07u-RFqd1dTyOWOG98HnOq87Nq-ZIg\"\n + \ ],\n \"alphabet\": \"ACGT\",\n \"length\": 3029\n}\n" + headers: {} + status: + code: 200 + message: OK +- request: + body: null + headers: {} + method: GET + uri: http://localhost:5000/seqrepo/1/metadata/ga4gh:SQ.KN07u-RFqd1dTyOWOG98HnOq87Nq-ZIg + response: + body: + string: "{\n \"added\": \"2016-08-24T05:03:05Z\",\n \"aliases\": [\n \"MD5:93e2dc533ba755782b3affcf53470434\",\n + \ \"NCBI:NM_181798.1\",\n \"refseq:NM_181798.1\",\n \"NCBI:NR_040711.1\",\n + \ \"refseq:NR_040711.1\",\n \"SEGUID:0nrqUDibhGAQBZ4pXR+soOiCOf0\",\n + \ \"SHA1:d27aea50389b846010059e295d1faca0e88239fd\",\n \"VMC:GS_KN07u-RFqd1dTyOWOG98HnOq87Nq-ZIg\",\n + \ \"sha512t24u:KN07u-RFqd1dTyOWOG98HnOq87Nq-ZIg\",\n \"ga4gh:SQ.KN07u-RFqd1dTyOWOG98HnOq87Nq-ZIg\"\n + \ ],\n \"alphabet\": \"ACGT\",\n \"length\": 3029\n}\n" + headers: {} + status: + code: 200 + message: OK +- request: + body: null + headers: {} + method: GET + uri: http://localhost:5000/seqrepo/1/sequence/ga4gh:SQ.KN07u-RFqd1dTyOWOG98HnOq87Nq-ZIg?start=1262&end=1263 + response: + body: + string: G + headers: {} + status: + code: 200 + message: OK +version: 1 diff --git a/tests/extras/cassettes/test_rle_seq_limit.yaml b/tests/extras/cassettes/test_rle_seq_limit.yaml index d7046ab8..96521dda 100644 --- a/tests/extras/cassettes/test_rle_seq_limit.yaml +++ b/tests/extras/cassettes/test_rle_seq_limit.yaml @@ -503,42 +503,4 @@ interactions: status: code: 200 message: OK -- request: - body: null - headers: {} - method: GET - uri: https://eutils.ncbi.nlm.nih.gov/entrez/eutils/efetch.fcgi?db=nucleotide&id=NC_000013.11&rettype=fasta&seq_start=32331043&seq_stop=32331094&tool=bioutils&email=biocommons-dev@googlegroups.com - response: - body: - string: '>NC_000013.11:32331043-32331094 Homo sapiens chromosome 13, GRCh38.p14 - Primary Assembly - - TTTAGTTGAACTACAGGTTTTTTTGTTGTTGTTGTTTTGATTTTTTTTTTTT - - - ' - headers: {} - status: - code: 200 - message: OK -- request: - body: null - headers: {} - method: GET - uri: https://eutils.ncbi.nlm.nih.gov/entrez/eutils/efetch.fcgi?db=nucleotide&id=NC_000013.11&rettype=fasta&seq_start=32331043&seq_stop=32331114&tool=bioutils&email=biocommons-dev@googlegroups.com - response: - body: - string: '>NC_000013.11:32331043-32331114 Homo sapiens chromosome 13, GRCh38.p14 - Primary Assembly - - TTTAGTTGAACTACAGGTTTTTTTGTTGTTGTTGTTTTGATTTTTTTTTTTTGAGGTGGAGTCTTGCTCT - - GT - - - ' - headers: {} - status: - code: 200 - message: OK version: 1 diff --git a/tests/extras/test_allele_translator.py b/tests/extras/test_allele_translator.py index 15f87a89..ce161082 100644 --- a/tests/extras/test_allele_translator.py +++ b/tests/extras/test_allele_translator.py @@ -1,4 +1,9 @@ +from typing import NoReturn + +import hgvs.dataproviders.seqfetcher +import hgvs.dataproviders.uta import pytest +from hgvs.decorators.lru_cache import RUN from ga4gh.vrs import models from ga4gh.vrs.dataproxy import DataProxyValidationError @@ -751,6 +756,34 @@ def test_hgvs(tlr, hgvsexpr, expected): ) +@pytest.mark.vcr +def test_hgvs_cache_run_mode_is_offline( + monkeypatch: pytest.MonkeyPatch, + tlr: AlleleTranslator, + hgvs_cached_data_provider: hgvs.dataproviders.uta.UTABase | None, +) -> None: + """With the tests' default hgvs cache (run mode), translating to and from hgvs + makes no UTA queries or hgvs sequence fetches. + + Replaces the two places hgvs reaches outside the process, `UTA_postgresql._get_cursor` + (every UTA query) and `SeqFetcher.fetch_seq` (every sequence fetch), with a function + that fails, then translates a transcript variant both ways. Skipped outside run mode + (e.g. when re-recording the cache), where both are expected. + """ + if hgvs_cached_data_provider is None or hgvs_cached_data_provider.mode != RUN: + pytest.skip("only applies when the hgvs cache is in run mode") + + def fail(*args: object, **kwargs: object) -> NoReturn: # noqa: ARG001 + msg = "hgvs queried UTA or fetched a sequence in hgvs cache run mode" + raise AssertionError(msg) + + monkeypatch.setattr(hgvs.dataproviders.uta.UTA_postgresql, "_get_cursor", fail) + monkeypatch.setattr(hgvs.dataproviders.seqfetcher.SeqFetcher, "fetch_seq", fail) + + allele = tlr.translate_from("NM_181798.1:c.1007G>T", "hgvs") + assert "NM_181798.1:c.1007G>T" in tlr.translate_to(allele, "hgvs") + + @pytest.mark.vcr def test_rle_seq_limit(tlr): """Test that for an ReferenceLengthExpression over 50bp, the sequence is not diff --git a/tests/extras/test_hgvs_tools.py b/tests/extras/test_hgvs_tools.py index fde53e60..5d48dbeb 100644 --- a/tests/extras/test_hgvs_tools.py +++ b/tests/extras/test_hgvs_tools.py @@ -1,5 +1,6 @@ """Tests for ga4gh.vrs.utils.hgvs_tools.""" +import hgvs.dataproviders.uta import hgvs.parser import pytest @@ -40,3 +41,15 @@ def test_is_intronic(hgvs_tools, hgvs_expr, expected): sv = hgvs_tools.parse(hgvs_expr) assert sv is not None assert hgvs_tools.is_intronic(sv) is expected + + +def test_hgvs_cache_data_provider_is_shared( + hgvs_cached_data_provider: hgvs.dataproviders.uta.UTABase | None, +) -> None: + """Every HgvsTools gets the tests' shared hgvs cache data provider, so in learn + mode they cannot overwrite each other's cache entries + """ + if hgvs_cached_data_provider is None: + pytest.skip("the hgvs cache is disabled") + assert HgvsTools().uta_conn is hgvs_cached_data_provider + assert HgvsTools().uta_conn is hgvs_cached_data_provider diff --git a/tests/hgvs_cache_json.py b/tests/hgvs_cache_json.py new file mode 100644 index 00000000..b1c84033 --- /dev/null +++ b/tests/hgvs_cache_json.py @@ -0,0 +1,93 @@ +"""Convert between hgvs's pickled data provider cache and the JSON file tests commit. + +hgvs reads and writes its cache (`hgvs.dataproviders.uta.connect(mode=..., cache=...)`) +as a pickle, which can run code when loaded and can't be reviewed in a diff. Tests +instead commit `tests/data/hgvs_cache.json` and generate the pickle from it at startup. + +Each cache entry is stored as ``{"func": ..., "args": [...], "value": ...}``. Values are +strings, numbers, None, lists, and UTA rows (`psycopg2.extras.DictRow`), which are +stored as ``{"psycopg2_dictrow": {column: value, ...}}`` in column order. + +Usage, to convert a cache hgvs just recorded: +``python tests/hgvs_cache_json.py `` +""" + +import json +import pickle +import sys +from collections import OrderedDict +from pathlib import Path +from typing import Any + +from hgvs.decorators.lru_cache import _make_key +from psycopg2.extras import DictRow + +# hgvs builds each cache key as (*args, "__func__", function name) +_FUNC_MARKER = "__func__" +_DICTROW_TAG = "psycopg2_dictrow" +_JSON_SCALARS = (str, int, float, bool, type(None)) + + +def _encode_value(value: Any) -> Any: # noqa: ANN401 + """Convert a cached hgvs result to a JSON value""" + if isinstance(value, DictRow): + return {_DICTROW_TAG: dict(value.items())} + if isinstance(value, list): + return [_encode_value(v) for v in value] + if isinstance(value, _JSON_SCALARS): + return value + msg = f"can't store a {type(value).__name__} in the hgvs JSON cache: {value!r}" + raise TypeError(msg) + + +def _decode_value(value: Any) -> Any: # noqa: ANN401 + """Convert a JSON value back to the cached hgvs result, rebuilding UTA rows""" + if isinstance(value, dict): + if value.keys() != {_DICTROW_TAG}: + msg = f'expected {{"{_DICTROW_TAG}": {{...}}}}, got {value!r}' + raise ValueError(msg) + columns: dict[str, Any] = value[_DICTROW_TAG] + row = DictRow.__new__(DictRow) + index = OrderedDict((column, i) for i, column in enumerate(columns)) + row.__setstate__((list(columns.values()), index)) + return row + if isinstance(value, list): + return [_decode_value(v) for v in value] + return value + + +def pickle_to_json(pickle_file: Path, json_file: Path) -> None: + """Write the hgvs cache pickle `pickle_file` as JSON to `json_file` + + Only use this on a cache hgvs just recorded: loading a pickle can run code. + """ + with pickle_file.open("rb") as f: + cache: dict = pickle.load(f) # noqa: S301 # hgvs cache key -> cached result + entries = [] + for key in cache: + *args, marker, func = key + if marker != _FUNC_MARKER: + msg = f"unexpected hgvs cache key layout: {key!r}" + raise ValueError(msg) + entries.append({"func": func, "args": args, "value": _encode_value(cache[key])}) + entries.sort(key=lambda e: (e["func"], json.dumps(e["args"]))) + json_file.write_text(json.dumps(entries, indent=2) + "\n") + + +def json_to_pickle(json_file: Path, pickle_file: Path) -> None: + """Write the JSON hgvs cache `json_file` as the pickle hgvs loads to `pickle_file`""" + entries: list[dict[str, Any]] = json.loads(json_file.read_text()) + cache = {} + for e in entries: + try: + value = _decode_value(e["value"]) + except ValueError as err: + msg = f"{json_file}: {e['func']} {e['args']}: {err}" + raise ValueError(msg) from err + cache[_make_key(e["func"], tuple(e["args"]), {}, False, ())] = value + with pickle_file.open("wb") as f: + pickle.dump(cache, f) + + +if __name__ == "__main__": + pickle_to_json(Path(sys.argv[1]), Path(sys.argv[2]))