scout-browser 4.100.2__py3-none-any.whl → 4.102.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/case.py +20 -6
- scout/adapter/mongo/clinvar.py +7 -7
- scout/adapter/mongo/hgnc.py +7 -2
- scout/adapter/mongo/omics_variant.py +8 -0
- scout/adapter/mongo/variant_loader.py +6 -2
- scout/constants/__init__.py +1 -0
- scout/constants/file_types.py +1 -1
- scout/constants/igv_tracks.py +6 -2
- scout/constants/phenotype.py +1 -0
- scout/load/hpo.py +8 -2
- scout/server/blueprints/alignviewers/controllers.py +8 -6
- scout/server/blueprints/alignviewers/templates/alignviewers/igv_viewer.html +2 -0
- scout/server/blueprints/alignviewers/templates/alignviewers/utils.html +1 -1
- scout/server/blueprints/cases/controllers.py +56 -28
- scout/server/blueprints/cases/templates/cases/case_report.html +9 -88
- scout/server/blueprints/cases/templates/cases/matchmaker.html +1 -1
- scout/server/blueprints/cases/templates/cases/phenotype.html +1 -1
- scout/server/blueprints/cases/templates/cases/utils.html +27 -25
- scout/server/blueprints/cases/views.py +32 -33
- scout/server/blueprints/clinvar/controllers.py +18 -23
- scout/server/blueprints/clinvar/templates/clinvar/multistep_add_variant.html +0 -2
- scout/server/blueprints/diagnoses/controllers.py +4 -8
- scout/server/blueprints/diagnoses/templates/diagnoses/diagnoses.html +1 -1
- scout/server/blueprints/diagnoses/templates/diagnoses/disease_term.html +1 -1
- scout/server/blueprints/diagnoses/views.py +2 -2
- scout/server/blueprints/institutes/controllers.py +107 -73
- scout/server/blueprints/institutes/templates/overview/cases.html +8 -7
- scout/server/blueprints/login/controllers.py +2 -1
- scout/server/blueprints/login/views.py +5 -2
- scout/server/blueprints/omics_variants/views.py +2 -2
- scout/server/blueprints/panels/views.py +11 -2
- scout/server/blueprints/phenotypes/controllers.py +15 -2
- scout/server/blueprints/phenotypes/templates/phenotypes/hpo_terms.html +1 -1
- scout/server/blueprints/variant/controllers.py +10 -11
- scout/server/blueprints/variant/templates/variant/utils.html +1 -1
- scout/server/blueprints/variant/templates/variant/variant_details.html +68 -60
- scout/server/blueprints/variant/utils.py +25 -0
- scout/server/blueprints/variants/controllers.py +11 -42
- scout/server/blueprints/variants/templates/variants/cancer-variants.html +3 -3
- scout/server/blueprints/variants/templates/variants/indicators.html +18 -15
- scout/server/blueprints/variants/templates/variants/utils.html +1 -1
- scout/server/blueprints/variants/views.py +9 -8
- scout/server/config.py +3 -0
- scout/server/extensions/beacon_extension.py +7 -2
- scout/server/templates/bootstrap_global.html +11 -1
- scout/server/templates/layout.html +6 -1
- scout/server/utils.py +24 -3
- {scout_browser-4.100.2.dist-info → scout_browser-4.102.0.dist-info}/METADATA +1 -1
- {scout_browser-4.100.2.dist-info → scout_browser-4.102.0.dist-info}/RECORD +52 -52
- {scout_browser-4.100.2.dist-info → scout_browser-4.102.0.dist-info}/WHEEL +0 -0
- {scout_browser-4.100.2.dist-info → scout_browser-4.102.0.dist-info}/entry_points.txt +0 -0
- {scout_browser-4.100.2.dist-info → scout_browser-4.102.0.dist-info}/licenses/LICENSE +0 -0
@@ -1,4 +1,5 @@
|
|
1
1
|
import logging
|
2
|
+
import re
|
2
3
|
from typing import Dict, List, Optional, Tuple
|
3
4
|
|
4
5
|
from scout.adapter import MongoAdapter
|
@@ -683,3 +684,27 @@ def associate_variant_genes_with_case_panels(case_obj: Dict, variant_obj: Dict)
|
|
683
684
|
geneid_gene[hgnc_id]["associated_gene_panels"] = matching_panels
|
684
685
|
|
685
686
|
variant_obj["genes"] = list(geneid_gene.values())
|
687
|
+
|
688
|
+
|
689
|
+
def get_str_mc(variant_obj: dict) -> Optional[int]:
|
690
|
+
"""Return variant Short Tandem Repeat motif count, either as given by its ALT MC value
|
691
|
+
from the variant FORMAT field, or as a number given in the ALT on the form
|
692
|
+
'<STR123>'.
|
693
|
+
"""
|
694
|
+
NUM = re.compile(r"\d+")
|
695
|
+
|
696
|
+
alt_mc = None
|
697
|
+
if variant_obj["alternative"] == ".":
|
698
|
+
return alt_mc
|
699
|
+
|
700
|
+
for sample in variant_obj["samples"]:
|
701
|
+
if sample["genotype_call"] in ["./.", ".|", "0/0", "0|0"]:
|
702
|
+
continue
|
703
|
+
alt_mc = sample.get("alt_mc")
|
704
|
+
if alt_mc:
|
705
|
+
return alt_mc
|
706
|
+
|
707
|
+
alt_num = NUM.search(variant_obj["alternative"])
|
708
|
+
if alt_num:
|
709
|
+
alt_mc = int(alt_num.group())
|
710
|
+
return alt_mc
|
@@ -35,6 +35,7 @@ from scout.server.blueprints.variant.utils import (
|
|
35
35
|
clinsig_human,
|
36
36
|
get_callers,
|
37
37
|
get_filters,
|
38
|
+
get_str_mc,
|
38
39
|
predictions,
|
39
40
|
update_representative_gene,
|
40
41
|
update_variant_case_panels,
|
@@ -45,6 +46,7 @@ from scout.server.links import add_gene_links, cosmic_links, str_source_link
|
|
45
46
|
from scout.server.utils import (
|
46
47
|
case_has_alignments,
|
47
48
|
case_has_mt_alignments,
|
49
|
+
get_case_genome_build,
|
48
50
|
institute_and_case,
|
49
51
|
user_institutes,
|
50
52
|
)
|
@@ -57,8 +59,6 @@ from .forms import (
|
|
57
59
|
)
|
58
60
|
from .utils import update_case_panels
|
59
61
|
|
60
|
-
NUM = re.compile(r"\d+")
|
61
|
-
|
62
62
|
LOG = logging.getLogger(__name__)
|
63
63
|
|
64
64
|
|
@@ -106,7 +106,7 @@ def populate_persistent_filters_choices(
|
|
106
106
|
def populate_chrom_choices(form, case_obj):
|
107
107
|
"""Populate the option of the chromosome select according to the case genome build"""
|
108
108
|
# Populate chromosome choices
|
109
|
-
chromosomes = CHROMOSOMES if
|
109
|
+
chromosomes = CHROMOSOMES if get_case_genome_build(case_obj) == "37" else CHROMOSOMES_38
|
110
110
|
form.chrom.choices = [(chrom, chrom) for chrom in chromosomes]
|
111
111
|
|
112
112
|
|
@@ -139,9 +139,7 @@ def variants(
|
|
139
139
|
more_variants = variant_count > (skip_count + per_page)
|
140
140
|
variant_res = variants_query.skip(skip_count).limit(per_page)
|
141
141
|
|
142
|
-
genome_build =
|
143
|
-
if genome_build not in ["37", "38"]:
|
144
|
-
genome_build = "37"
|
142
|
+
genome_build = get_case_genome_build(case_obj)
|
145
143
|
|
146
144
|
case_dismissed_vars = store.case_dismissed_variants(institute_obj, case_obj)
|
147
145
|
|
@@ -237,9 +235,7 @@ def sv_variants(store, institute_obj, case_obj, variants_query, variant_count, p
|
|
237
235
|
|
238
236
|
more_variants = variant_count > (skip_count + per_page)
|
239
237
|
variants = []
|
240
|
-
genome_build =
|
241
|
-
if genome_build not in ["37", "38"]:
|
242
|
-
genome_build = "37"
|
238
|
+
genome_build = get_case_genome_build(case_obj)
|
243
239
|
|
244
240
|
case_dismissed_vars = store.case_dismissed_variants(institute_obj, case_obj)
|
245
241
|
|
@@ -285,9 +281,7 @@ def mei_variants(
|
|
285
281
|
|
286
282
|
more_variants = variant_count > (skip_count + per_page)
|
287
283
|
variants = []
|
288
|
-
genome_build =
|
289
|
-
if genome_build not in ["37", "38"]:
|
290
|
-
genome_build = "37"
|
284
|
+
genome_build = get_case_genome_build(case_obj)
|
291
285
|
|
292
286
|
case_dismissed_vars = store.case_dismissed_variants(institute_obj, case_obj)
|
293
287
|
|
@@ -353,9 +347,7 @@ def fusion_variants(
|
|
353
347
|
|
354
348
|
more_variants = variant_count > (skip_count + per_page)
|
355
349
|
variants = []
|
356
|
-
genome_build =
|
357
|
-
if genome_build not in ["37", "38"]:
|
358
|
-
genome_build = "38"
|
350
|
+
genome_build = get_case_genome_build(case_obj)
|
359
351
|
|
360
352
|
case_dismissed_vars = store.case_dismissed_variants(institute_obj, case_obj)
|
361
353
|
|
@@ -997,28 +989,6 @@ def parse_variant(
|
|
997
989
|
return variant_obj
|
998
990
|
|
999
991
|
|
1000
|
-
def get_str_mc(variant_obj: dict) -> Optional[int]:
|
1001
|
-
"""Return variant Short Tandem Repeat motif count, either as given by its ALT MC value
|
1002
|
-
from the variant FORMAT field, or as a number given in the ALT on the form
|
1003
|
-
'<STR123>'.
|
1004
|
-
"""
|
1005
|
-
alt_mc = None
|
1006
|
-
if variant_obj["alternative"] == ".":
|
1007
|
-
return alt_mc
|
1008
|
-
|
1009
|
-
for sample in variant_obj["samples"]:
|
1010
|
-
if sample["genotype_call"] in ["./.", ".|", "0/0", "0|0"]:
|
1011
|
-
continue
|
1012
|
-
alt_mc = sample.get("alt_mc")
|
1013
|
-
if alt_mc:
|
1014
|
-
return alt_mc
|
1015
|
-
|
1016
|
-
alt_num = NUM.search(variant_obj["alternative"])
|
1017
|
-
if alt_num:
|
1018
|
-
alt_mc = int(alt_num.group())
|
1019
|
-
return alt_mc
|
1020
|
-
|
1021
|
-
|
1022
992
|
def download_str_variants(case_obj, variant_objs):
|
1023
993
|
"""Download filtered STR variants for a case to a CSV file
|
1024
994
|
|
@@ -1502,7 +1472,9 @@ def upload_panel(store, institute_id, case_name, stream):
|
|
1502
1472
|
hgnc_symbols = set()
|
1503
1473
|
for raw_symbol in raw_symbols:
|
1504
1474
|
matching_genes = list(
|
1505
|
-
store.gene_by_symbol_or_aliases(
|
1475
|
+
store.gene_by_symbol_or_aliases(
|
1476
|
+
symbol=raw_symbol, build=get_case_genome_build(case_obj)
|
1477
|
+
)
|
1506
1478
|
)
|
1507
1479
|
if not matching_genes:
|
1508
1480
|
flash("HGNC symbol not found: {}".format(raw_symbol), "warning")
|
@@ -1983,10 +1955,7 @@ def update_form_hgnc_symbols(store, case_obj, form):
|
|
1983
1955
|
genome_build = None
|
1984
1956
|
case_obj = case_obj or {}
|
1985
1957
|
|
1986
|
-
|
1987
|
-
if build in str(case_obj.get("genome_build", "")):
|
1988
|
-
genome_build = build
|
1989
|
-
break
|
1958
|
+
genome_build = get_case_genome_build(case_obj)
|
1990
1959
|
|
1991
1960
|
# retrieve current symbols from form
|
1992
1961
|
if form.hgnc_symbols.data:
|
@@ -2,7 +2,7 @@
|
|
2
2
|
|
3
3
|
{% from "variants/components.html" import allele_cell, external_scripts, external_stylesheets, gene_cell, frequency_cell_general, observed_cell_general, variant_funct_anno_cell %}
|
4
4
|
{% from "variants/utils.html" import cancer_filters, cell_rank, pagination_footer, pagination_hidden_div, dismiss_variants_block, filter_form_footer, filter_script_main, update_stash_filter_button_status, callers_cell %}
|
5
|
-
{% from "variants/indicators.html" import pin_indicator, causative_badge, clinical_assessments_badge, comments_badge, dismissals_badge, evaluations_badge,
|
5
|
+
{% from "variants/indicators.html" import pin_indicator, causative_badge, clinical_assessments_badge, comments_badge, dismissals_badge, evaluations_badge, group_assessments_badge, matching_manual_rank, other_tiered_variants, research_assessments_badge %}
|
6
6
|
|
7
7
|
{% block title %}
|
8
8
|
{{ variant_type|capitalize }} somatic variants
|
@@ -101,7 +101,7 @@
|
|
101
101
|
</a>
|
102
102
|
</td>
|
103
103
|
<td>
|
104
|
-
{{ evaluations_badge(variant) }}
|
104
|
+
{{ evaluations_badge(variant.evaluations) }}
|
105
105
|
{{ dismissals_badge(variant) }}
|
106
106
|
{{ matching_manual_rank(variant) }}
|
107
107
|
{{ research_assessments_badge(variant) }}
|
@@ -110,7 +110,7 @@
|
|
110
110
|
{{ comments_badge(case, institute, variant) }}
|
111
111
|
{{ causative_badge(variant, case) }}
|
112
112
|
{{ other_tiered_variants(variant) }}
|
113
|
-
{{
|
113
|
+
{{ evaluations_badge(variant.ccv_evaluations) }}
|
114
114
|
</td>
|
115
115
|
<td>{{ rank_cell(variant) }}</td>
|
116
116
|
<td>{{ cadd_cell(variant) }}</td>
|
@@ -61,23 +61,26 @@
|
|
61
61
|
{% endif %}
|
62
62
|
{% endmacro %}
|
63
63
|
|
64
|
-
{% macro evaluations_badge(
|
65
|
-
{% if
|
66
|
-
{%
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
64
|
+
{% macro evaluations_badge(evaluations) %}
|
65
|
+
{% if evaluations %}
|
66
|
+
{% set classification_counts = {} %}
|
67
|
+
{% for evaluation in evaluations %}
|
68
|
+
{% set c = evaluation.classification if evaluation.classification is defined else evaluation.ccv_classification %}
|
69
|
+
{% if c %}
|
70
|
+
{% set short = c.short %}
|
71
|
+
{% set label = c.label %}
|
72
|
+
{% set current = classification_counts.get(short, {'count': 0, 'label': label}) %}
|
73
|
+
{% set _ = classification_counts.update({short: {
|
74
|
+
'count': current.count + 1,
|
75
|
+
'label': label
|
76
|
+
}}) %}
|
77
|
+
{% endif %}
|
71
78
|
{% endfor %}
|
72
|
-
{% endif %}
|
73
|
-
{% endmacro %}
|
74
79
|
|
75
|
-
{%
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
title="Previously classified as {{ evaluation.ccv_classification.label }}">
|
80
|
-
{{ evaluation.ccv_classification.short }}
|
80
|
+
{% for short, data in classification_counts.items() | sort(attribute='1.count', reverse=true) %}
|
81
|
+
<span class="badge bg-secondary ms-1" data-bs-toggle="tooltip" data-bs-placement="right"
|
82
|
+
title="Previously classified as {{ data.label }} ({{ data.count }} times)">
|
83
|
+
{{ short }} ×{{ data.count }}
|
81
84
|
</span>
|
82
85
|
{% endfor %}
|
83
86
|
{% endif %}
|
@@ -1118,7 +1118,7 @@
|
|
1118
1118
|
|
1119
1119
|
{{ variant.variant_rank }}</a>
|
1120
1120
|
|
1121
|
-
{{ evaluations_badge(variant) }}
|
1121
|
+
{{ evaluations_badge(variant.evaluations) }}
|
1122
1122
|
{{ research_assessments_badge(variant) }}
|
1123
1123
|
{{ clinical_assessments_badge(variant) }}
|
1124
1124
|
{{ group_assessments_badge(variant) }}
|
@@ -19,7 +19,7 @@ from scout.constants import (
|
|
19
19
|
SEVERE_SO_TERMS_SV,
|
20
20
|
)
|
21
21
|
from scout.server.extensions import store
|
22
|
-
from scout.server.utils import institute_and_case, templated
|
22
|
+
from scout.server.utils import get_case_genome_build, institute_and_case, templated
|
23
23
|
|
24
24
|
from . import controllers
|
25
25
|
from .forms import (
|
@@ -129,7 +129,7 @@ def variants(institute_id, case_name):
|
|
129
129
|
|
130
130
|
controllers.update_form_hgnc_symbols(store, case_obj, form)
|
131
131
|
|
132
|
-
genome_build =
|
132
|
+
genome_build = get_case_genome_build(case_obj)
|
133
133
|
cytobands = store.cytoband_by_chrom(genome_build)
|
134
134
|
|
135
135
|
variants_query = store.variants(
|
@@ -220,7 +220,7 @@ def str_variants(institute_id, case_name):
|
|
220
220
|
|
221
221
|
controllers.activate_case(store, institute_obj, case_obj, current_user)
|
222
222
|
|
223
|
-
genome_build =
|
223
|
+
genome_build = get_case_genome_build(case_obj)
|
224
224
|
cytobands = store.cytoband_by_chrom(genome_build)
|
225
225
|
|
226
226
|
query = form.data
|
@@ -231,6 +231,7 @@ def str_variants(institute_id, case_name):
|
|
231
231
|
).sort(
|
232
232
|
[
|
233
233
|
("str_repid", pymongo.ASCENDING),
|
234
|
+
("str_trid", pymongo.ASCENDING),
|
234
235
|
("chromosome", pymongo.ASCENDING),
|
235
236
|
("position", pymongo.ASCENDING),
|
236
237
|
]
|
@@ -302,7 +303,7 @@ def sv_variants(institute_id, case_name):
|
|
302
303
|
# Populate custom soft filters
|
303
304
|
controllers.populate_institute_soft_filters(form=form, institute_obj=institute_obj)
|
304
305
|
|
305
|
-
genome_build =
|
306
|
+
genome_build = get_case_genome_build(case_obj)
|
306
307
|
cytobands = store.cytoband_by_chrom(genome_build)
|
307
308
|
|
308
309
|
controllers.update_form_hgnc_symbols(store, case_obj, form)
|
@@ -397,7 +398,7 @@ def mei_variants(institute_id, case_name):
|
|
397
398
|
# populate available panel choices
|
398
399
|
form.gene_panels.choices = controllers.gene_panel_choices(store, institute_obj, case_obj)
|
399
400
|
|
400
|
-
genome_build =
|
401
|
+
genome_build = get_case_genome_build(case_obj)
|
401
402
|
cytobands = store.cytoband_by_chrom(genome_build)
|
402
403
|
|
403
404
|
controllers.update_form_hgnc_symbols(store, case_obj, form)
|
@@ -509,7 +510,7 @@ def cancer_variants(institute_id, case_name):
|
|
509
510
|
|
510
511
|
form.gene_panels.choices = controllers.gene_panel_choices(store, institute_obj, case_obj)
|
511
512
|
|
512
|
-
genome_build =
|
513
|
+
genome_build = get_case_genome_build(case_obj)
|
513
514
|
cytobands = store.cytoband_by_chrom(genome_build)
|
514
515
|
|
515
516
|
controllers.update_form_hgnc_symbols(store, case_obj, form)
|
@@ -587,7 +588,7 @@ def cancer_sv_variants(institute_id, case_name):
|
|
587
588
|
# Populate custom soft filters
|
588
589
|
controllers.populate_institute_soft_filters(form=form, institute_obj=institute_obj)
|
589
590
|
|
590
|
-
genome_build =
|
591
|
+
genome_build = get_case_genome_build(case_obj)
|
591
592
|
cytobands = store.cytoband_by_chrom(genome_build)
|
592
593
|
|
593
594
|
controllers.update_form_hgnc_symbols(store, case_obj, form)
|
@@ -671,7 +672,7 @@ def fusion_variants(institute_id, case_name):
|
|
671
672
|
# Populate custom soft filters
|
672
673
|
controllers.populate_institute_soft_filters(form=form, institute_obj=institute_obj)
|
673
674
|
|
674
|
-
genome_build =
|
675
|
+
genome_build = get_case_genome_build(case_obj)
|
675
676
|
cytobands = store.cytoband_by_chrom(genome_build)
|
676
677
|
|
677
678
|
controllers.update_form_hgnc_symbols(store, case_obj, form)
|
scout/server/config.py
CHANGED
@@ -1,6 +1,9 @@
|
|
1
1
|
# -*- coding: utf-8 -*-
|
2
2
|
SECRET_KEY = "this is not secret..."
|
3
3
|
REMEMBER_COOKIE_NAME = "scout_remember_me" # Prevent session timeout when user closes browser
|
4
|
+
# INSTANCE_NAME = "Development" # Name will be displayed on the top navigation menu
|
5
|
+
# INSTANCE_COLOR = "#800000" # Color of the top navigation menu
|
6
|
+
|
4
7
|
# SESSION_TIMEOUT_MINUTES = 60 # Minutes of inactivity before session times out
|
5
8
|
|
6
9
|
# MONGO_URI = "mongodb://127.0.0.1:27011,127.0.0.1:27012,127.0.0.1:27013/?replicaSet=rs0&readPreference=primary"
|
@@ -8,7 +8,12 @@ import logging
|
|
8
8
|
from flask import flash, url_for
|
9
9
|
from flask_login import current_user
|
10
10
|
|
11
|
-
from scout.utils
|
11
|
+
from scout.server.utils import get_case_genome_build
|
12
|
+
from scout.utils.scout_requests import (
|
13
|
+
delete_request_json,
|
14
|
+
get_request_json,
|
15
|
+
post_request_json,
|
16
|
+
)
|
12
17
|
|
13
18
|
LOG = logging.getLogger(__name__)
|
14
19
|
DATASET_BUILDS = ["GRCh37", "GRCh38"]
|
@@ -58,7 +63,7 @@ class Beacon:
|
|
58
63
|
data(dict): a dictionary with base info to be used as json data in beacon add request (lacks path to VCF file to extract variants from)
|
59
64
|
"""
|
60
65
|
# Initialize key/values to be sent in request:
|
61
|
-
assembly = "GRCh38" if
|
66
|
+
assembly = "GRCh38" if get_case_genome_build(case_obj) == "38" else "GRCh37"
|
62
67
|
dataset_id = "_".join([case_obj["owner"], case_obj.get("build", assembly)])
|
63
68
|
|
64
69
|
samples = []
|
@@ -12,7 +12,17 @@
|
|
12
12
|
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap-dark-5@1.1.3/dist/css/bootstrap-dark.min.css" integrity="sha384-pZAJcuaxKZEGkzXV5bYqUcSwBfMZPdQS/+JXdYOu9ScyZJMnGHD5Xi6HVHfZuULH" crossorigin="anonymous">
|
13
13
|
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.6.0/css/all.min.css" integrity="sha512-Kc323vGBEqzTmouAECnVceyQqyqdsSiqLQISBL29aUW4U/M7pSPA/gEUZQqv1cwx4OnYxTxve5UMg5GT6L4JJg==" crossorigin="anonymous" referrerpolicy="no-referrer" />
|
14
14
|
<link rel="stylesheet" href="{{ url_for('static', filename='bs_styles.css') }}">
|
15
|
-
|
15
|
+
|
16
|
+
{% if config.INSTANCE_COLOR %}
|
17
|
+
<style>
|
18
|
+
/* Override Scout's bg-primary with color set on app config, if available */
|
19
|
+
nav.navbar.bg-primary {
|
20
|
+
background-color: {{ config.INSTANCE_COLOR }} !important;
|
21
|
+
}
|
22
|
+
</style>
|
23
|
+
{% endif %}
|
24
|
+
|
25
|
+
{% endblock %}
|
16
26
|
|
17
27
|
{% block css_style %}
|
18
28
|
{% endblock %}
|
@@ -18,9 +18,14 @@
|
|
18
18
|
|
19
19
|
{% block navbar %}
|
20
20
|
<nav class="navbar navbar-expand-lg nav-pills navbar-dark bg-primary sticky-top" >
|
21
|
-
<div class="container-fluid
|
21
|
+
<div class="container-fluid rounded-bottom">
|
22
22
|
<a class="navbar-brand" href="{{ url_for('cases.index') }}">
|
23
23
|
<img src="{{ url_for('public.static', filename='scout-logo.png') }}" width="30" height="30" class="d-inline-block align-top text-white" alt="">Scout</a>
|
24
|
+
{% if config.INSTANCE_NAME %}
|
25
|
+
<span class="badge bg-light text-dark">
|
26
|
+
{{ config.INSTANCE_NAME }}
|
27
|
+
</span>
|
28
|
+
{% endif %}
|
24
29
|
<button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarSupportedContent" aria-controls="navbarSupportedContent" aria-expanded="false" aria-label="Toggle navigation">
|
25
30
|
<span class="navbar-toggler-icon"></span>
|
26
31
|
</button>
|
scout/server/utils.py
CHANGED
@@ -8,11 +8,21 @@ import zipfile
|
|
8
8
|
from functools import wraps
|
9
9
|
from io import BytesIO
|
10
10
|
from typing import Dict, Optional, Tuple
|
11
|
+
from urllib.parse import urlparse
|
11
12
|
|
12
13
|
import pdfkit
|
13
14
|
from bson.objectid import ObjectId
|
14
|
-
from flask import
|
15
|
+
from flask import (
|
16
|
+
Response,
|
17
|
+
abort,
|
18
|
+
current_app,
|
19
|
+
flash,
|
20
|
+
redirect,
|
21
|
+
render_template,
|
22
|
+
request,
|
23
|
+
)
|
15
24
|
from flask_login import current_user
|
25
|
+
from werkzeug.local import LocalProxy
|
16
26
|
|
17
27
|
LOG = logging.getLogger(__name__)
|
18
28
|
|
@@ -102,6 +112,17 @@ def public_endpoint(function):
|
|
102
112
|
return function
|
103
113
|
|
104
114
|
|
115
|
+
def safe_redirect_back(request: LocalProxy, link: Optional[str] = None) -> Response:
|
116
|
+
"""Safely redirects the user back to the referring URL, if it originates from the same host.
|
117
|
+
Otherwise, the user is redirected to a default '/'."""
|
118
|
+
referrer = request.referrer
|
119
|
+
if referrer:
|
120
|
+
parsed_referrer = urlparse(referrer)
|
121
|
+
if parsed_referrer.netloc == request.host:
|
122
|
+
return redirect(link or referrer)
|
123
|
+
return redirect("/")
|
124
|
+
|
125
|
+
|
105
126
|
def variant_institute_and_case(
|
106
127
|
store, variant_obj: dict, institute_id: Optional[str], case_name: Optional[str]
|
107
128
|
) -> Tuple[dict, dict]:
|
@@ -145,7 +166,7 @@ def institute_and_case(store, institute_id, case_name=None):
|
|
145
166
|
return abort(404)
|
146
167
|
|
147
168
|
# Make sure build is either "37" or "38"
|
148
|
-
case_obj["genome_build"] =
|
169
|
+
case_obj["genome_build"] = get_case_genome_build(case_obj)
|
149
170
|
|
150
171
|
# validate that user has access to the institute
|
151
172
|
|
@@ -208,7 +229,7 @@ def user_institutes(store, login_user):
|
|
208
229
|
|
209
230
|
def get_case_genome_build(case_obj: dict) -> str:
|
210
231
|
"""returns the genome build of a case, as a string."""
|
211
|
-
return "38" if "38" in case_obj.get("genome_build", "37") else "37"
|
232
|
+
return "38" if "38" in str(case_obj.get("genome_build", "37")) else "37"
|
212
233
|
|
213
234
|
|
214
235
|
def get_case_mito_chromosome(case_obj: dict) -> str:
|
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.4
|
2
2
|
Name: scout-browser
|
3
|
-
Version: 4.
|
3
|
+
Version: 4.102.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
|