Skip to content

Commit bcffb5b

Browse files
docs: complete hgvs2reference documentation and reorganise user guides
- add CLI and Python API documentation for hgvs2reference - update the User Manual to include hgvs2reference alongside the other tools - update the documentation landing page to reflect the current software suite - update MkDocs navigation to include the hgvs2reference CLI and Python API - improve organisation of the documentation by interface (Web, Installation, User Manual and REST API) - ensure documentation links and navigation match the current project structure - remove references to documentation pages that do not exist - improve consistency across tool descriptions and documentation sections
1 parent 0f5e4f0 commit bcffb5b

8 files changed

Lines changed: 994 additions & 57 deletions

File tree

Lines changed: 360 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,360 @@
1+
#!/usr/bin/env python3
2+
3+
"""
4+
VariantValidator HGVS2Reference Command Line Interface.
5+
6+
The HGVS2Reference CLI provides convenient access to the
7+
VariantValidator `hgvs2ref()` method for retrieving the reference
8+
sequence corresponding to an HGVS variant description.
9+
10+
Features
11+
--------
12+
* Query genomic, coding and non-coding HGVS variants
13+
* Support transcript variants with explicit genomic context
14+
* Pretty-printed JSON output
15+
* Configurable logging
16+
"""
17+
18+
from __future__ import annotations
19+
20+
import argparse
21+
import json
22+
import logging
23+
import sys
24+
25+
import VariantValidator
26+
27+
from VariantValidator import logger as vvlogger
28+
29+
30+
LOGGER = logging.getLogger(__name__)
31+
32+
33+
EXIT_SUCCESS = 0
34+
EXIT_INPUT_ERROR = 2
35+
EXIT_UNEXPECTED_ERROR = 5
36+
37+
38+
EXAMPLES = """
39+
Examples
40+
--------
41+
42+
Common usage
43+
~~~~~~~~~~~~
44+
45+
Query a genomic variant
46+
47+
hgvs2reference -q NC_000017.11:g.7676594C>T
48+
49+
Query a coding variant
50+
51+
hgvs2reference -q NM_000546.6:c.215C>G
52+
53+
Query a transcript variant with genomic context
54+
55+
hgvs2reference -q NC_000017.11(NM_000546.6):c.375+1G>A
56+
57+
58+
Output
59+
~~~~~~
60+
61+
Write JSON to a file
62+
63+
hgvs2reference -q NM_000546.6:c.215C>G -o results.json
64+
"""
65+
66+
# ----------------------------------------------------------------------
67+
# Logging
68+
# ----------------------------------------------------------------------
69+
70+
71+
def configure_logging(level: str | None) -> None:
72+
"""
73+
Configure logging for the HGVS2Reference CLI.
74+
75+
Parameters
76+
----------
77+
level
78+
Console logging level supplied on the command line.
79+
If None, the logging configuration defined in
80+
VariantValidator.settings is used.
81+
"""
82+
83+
vvlogger.configure_logging(
84+
console_level=level,
85+
)
86+
87+
LOGGER.debug("Logging initialised")
88+
89+
90+
# ----------------------------------------------------------------------
91+
# Argument parser
92+
# ----------------------------------------------------------------------
93+
94+
95+
class CustomFormatter(
96+
argparse.ArgumentDefaultsHelpFormatter,
97+
argparse.RawTextHelpFormatter,
98+
):
99+
"""
100+
Preserve help formatting while displaying default values.
101+
"""
102+
pass
103+
104+
105+
def build_parser() -> argparse.ArgumentParser:
106+
"""
107+
Build the command-line argument parser.
108+
"""
109+
110+
parser = argparse.ArgumentParser(
111+
prog="hgvs2reference",
112+
description=(
113+
"Retrieve the reference sequence corresponding "
114+
"to an HGVS variant description."
115+
),
116+
formatter_class=CustomFormatter,
117+
epilog=EXAMPLES,
118+
)
119+
120+
#
121+
# Query
122+
#
123+
124+
parser.add_argument(
125+
"-q",
126+
"--query",
127+
required=True,
128+
metavar="HGVS",
129+
help="""
130+
HGVS variant description.
131+
132+
Supported formats
133+
134+
• Genomic (g.)
135+
• Coding (c.)
136+
• Non-coding transcript (n.)
137+
• Transcript with explicit genomic context
138+
(NC_(NM_) / NC_(NR_))
139+
140+
See the examples below.
141+
""",
142+
)
143+
144+
#
145+
# Output
146+
#
147+
148+
output = parser.add_argument_group(
149+
"Output"
150+
)
151+
152+
output.add_argument(
153+
"-o",
154+
"--output",
155+
type=argparse.FileType("w"),
156+
default=sys.stdout,
157+
metavar="FILE",
158+
help=(
159+
"Write JSON output to FILE "
160+
"(default: stdout)."
161+
),
162+
)
163+
164+
#
165+
# Logging
166+
#
167+
168+
logging_group = parser.add_argument_group(
169+
"Logging"
170+
)
171+
172+
logging_group.add_argument(
173+
"--log-level",
174+
default="WARNING",
175+
choices=[
176+
"DEBUG",
177+
"INFO",
178+
"WARNING",
179+
"ERROR",
180+
"CRITICAL",
181+
],
182+
help="Console logging level.",
183+
)
184+
185+
#
186+
# Version
187+
#
188+
189+
parser.add_argument(
190+
"--version",
191+
action="version",
192+
version=(
193+
f"hgvs2reference "
194+
f"(VariantValidator {VariantValidator.__version__})"
195+
),
196+
)
197+
198+
return parser
199+
200+
# ----------------------------------------------------------------------
201+
# Output
202+
# ----------------------------------------------------------------------
203+
204+
205+
class Writer:
206+
"""
207+
Write HGVS2Reference results as JSON.
208+
"""
209+
210+
def __init__(
211+
self,
212+
handle,
213+
) -> None:
214+
215+
self.handle = handle
216+
217+
def write(
218+
self,
219+
result,
220+
) -> None:
221+
"""
222+
Write formatted JSON.
223+
"""
224+
225+
json.dump(
226+
result,
227+
self.handle,
228+
indent=2,
229+
sort_keys=True,
230+
ensure_ascii=False,
231+
)
232+
233+
self.handle.write("\n")
234+
235+
def close(self) -> None:
236+
"""
237+
Flush the output stream.
238+
"""
239+
240+
self.handle.flush()
241+
242+
243+
# ----------------------------------------------------------------------
244+
# Query execution
245+
# ----------------------------------------------------------------------
246+
247+
248+
def run_query(
249+
validator: VariantValidator.Validator,
250+
query: str,
251+
) -> dict:
252+
"""
253+
Execute a HGVS2Reference query.
254+
"""
255+
256+
LOGGER.info(
257+
"Initialising HGVS2Reference"
258+
)
259+
260+
LOGGER.info(
261+
"Processing %s",
262+
query,
263+
)
264+
265+
result = validator.hgvs2ref(
266+
query,
267+
)
268+
269+
LOGGER.info(
270+
"Query complete"
271+
)
272+
273+
return result
274+
275+
# ----------------------------------------------------------------------
276+
# Main
277+
# ----------------------------------------------------------------------
278+
279+
280+
def main() -> int:
281+
"""
282+
HGVS2Reference command-line entry point.
283+
"""
284+
285+
parser = build_parser()
286+
287+
args = parser.parse_args()
288+
289+
configure_logging(
290+
args.log_level,
291+
)
292+
293+
try:
294+
295+
validator = VariantValidator.Validator()
296+
297+
writer = Writer(
298+
args.output,
299+
)
300+
301+
result = run_query(
302+
validator=validator,
303+
query=args.query,
304+
)
305+
306+
writer.write(
307+
result,
308+
)
309+
310+
writer.close()
311+
312+
return EXIT_SUCCESS
313+
314+
except KeyboardInterrupt:
315+
316+
LOGGER.error(
317+
"Interrupted by user."
318+
)
319+
320+
return EXIT_UNEXPECTED_ERROR
321+
322+
except ValueError as exc:
323+
324+
LOGGER.error(
325+
"%s",
326+
exc,
327+
)
328+
329+
print(
330+
f"Error: {exc}",
331+
file=sys.stderr,
332+
)
333+
334+
return EXIT_INPUT_ERROR
335+
336+
except Exception:
337+
338+
LOGGER.exception(
339+
"HGVS2Reference failed."
340+
)
341+
342+
print(
343+
"Unexpected error. "
344+
"Run with --log-level DEBUG for additional information.",
345+
file=sys.stderr,
346+
)
347+
348+
return EXIT_UNEXPECTED_ERROR
349+
350+
351+
if __name__ == "__main__":
352+
raise SystemExit(main())
353+
354+
355+
# Copyright (C) 2016-2026 VariantValidator Contributors
356+
# This file is part of VariantValidator and is distributed under the
357+
# GNU Affero General Public License, version 3 or (at your option) any
358+
# later version. See the LICENSE file in the project root for the full
359+
# licence terms.
360+
# SPDX-License-Identifier: AGPL-3.0-or-later

0 commit comments

Comments
 (0)