scout-browser 4.98.0__py3-none-any.whl → 4.99.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- scout/adapter/mongo/institute.py +42 -55
- scout/adapter/mongo/variant.py +19 -15
- scout/adapter/mongo/variant_loader.py +11 -11
- scout/build/individual.py +2 -0
- scout/build/variant/variant.py +8 -0
- scout/commands/download/ensembl.py +18 -2
- scout/commands/update/individual.py +2 -0
- scout/commands/update/panelapp.py +15 -2
- scout/constants/__init__.py +6 -7
- scout/constants/clnsig.py +2 -0
- scout/constants/file_types.py +12 -0
- scout/constants/igv_tracks.py +8 -6
- scout/constants/panels.py +3 -0
- scout/constants/variant_tags.py +6 -6
- scout/demo/643594.config.yaml +1 -0
- scout/load/panelapp.py +11 -5
- scout/models/case/case_loading_models.py +4 -0
- scout/parse/variant/clnsig.py +38 -0
- scout/parse/variant/genotype.py +4 -10
- scout/parse/variant/models.py +5 -11
- scout/parse/variant/rank_score.py +5 -13
- scout/parse/variant/variant.py +90 -111
- scout/server/app.py +33 -22
- scout/server/blueprints/alignviewers/controllers.py +29 -10
- scout/server/blueprints/alignviewers/templates/alignviewers/igv_viewer.html +41 -11
- scout/server/blueprints/cases/templates/cases/utils.html +6 -6
- scout/server/blueprints/clinvar/controllers.py +29 -14
- scout/server/blueprints/clinvar/templates/clinvar/multistep_add_variant.html +13 -4
- scout/server/blueprints/clinvar/views.py +14 -2
- scout/server/blueprints/institutes/controllers.py +10 -2
- scout/server/blueprints/login/controllers.py +112 -12
- scout/server/blueprints/login/views.py +38 -60
- scout/server/blueprints/public/templates/public/index.html +5 -1
- scout/server/blueprints/variant/controllers.py +1 -1
- scout/server/blueprints/variant/templates/variant/acmg.html +6 -2
- scout/server/blueprints/variant/templates/variant/components.html +19 -0
- scout/server/blueprints/variant/templates/variant/utils.html +3 -3
- scout/server/blueprints/variants/controllers.py +10 -1
- scout/server/blueprints/variants/templates/variants/components.html +28 -0
- scout/server/blueprints/variants/templates/variants/mei-variants.html +8 -6
- scout/server/blueprints/variants/templates/variants/sv-variants.html +9 -7
- scout/server/blueprints/variants/templates/variants/utils.html +8 -12
- scout/server/blueprints/variants/templates/variants/variants.html +4 -25
- scout/server/config.py +8 -0
- scout/server/utils.py +22 -5
- scout/utils/acmg.py +25 -26
- scout/utils/ensembl_biomart_clients.py +1 -1
- scout/utils/ensembl_rest_clients.py +25 -32
- scout/utils/hgvs.py +1 -1
- {scout_browser-4.98.0.dist-info → scout_browser-4.99.0.dist-info}/METADATA +10 -14
- {scout_browser-4.98.0.dist-info → scout_browser-4.99.0.dist-info}/RECORD +54 -54
- {scout_browser-4.98.0.dist-info → scout_browser-4.99.0.dist-info}/WHEEL +0 -0
- {scout_browser-4.98.0.dist-info → scout_browser-4.99.0.dist-info}/entry_points.txt +0 -0
- {scout_browser-4.98.0.dist-info → scout_browser-4.99.0.dist-info}/licenses/LICENSE +0 -0
@@ -1,6 +1,6 @@
|
|
1
1
|
{% extends "layout.html" %}
|
2
2
|
{% from "variants/utils.html" import sv_filters, cell_rank, pagination_footer, pagination_hidden_div, dismiss_variants_block, filter_form_footer, filter_script_main, update_stash_filter_button_status, callers_cell %}
|
3
|
-
{% from "variants/components.html" import external_scripts, external_stylesheets, frequency_cell_general, observed_cell_general, variant_gene_symbols_cell, variant_funct_anno_cell %}
|
3
|
+
{% from "variants/components.html" import external_scripts, external_stylesheets, frequency_cell_general, observed_cell_general, overlapping_cell, variant_gene_symbols_cell, variant_funct_anno_cell %}
|
4
4
|
|
5
5
|
{% block title %}
|
6
6
|
{{ super() }} - {{ institute.display_name }} - {{ case.display_name }} - SV variants
|
@@ -57,18 +57,19 @@ onsubmit="return validateForm()">
|
|
57
57
|
<thead class="table-light thead">
|
58
58
|
<tr>
|
59
59
|
<th style="width:3%"></th>
|
60
|
-
<th>Rank</th>
|
61
|
-
<th>Score</th>
|
60
|
+
<th title="Rank position">Rank</th>
|
61
|
+
<th title="Rank score">Score</th>
|
62
62
|
<th>Callers</th>
|
63
63
|
<th>Type</th>
|
64
|
-
<th>Chr</th>
|
64
|
+
<th title="Chromosome">Chr</th>
|
65
65
|
<th>Start</th>
|
66
66
|
<th>End</th>
|
67
67
|
<th>Length</th>
|
68
|
-
<th>Pop Freq</th>
|
69
|
-
<th>Observed</th>
|
68
|
+
<th title="Population Frequency">Pop Freq</th>
|
69
|
+
<th title="Observed database matches">Observed</th>
|
70
70
|
<th>Gene(s)</th>
|
71
|
-
<th>Function</th>
|
71
|
+
<th title="Functional annotation">Function</th>
|
72
|
+
<th title="Gene overlapping variants">Overlap</th>
|
72
73
|
</tr>
|
73
74
|
</thead>
|
74
75
|
<tbody>
|
@@ -121,6 +122,7 @@ onsubmit="return validateForm()">
|
|
121
122
|
<td style="word-wrap:break-word;">
|
122
123
|
{{ variant_funct_anno_cell(variant) }}
|
123
124
|
</td>
|
125
|
+
<td>{{ overlapping_cell(variant, institute, case) }}</td>
|
124
126
|
</tr>
|
125
127
|
{% endmacro %}
|
126
128
|
|
@@ -1,5 +1,6 @@
|
|
1
1
|
{% import "bootstrap/wtf.html" as wtf %}
|
2
2
|
{% from "utils.html" import comments_table %}
|
3
|
+
{% from "cases/utils.html" import pretty_link_variant %}
|
3
4
|
{% from "variants/indicators.html" import pin_indicator, causative_badge, clinical_assessments_badge, comments_badge, dismissals_badge, evaluations_badge, group_assessments_badge, matching_manual_rank, research_assessments_badge %}
|
4
5
|
|
5
6
|
{% macro filter_script_main(cytobands) %}
|
@@ -225,30 +226,25 @@
|
|
225
226
|
</table>
|
226
227
|
{% endmacro %}
|
227
228
|
|
228
|
-
{% macro
|
229
|
+
{% macro overlapping_tooltip_table(institute, case, overlapping) %}
|
229
230
|
<table class='table table-bordered table-hover table-condensed'>
|
230
231
|
<thead>
|
231
232
|
<tr>
|
232
|
-
<th>
|
233
|
+
<th>Pos</th>
|
233
234
|
<th>Type</th>
|
234
235
|
<th>Length</th>
|
235
236
|
<th>Rank score</th>
|
236
237
|
</tr>
|
237
238
|
</thead>
|
238
239
|
<tbody>
|
239
|
-
{% for
|
240
|
+
{% for variant in overlapping %}
|
240
241
|
<tr>
|
241
242
|
<td>
|
242
|
-
|
243
|
-
institute_id=institute._id,
|
244
|
-
case_name=case.display_name,
|
245
|
-
variant_id=sv._id) }}'>
|
246
|
-
{{ sv.chromosome }}{{ sv.cytoband_start }}
|
247
|
-
</a>
|
243
|
+
{{ pretty_link_variant(variant, case) }}
|
248
244
|
</td>
|
249
|
-
<td class='text-end'>{{
|
250
|
-
<td class='text-end'>{{
|
251
|
-
<td class='text-end'>{{
|
245
|
+
<td class='text-end'>{{ variant.sub_category }}</td>
|
246
|
+
<td class='text-end'>{{ variant.length if variant.length < 100000000000 else '-' }}</td>
|
247
|
+
<td class='text-end'>{{ variant.rank_score }}</td>
|
252
248
|
</tr>
|
253
249
|
{% endfor %}
|
254
250
|
</tbody>
|
@@ -1,6 +1,6 @@
|
|
1
1
|
{% extends "layout.html" %}
|
2
|
-
{% from "variants/utils.html" import
|
3
|
-
{% from "variants/components.html" import external_scripts, external_stylesheets, frequency_cell_general, gene_cell, observed_cell_general %}
|
2
|
+
{% from "variants/utils.html" import snv_filters, cell_rank, pagination_footer, pagination_hidden_div, dismiss_variants_block, filter_form_footer, filter_script_main, update_stash_filter_button_status, mark_heteroplasmic_mt %}
|
3
|
+
{% from "variants/components.html" import external_scripts, external_stylesheets, frequency_cell_general, gene_cell, observed_cell_general, overlapping_cell %}
|
4
4
|
|
5
5
|
{% block title %}
|
6
6
|
{{ super() }} - {{ institute.display_name }} - {{ case.display_name }} - {{ form.variant_type.data|capitalize }} variants
|
@@ -59,7 +59,7 @@
|
|
59
59
|
<th style="width:5%" title="Rank score">Score</th>
|
60
60
|
<th style="width:4%" title="Chromosome">Chr.</th>
|
61
61
|
<th style="width:12%" title="HGNC symbols">Gene</th>
|
62
|
-
<th style="width:6%" title="
|
62
|
+
<th style="width:6%" title="Population Frequency">Pop Freq</th>
|
63
63
|
<th style="width:10%" title="Observed database matches">Observed</th>
|
64
64
|
<th style="width:5%" title="CADD score">CADD</th>
|
65
65
|
<th style="width:18%" title="Functional annotation">Function</th>
|
@@ -93,7 +93,7 @@
|
|
93
93
|
{{ functional_annotation_cell(variant) }}
|
94
94
|
</td>
|
95
95
|
<td>{{ cell_models(variant) }}</td>
|
96
|
-
<td>{{ overlapping_cell(variant) }}</td>
|
96
|
+
<td>{{ overlapping_cell(variant, institute, case) }}</td>
|
97
97
|
</tr>
|
98
98
|
{% else %}
|
99
99
|
<tr>
|
@@ -159,27 +159,6 @@
|
|
159
159
|
{% endif %}
|
160
160
|
{% endmacro %}
|
161
161
|
|
162
|
-
{% macro overlapping_cell(variant) %}
|
163
|
-
|
164
|
-
{% if variant.compounds %}
|
165
|
-
{% set ns=namespace(show_compounds=false) %}
|
166
|
-
{% for compound in variant.compounds if not compound.is_dismissed %}
|
167
|
-
{% set ns.show_compounds = true %}
|
168
|
-
{% endfor %}
|
169
|
-
{% if ns.show_compounds %}
|
170
|
-
<a href="#" class="badge bg-primary text-white" data-bs-toggle="popover" data-bs-placement="left"
|
171
|
-
data-bs-html="true" data-bs-trigger="hover click"
|
172
|
-
data-bs-content="{{ compounds_table(institute, case, variant.compounds[:20], is_popover=true) }}">Compounds</a>
|
173
|
-
{% endif %}
|
174
|
-
{% endif %}
|
175
|
-
|
176
|
-
{% if variant.overlapping %}
|
177
|
-
<a href="#" class="badge bg-warning" data-bs-toggle="popover" data-bs-placement="left"
|
178
|
-
data-bs-html="true" data-bs-trigger="hover click"
|
179
|
-
data-bs-content="{{ svs_table(institute, case, variant.overlapping[:20]) }}">Overlapping SVs</a>
|
180
|
-
{% endif %}
|
181
|
-
{% endmacro %}
|
182
|
-
|
183
162
|
{% block scripts %}
|
184
163
|
{{ super() }}
|
185
164
|
{{ external_scripts() }}
|
scout/server/config.py
CHANGED
@@ -38,6 +38,14 @@ ACCREDITATION_BADGE = "swedac-1926-iso17025.png"
|
|
38
38
|
# discovery_url="https://accounts.google.com/.well-known/openid-configuration",
|
39
39
|
# )
|
40
40
|
|
41
|
+
# Parameters required for login with Keycloak
|
42
|
+
# KEYCLOAK = dict(
|
43
|
+
# client_id="<name_of_client>",
|
44
|
+
# client_secret="secret",
|
45
|
+
# discovery_url="http://localhost:8080/realms/<name_of_realm>/.well-known/openid-configuration",
|
46
|
+
# logout_url="http://localhost:8080/realms/<name_of_realm>/protocol/openid-connect/logout",
|
47
|
+
# )
|
48
|
+
|
41
49
|
# Chanjo database connection string - used by chanjo report to create coverage reports
|
42
50
|
# SQLALCHEMY_DATABASE_URI = "mysql+pymysql://test_user:test_passwordw@127.0.0.1:3306/chanjo"
|
43
51
|
|
scout/server/utils.py
CHANGED
@@ -244,15 +244,23 @@ def case_has_chanjo2_coverage(case_obj: dict):
|
|
244
244
|
def case_has_alignments(case_obj: dict):
|
245
245
|
"""Add info on bam/cram files availability to a case dictionary
|
246
246
|
|
247
|
+
This sets the availability of alignments for autosomal chromosomes.
|
248
|
+
If paraphase or de novo assembly alignments, this is also sufficient to set
|
249
|
+
alignment availability.
|
247
250
|
Args:
|
248
251
|
case_obj(scout.models.Case)
|
249
252
|
"""
|
250
|
-
case_obj["bam_files"] = False
|
253
|
+
case_obj["bam_files"] = False
|
251
254
|
for ind in case_obj.get("individuals"):
|
252
|
-
|
253
|
-
|
254
|
-
|
255
|
-
|
255
|
+
for alignment_path_key in [
|
256
|
+
"bam_file",
|
257
|
+
"assembly_alignment_path",
|
258
|
+
"paraphase_alignment_path",
|
259
|
+
]:
|
260
|
+
bam_path = ind.get(alignment_path_key)
|
261
|
+
if bam_path and os.path.exists(bam_path):
|
262
|
+
case_obj["bam_files"] = True
|
263
|
+
return
|
256
264
|
|
257
265
|
|
258
266
|
def case_has_mt_alignments(case_obj: dict):
|
@@ -301,10 +309,19 @@ def case_append_alignments(case_obj: dict):
|
|
301
309
|
"""Deconvolute information about files to case_obj.
|
302
310
|
|
303
311
|
This function prepares bam/cram files and their indexes for easy access in templates.
|
312
|
+
|
313
|
+
index is set only if it is expected as a separate key on the indiviudal: an
|
314
|
+
attempt at discovery is still made for files with index: None.
|
304
315
|
"""
|
305
316
|
unwrap_settings = [
|
306
317
|
{"path": "bam_file", "append_to": "bam_files", "index": "bai_files"},
|
318
|
+
{"path": "assembly_alignment_path", "append_to": "assembly_alignments", "index": None},
|
307
319
|
{"path": "mt_bam", "append_to": "mt_bams", "index": "mt_bais"},
|
320
|
+
{
|
321
|
+
"path": "paraphase_alignment_path",
|
322
|
+
"append_to": "paraphase_alignments",
|
323
|
+
"index": None,
|
324
|
+
},
|
308
325
|
{"path": "rhocall_bed", "append_to": "rhocall_beds", "index": None},
|
309
326
|
{"path": "rhocall_wig", "append_to": "rhocall_wigs", "index": None},
|
310
327
|
{"path": "upd_regions_bed", "append_to": "upd_regions_beds", "index": None},
|
scout/utils/acmg.py
CHANGED
@@ -173,7 +173,7 @@ def get_acmg_criteria(acmg_terms: set) -> tuple:
|
|
173
173
|
finally, check remaining prefixes if no suffix match or stand-alone criteria match
|
174
174
|
|
175
175
|
Return a tuple with
|
176
|
-
|
176
|
+
pvs_terms: This variable indicates if Pathogenicity Very Strong exists
|
177
177
|
ps_terms: Collection of terms with Pathogenicity Strong
|
178
178
|
pm_terms: Collection of terms with Pathogenicity moderate
|
179
179
|
pp_terms: Collection of terms with Pathogenicity supporting
|
@@ -182,25 +182,29 @@ def get_acmg_criteria(acmg_terms: set) -> tuple:
|
|
182
182
|
bp_terms: Collection of terms with supporting Benign evidence
|
183
183
|
"""
|
184
184
|
|
185
|
-
|
185
|
+
pvs_terms = []
|
186
186
|
ps_terms = []
|
187
187
|
pm_terms = []
|
188
188
|
pp_terms = []
|
189
189
|
|
190
|
-
|
190
|
+
ba_terms = []
|
191
191
|
bs_terms = []
|
192
192
|
bp_terms = []
|
193
193
|
|
194
194
|
suffix_map = {
|
195
|
+
"_Stand-alone": {"B": ba_terms},
|
196
|
+
"_Very Strong": {"P": pvs_terms},
|
195
197
|
"_Strong": {"P": ps_terms, "B": bs_terms},
|
196
198
|
"_Moderate": {"P": pm_terms},
|
197
199
|
"_Supporting": {"P": pp_terms, "B": bp_terms},
|
198
200
|
}
|
199
201
|
|
200
202
|
prefix_map = {
|
203
|
+
"PVS": pvs_terms,
|
201
204
|
"PS": ps_terms,
|
202
205
|
"PM": pm_terms,
|
203
206
|
"PP": pp_terms,
|
207
|
+
"BA": ba_terms,
|
204
208
|
"BS": bs_terms,
|
205
209
|
"BP": bp_terms,
|
206
210
|
}
|
@@ -216,17 +220,12 @@ def get_acmg_criteria(acmg_terms: set) -> tuple:
|
|
216
220
|
continue
|
217
221
|
break
|
218
222
|
else:
|
219
|
-
|
220
|
-
|
221
|
-
|
222
|
-
|
223
|
-
else:
|
224
|
-
for prefix, term_list in prefix_map.items():
|
225
|
-
if term.startswith(prefix):
|
226
|
-
term_list.append(term)
|
227
|
-
break
|
223
|
+
for prefix, term_list in prefix_map.items():
|
224
|
+
if term.startswith(prefix):
|
225
|
+
term_list.append(term)
|
226
|
+
break
|
228
227
|
|
229
|
-
return (
|
228
|
+
return (pvs_terms, ps_terms, pm_terms, pp_terms, ba_terms, bs_terms, bp_terms)
|
230
229
|
|
231
230
|
|
232
231
|
def get_acmg(acmg_terms: set) -> Optional[str]:
|
@@ -316,19 +315,19 @@ def get_acmg_temperature(acmg_terms: set) -> Optional[dict]:
|
|
316
315
|
if not acmg_terms:
|
317
316
|
return {}
|
318
317
|
|
319
|
-
(
|
320
|
-
|
321
|
-
|
322
|
-
|
323
|
-
|
324
|
-
|
325
|
-
|
326
|
-
|
327
|
-
|
328
|
-
|
329
|
-
|
330
|
-
|
331
|
-
|
318
|
+
(pvs_terms, ps_terms, pm_terms, pp_terms, ba_terms, bs_terms, bp_terms) = get_acmg_criteria(
|
319
|
+
acmg_terms
|
320
|
+
)
|
321
|
+
|
322
|
+
points = (
|
323
|
+
8 * len(pvs_terms)
|
324
|
+
+ 4 * len(ps_terms)
|
325
|
+
+ 2 * len(pm_terms)
|
326
|
+
+ len(pp_terms)
|
327
|
+
- 8 * len(ba_terms)
|
328
|
+
- 4 * len(bs_terms)
|
329
|
+
- len(bp_terms)
|
330
|
+
)
|
332
331
|
|
333
332
|
if points <= -7:
|
334
333
|
point_classification = "benign"
|
@@ -1,30 +1,27 @@
|
|
1
1
|
"""Code for talking to ensembl rest API"""
|
2
2
|
|
3
3
|
import logging
|
4
|
+
from typing import Optional
|
4
5
|
from urllib.parse import urlencode
|
5
6
|
|
6
7
|
import requests
|
8
|
+
from flask import flash
|
7
9
|
|
8
10
|
LOG = logging.getLogger(__name__)
|
9
11
|
|
10
12
|
HEADERS = {"Content-type": "application/json"}
|
11
|
-
|
12
|
-
RESTAPI_38 = "https://rest.ensembl.org"
|
13
|
+
RESTAPI_URL = "https://rest.ensembl.org"
|
13
14
|
|
14
15
|
|
15
16
|
class EnsemblRestApiClient:
|
16
17
|
"""A class handling requests and responses to and from the Ensembl REST APIs.
|
17
|
-
|
18
|
-
Endpoints for human build 38: http://rest.ensembl.org/
|
18
|
+
Endpoint: http://rest.ensembl.org/
|
19
19
|
Documentation: https://github.com/Ensembl/ensembl-rest/wiki
|
20
20
|
doi:10.1093/bioinformatics/btu613
|
21
21
|
"""
|
22
22
|
|
23
|
-
def __init__(self
|
24
|
-
|
25
|
-
self.server = RESTAPI_38
|
26
|
-
else:
|
27
|
-
self.server = RESTAPI_37
|
23
|
+
def __init__(self):
|
24
|
+
self.server = RESTAPI_URL
|
28
25
|
|
29
26
|
def build_url(self, endpoint, params=None):
|
30
27
|
"""Build an url to query ensembml"""
|
@@ -34,7 +31,7 @@ class EnsemblRestApiClient:
|
|
34
31
|
return "".join([self.server, endpoint])
|
35
32
|
|
36
33
|
@staticmethod
|
37
|
-
def send_request(url):
|
34
|
+
def send_request(url) -> Optional[dict]:
|
38
35
|
"""Sends the actual request to the server and returns the response
|
39
36
|
|
40
37
|
Accepts:
|
@@ -43,33 +40,29 @@ class EnsemblRestApiClient:
|
|
43
40
|
Returns:
|
44
41
|
data(dict): dictionary from json response
|
45
42
|
"""
|
46
|
-
|
43
|
+
error = None
|
44
|
+
data = None
|
47
45
|
try:
|
48
46
|
response = requests.get(url, headers=HEADERS)
|
49
|
-
if response.status_code
|
50
|
-
|
51
|
-
response.
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
except requests.exceptions.HTTPError
|
57
|
-
|
58
|
-
|
47
|
+
if response.status_code not in [404, 500]:
|
48
|
+
|
49
|
+
data = response.json()
|
50
|
+
else:
|
51
|
+
error = f"Ensembl request failed with code:{response.status_code} for url {url}"
|
52
|
+
except requests.exceptions.MissingSchema:
|
53
|
+
error = f"Ensembl request failed with MissingSchema error for url {url}"
|
54
|
+
except requests.exceptions.HTTPError:
|
55
|
+
error = f"Ensembl request failed with HTTPError error for url {url}"
|
56
|
+
|
57
|
+
if error:
|
58
|
+
flash(error)
|
59
59
|
return data
|
60
60
|
|
61
|
-
def liftover(
|
61
|
+
def liftover(
|
62
|
+
self, build: str, chrom: str, start: int, end: Optional[int] = None
|
63
|
+
) -> Optional[dict]:
|
62
64
|
"""Perform variant liftover using Ensembl REST API
|
63
|
-
|
64
|
-
Args:
|
65
|
-
build(str): genome build: "37" or "38"
|
66
|
-
chrom(str): 1-22,X,Y,MT,M
|
67
|
-
start(int): start coordinate
|
68
|
-
stop(int): stop coordinate or None
|
69
|
-
|
70
|
-
Returns:
|
71
|
-
mappings(list of dict): example:
|
72
|
-
example: https://rest.ensembl.org/map/human/GRCh37/X:1000000..1000100:1/GRCh38?content-type=application/json
|
65
|
+
example: https://rest.ensembl.org/map/human/GRCh37/X:1000000..1000100:1/GRCh38?content-type=application/json
|
73
66
|
"""
|
74
67
|
|
75
68
|
build = "GRCh38" if "38" in str(build) else "GRCh37"
|
scout/utils/hgvs.py
CHANGED
@@ -6,7 +6,7 @@ LOG = logging.getLogger(__name__)
|
|
6
6
|
VALIDATOR_URL = "https://rest.variantvalidator.org/VariantValidator/variantvalidator/{}/{}/select?content-type=application%2Fjson"
|
7
7
|
|
8
8
|
|
9
|
-
def validate_hgvs(build, desc):
|
9
|
+
def validate_hgvs(build: str, desc: str) -> bool:
|
10
10
|
"""Validates a simple hgvs descriptor using the VariantValidator API (https://rest.variantvalidator.org/)
|
11
11
|
|
12
12
|
Args:
|
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.4
|
2
2
|
Name: scout-browser
|
3
|
-
Version: 4.
|
3
|
+
Version: 4.99.0
|
4
4
|
Summary: Clinical DNA variant visualizer and browser
|
5
5
|
Project-URL: Repository, https://github.com/Clinical-Genomics/scout
|
6
6
|
Project-URL: Changelog, https://github.com/Clinical-Genomics/scout/blob/main/CHANGELOG.md
|
@@ -124,29 +124,25 @@ Instructions on how to run a Scout image connected to your local database or a c
|
|
124
124
|
|
125
125
|
## Installation
|
126
126
|
|
127
|
-
|
128
|
-
|
129
|
-
```bash
|
130
|
-
pip install scout-browser
|
131
|
-
|
132
|
-
# ... to include optional coverage tools you would use:
|
133
|
-
pip install scout-browser[coverage]
|
134
|
-
```
|
135
|
-
|
136
|
-
If you would like to install Scout for local development: -->
|
127
|
+
Here is a quick start. Please see e.g. the [Installation instructions](docs/install.md) for more details.
|
137
128
|
|
138
129
|
```bash
|
139
130
|
git clone https://github.com/Clinical-Genomics/scout
|
140
131
|
cd scout
|
141
|
-
pip install --editable .
|
142
132
|
```
|
143
133
|
|
144
|
-
Scout is configured to use `uv
|
145
|
-
|
134
|
+
Scout is configured to use `uv`; either run, install, or install as a tool.
|
135
|
+
|
136
|
+
```bash
|
146
137
|
uv sync --frozen
|
147
138
|
uv run scout
|
148
139
|
```
|
149
140
|
|
141
|
+
You can also install using pip:
|
142
|
+
|
143
|
+
```
|
144
|
+
pip install --editable .
|
145
|
+
```
|
150
146
|
|
151
147
|
Scout PDF reports are created using [Flask-WeasyPrint](https://pythonhosted.org/Flask-WeasyPrint/). This library requires external dependencies which need be installed separately (namely Cairo and Pango). See platform-specific instructions for Linux, macOS and Windows available on the WeasyPrint installation [pages](https://doc.courtbouillon.org/weasyprint/stable/first_steps.html#installation).
|
152
148
|
|