scout-browser 4.83__py3-none-any.whl → 4.84__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.
Files changed (47) hide show
  1. scout/__version__.py +1 -1
  2. scout/adapter/mongo/case.py +5 -1
  3. scout/adapter/mongo/variant.py +9 -0
  4. scout/adapter/mongo/variant_loader.py +73 -71
  5. scout/build/genes/hgnc_gene.py +5 -134
  6. scout/commands/download/ensembl.py +1 -0
  7. scout/commands/download/everything.py +1 -0
  8. scout/commands/download/exac.py +1 -0
  9. scout/commands/download/hgnc.py +1 -0
  10. scout/commands/download/hpo.py +1 -0
  11. scout/commands/download/omim.py +1 -0
  12. scout/commands/export/database.py +1 -0
  13. scout/commands/load/panel.py +1 -0
  14. scout/commands/load/report.py +1 -0
  15. scout/commands/update/omim.py +1 -0
  16. scout/commands/update/panelapp.py +1 -0
  17. scout/constants/file_types.py +86 -17
  18. scout/export/exon.py +1 -0
  19. scout/load/all.py +5 -1
  20. scout/load/hgnc_gene.py +1 -1
  21. scout/models/hgnc_map.py +50 -87
  22. scout/models/phenotype_term.py +3 -3
  23. scout/parse/orpha.py +1 -0
  24. scout/parse/variant/conservation.py +1 -0
  25. scout/server/blueprints/cases/templates/cases/case.html +95 -88
  26. scout/server/blueprints/panels/forms.py +1 -0
  27. scout/server/blueprints/variant/controllers.py +9 -14
  28. scout/server/blueprints/variants/controllers.py +11 -27
  29. scout/server/extensions/bionano_extension.py +1 -0
  30. scout/server/extensions/chanjo_extension.py +10 -9
  31. scout/server/extensions/gens_extension.py +1 -0
  32. scout/server/extensions/ldap_extension.py +5 -3
  33. scout/server/extensions/loqus_extension.py +16 -14
  34. scout/server/extensions/matchmaker_extension.py +1 -0
  35. scout/server/extensions/mongo_extension.py +1 -0
  36. scout/server/extensions/rerunner_extension.py +1 -0
  37. scout/server/links.py +4 -4
  38. scout/server/static/bs_styles.css +5 -5
  39. scout/utils/ensembl_rest_clients.py +1 -0
  40. scout/utils/scout_requests.py +1 -0
  41. scout/utils/sort.py +21 -0
  42. {scout_browser-4.83.dist-info → scout_browser-4.84.dist-info}/METADATA +2 -5
  43. {scout_browser-4.83.dist-info → scout_browser-4.84.dist-info}/RECORD +47 -46
  44. {scout_browser-4.83.dist-info → scout_browser-4.84.dist-info}/WHEEL +1 -1
  45. {scout_browser-4.83.dist-info → scout_browser-4.84.dist-info}/entry_points.txt +0 -1
  46. {scout_browser-4.83.dist-info → scout_browser-4.84.dist-info}/LICENSE +0 -0
  47. {scout_browser-4.83.dist-info → scout_browser-4.84.dist-info}/top_level.txt +0 -0
scout/models/hgnc_map.py CHANGED
@@ -2,6 +2,8 @@ from __future__ import unicode_literals
2
2
 
3
3
  from typing import List, Optional
4
4
 
5
+ from pydantic import BaseModel, Field, field_validator, model_validator
6
+
5
7
 
6
8
  class Exon(dict):
7
9
  """Exon dictionary
@@ -66,90 +68,51 @@ class HgncTranscript(dict):
66
68
  self["mane_plus_clinical"] = mane_plus_clinical
67
69
 
68
70
 
69
- class HgncGene(dict):
70
- """HgncGene dictionary
71
-
72
- 'hgnc_id': int, # This is the hgnc id, required:
73
- 'hgnc_symbol': str, # The primary symbol, required
74
- 'ensembl_id': str, # required
75
- 'build': str, # '37' or '38', defaults to '37', required
76
-
77
- 'chromosome': str, # required
78
- 'start': int, # required
79
- 'end': int, # required
80
-
81
- 'description': str, # Gene description
82
- 'aliases': list(), # Gene symbol aliases, includes hgnc_symbol, str
83
- 'entrez_id': int,
84
- 'omim_id': int,
85
- 'pli_score': float,
86
- 'primary_transcripts': list(), # List of refseq transcripts (str)
87
- 'ucsc_id': str,
88
- 'uniprot_ids': list(), # List of str
89
- 'vega_id': str,
90
-
91
- # Inheritance information
92
- 'inheritance_models': list(), # List of model names
93
- 'incomplete_penetrance': bool, # Acquired from HPO
94
-
95
- # Phenotype information
96
- 'phenotypes': list(), # List of dictionaries with phenotype information
97
- """
98
-
99
- def __init__(
100
- self,
101
- hgnc_id,
102
- hgnc_symbol,
103
- ensembl_id,
104
- chrom,
105
- start,
106
- end,
107
- description=None,
108
- aliases=None,
109
- entrez_id=None,
110
- omim_id=None,
111
- pli_score=None,
112
- primary_transcripts=None,
113
- ucsc_id=None,
114
- uniprot_ids=None,
115
- vega_id=None,
116
- inheritance_models=None,
117
- incomplete_penetrance=False,
118
- phenotypes=None,
119
- build="37",
120
- ):
121
- super(HgncGene, self).__init__()
122
- self["hgnc_id"] = int(hgnc_id)
123
- self["hgnc_symbol"] = hgnc_symbol
124
- self["ensembl_id"] = ensembl_id
125
-
126
- self["chromosome"] = chrom
127
- self["start"] = int(start)
128
- self["end"] = int(end)
129
- self["length"] = self["end"] - self["start"]
130
-
131
- self["description"] = description
132
- self["aliases"] = aliases
133
- self["primary_transcripts"] = primary_transcripts
134
- self["inheritance_models"] = inheritance_models
135
- self["phenotypes"] = phenotypes
136
-
137
- self["entrez_id"] = entrez_id
138
- if entrez_id:
139
- self["entrez_id"] = int(entrez_id)
140
-
141
- self["omim_id"] = omim_id
142
- if omim_id:
143
- self["omim_id"] = int(omim_id)
144
-
145
- self["ucsc_id"] = ucsc_id
146
- self["uniprot_ids"] = uniprot_ids
147
- self["vega_id"] = vega_id
148
-
149
- self["pli_score"] = pli_score
150
- if pli_score:
151
- self["pli_score"] = float(pli_score)
152
-
153
- self["incomplete_penetrance"] = incomplete_penetrance
154
-
155
- self["build"] = build
71
+ class HgncGene(BaseModel):
72
+ hgnc_id: int
73
+ hgnc_symbol: str
74
+ build: str
75
+ chromosome: str
76
+ start: int
77
+ end: int
78
+ length: int
79
+ description: Optional[str] = None
80
+ ensembl_id: Optional[str] = Field(None, alias="ensembl_gene_id")
81
+ aliases: Optional[List[str]] = Field(None, alias="previous_symbols")
82
+ entrez_id: Optional[int] = None
83
+ omim_id: Optional[int] = None
84
+ primary_transcripts: Optional[List[str]] = Field(None, alias="ref_seq")
85
+ ucsc_id: Optional[str] = None
86
+ uniprot_ids: Optional[List[str]] = None
87
+ vega_id: Optional[str] = None
88
+ inheritance_models: Optional[List[str]] = None
89
+ incomplete_penetrance: Optional[bool] = False
90
+ phenotypes: Optional[List[dict]] = None
91
+ pli_score: Optional[float] = None
92
+ constraint_lof_oe: Optional[float] = None
93
+ constraint_lof_oe_ci_lower: Optional[float] = None
94
+ constraint_lof_oe_ci_upper: Optional[float] = None
95
+ constraint_lof_z: Optional[float] = None
96
+ constraint_mis_oe: Optional[float] = None
97
+ constraint_mis_oe_ci_lower: Optional[float] = None
98
+ constraint_mis_oe_ci_upper: Optional[float] = None
99
+ constraint_mis_z: Optional[float] = None
100
+
101
+ @model_validator(mode="before")
102
+ def set_gene_length(cls, values) -> "HgncGene":
103
+ """Set gene length."""
104
+ if None in [values.get("end"), values.get("start")]:
105
+ values.update({"length": None})
106
+ else:
107
+ values.update({"length": values.get("end") - values.get("start")})
108
+ return values
109
+
110
+ @field_validator("phenotypes", mode="before")
111
+ @classmethod
112
+ def set_phenotypes_inheritance(cls, phenotypes) -> Optional[List[dict]]:
113
+ """Convert field 'inheritance' of each phenotype in phenotypes from set to list."""
114
+ for phenotype in phenotypes:
115
+ phenotype["inheritance_models"] = list(phenotype.get("inheritance", {}))
116
+ phenotype.pop("inheritance", None)
117
+
118
+ return phenotypes
@@ -14,9 +14,9 @@ class HpoTerm(BaseModel):
14
14
  """
15
15
 
16
16
  hpo_id: str # id field in the hpo.obo file
17
- hpo_number: Optional[
18
- int
19
- ] = None # id field in the hpo.obo file, stripped of the 'HP:' part and the zeroes
17
+ hpo_number: Optional[int] = (
18
+ None # id field in the hpo.obo file, stripped of the 'HP:' part and the zeroes
19
+ )
20
20
  description: str # name field in the hpo.obo file
21
21
  ancestors: List = []
22
22
  all_ancestors: List = []
scout/parse/orpha.py CHANGED
@@ -1,4 +1,5 @@
1
1
  """Code for parsing ORPHA formatted files"""
2
+
2
3
  import logging
3
4
  from typing import Any, Dict, List
4
5
  from xml.etree.ElementTree import Element
@@ -1,4 +1,5 @@
1
1
  """Code for parsing conservation"""
2
+
2
3
  import logging
3
4
  import numbers
4
5
 
@@ -65,7 +65,7 @@
65
65
  <span class="badge rounded-pill bg-info text-body" data-bs-toggle="tooltip" data-bs-placement="left" title="Matching causatives and managed variants displayed on case page are NOT filtered by gene panel. Use caution to avoid incidental findings.">off</span>
66
66
  {% endif %}
67
67
  </div>
68
- </div> <!--end of div class="row" -->
68
+ </div> <!--end of row -->
69
69
  <div class="row">
70
70
  <form id="case_status_form" method="POST" action="{{ url_for('cases.status', institute_id=institute._id, case_name=case.display_name) }}">
71
71
  <div class="btn-toolbar ms-2" role="toolbar">
@@ -105,7 +105,7 @@
105
105
  {{ 'Inactive' if case.status == 'ignored' else 'Ignored' }}
106
106
  </button>
107
107
  </div>
108
- <div class="btn-group ms-2 role="group">
108
+ <div class="btn-group ms-2" role="group">
109
109
  <select name="tags" id="status_tags_case" multiple class="selectpicker" data-style="btn btn-secondary">
110
110
  {% for tag, data in case_tag_options.items() %}
111
111
  <option {% if 'tags' in case and tag~"" in case.tags %} selected {% endif %} value="{{ tag }}" title="{{ data.label }}">
@@ -119,103 +119,65 @@
119
119
  </div>
120
120
  </div>
121
121
 
122
+ {{ matching_variants() }}
123
+
122
124
  <div class="card panel-default" >
123
- <div class="row mt-0">
124
- <div class="col-sm-12 col-md-12 ms-3">
125
- <div data-bs-toggle='tooltip' class="panel-heading" title="Check if there are any variants in this case
126
- marked as causative in another case for this institute, or are on the managed variants list.">
127
- <strong>{% if hide_matching == false %}
128
- <a href="{{ url_for('cases.case', institute_id=institute._id, case_name=case.display_name, hide_matching='True') }}" class="text-body"><span class="me-1 fa fa-caret-right"></span>Search for matching causatives and managed variants</a>
129
- {% else %}
130
- <a href="{{ url_for('cases.case', institute_id=institute._id, case_name=case.display_name, hide_matching='False') }}" class="text-body"><span class="me-1 fa fa-caret-down"></span>Search for matching causatives and managed variants</a>
131
- {% endif %}
132
- </strong>
133
- </div>
134
- </div>
125
+ <div class="row">
126
+ <div class="col">{{ causatives_list(causatives, partial_causatives, evaluated_variants, institute, case, manual_rank_options, cancer_tier_options) }}</div>
127
+ <div class="col">{{ suspects_list(suspects, institute, case, manual_rank_options, cancer_tier_options) }}</div>
128
+ <!-- end of data sharing panels -->
135
129
  </div>
136
- {% if hide_matching == false %}
137
- {% if other_causatives|length > 0 %}
138
- <div class="row mt-0 ms-3">
139
- <div class="col-xs-12 col-md-12 ms-3">{{ matching_causatives(other_causatives, institute, case) }}</div>
140
- </div>
141
- {% endif %}
142
- {% if default_other_causatives|length > 0%}
143
- <div class="row mt-0 ms-3">
144
- <div class="col-xs-12 col-md-12 ms-3">{{ matching_causatives(default_other_causatives, institute, case, default=True) }}</div>
145
- </div>
146
- {% endif %}
147
- {% if managed_variants|length > 0%}
148
- <div class="row mt-0 ms-3">
149
- <div class="col-sm-12 col-md-12 ms-3">{{ matching_managed_variants(managed_variants, institute, case) }}</div>
150
- </div>
151
- {% endif %}
152
- {% if default_managed_variants|length > 0%}
153
- <div class="row mt-0 ms-3">
154
- <div class="col-sm-12 col-md-12 ms-3">{{ matching_managed_variants(default_managed_variants, institute, case, default=True) }}</div>
155
- </div>
156
- {% endif %}
157
- {% if other_causatives|length == 0 and default_other_causatives|length == 0 and managed_variants|length == 0 and default_managed_variants|length == 0%}
158
- <div class="row mt-0 ms-3">
159
- <div class="col-sm-12 col-md-12 ms-3">No matching causatives or managed variants found</div>
160
- </div>
161
- {% endif %}
162
- {% endif %}
163
- <div class="row">
164
- <div class="col">{{ causatives_list(causatives, partial_causatives, evaluated_variants, institute, case, manual_rank_options, cancer_tier_options) }}</div>
165
- <div class="col">{{ suspects_list(suspects, institute, case, manual_rank_options, cancer_tier_options) }}</div>
166
- <!-- end of data sharing panels -->
167
- </div>
168
130
 
169
- <div class="row">
170
- {% if case.track == 'cancer' %}
171
- <div class="col-sm-12 col-md-12 mt-3">{{ cancer_individuals_table(case, institute, tissue_types, gens_info) }}</div>
172
- {% else %}
173
- <div class="mt-3 col-sm-8 col-md-{{"8" if case.madeline_info and case.individuals|length > 1 else "12"}}">{{ individuals_table(case, institute, tissue_types, display_rerunner, gens_info) }}</div>
174
- {% if case.madeline_info and case.individuals|length > 1 %}
175
- <div class="col-sm-4">
176
- {{ pedigree_panel(case) }}
177
- </div>
131
+ <div class="row">
132
+ {% if case.track == 'cancer' %}
133
+ <div class="col-sm-12 col-md-12 mt-3">{{ cancer_individuals_table(case, institute, tissue_types, gens_info) }}</div>
134
+ {% else %}
135
+ <div class="mt-3 col-sm-8 col-md-{{"8" if case.madeline_info and case.individuals|length > 1 else "12"}}">{{ individuals_table(case, institute, tissue_types, display_rerunner, gens_info) }}</div>
136
+ {% if case.madeline_info and case.individuals|length > 1 %}
137
+ <div class="col-sm-4">
138
+ {{ pedigree_panel(case) }}
139
+ </div>
140
+ {% endif %}
178
141
  {% endif %}
179
- {% endif %}
180
- </div>
181
-
182
- <div class="row mt-3">
183
- <div class="col-6">{{ synopsis_panel() }}</div>
184
- <div class="col-6">{{ comments_panel(institute, case, current_user, comments) }}</div>
185
- </div>
142
+ </div>
186
143
 
187
- <div class="row">
188
- <div class="col-sm-12">
189
- {{ insert_multi_image_panel() }}
144
+ <div class="row mt-3">
145
+ <div class="col-6">{{ synopsis_panel() }}</div>
146
+ <div class="col-6">{{ comments_panel(institute, case, current_user, comments) }}</div>
190
147
  </div>
191
- </div>
192
148
 
193
- <div class="row">
194
- <div class="col-sm-12">
195
- {{ custom_image_panels() }}
149
+ <div class="row">
150
+ <div class="col-sm-12">
151
+ {{ insert_multi_image_panel() }}
152
+ </div>
196
153
  </div>
197
- </div>
198
154
 
199
- <!-- CASE DIAGNOSES AND PHENOTYPES -->
200
- <div class="panel-default">
201
- <div class="panel-heading"><span class="fa fa-user-md"></span>&nbsp;Phenotypes & diagnoses</div>
202
155
  <div class="row">
203
- <div class="col-sm-6 ">
204
- <div class="card h-100">
205
- <div class="card-body">
206
- {{ hpo_panel(case, institute, config) }}
156
+ <div class="col-sm-12">
157
+ {{ custom_image_panels() }}
158
+ </div>
159
+ </div>
160
+
161
+ <!-- CASE DIAGNOSES AND PHENOTYPES -->
162
+ <div class="panel-default">
163
+ <div class="panel-heading"><span class="fa fa-user-md"></span>&nbsp;Phenotypes & diagnoses</div>
164
+ <div class="row">
165
+ <div class="col-sm-6 ">
166
+ <div class="card h-100">
167
+ <div class="card-body">
168
+ {{ hpo_panel(case, institute, config) }}
169
+ </div>
207
170
  </div>
208
171
  </div>
209
- </div>
210
- <div class="col-sm-6">
211
- <div class="card h-100">
212
- <div class="card-body">
213
- {{ hpo_genelist_panel(case, institute, config) }}
172
+ <div class="col-sm-6">
173
+ <div class="card h-100">
174
+ <div class="card-body">
175
+ {{ hpo_genelist_panel(case, institute, config) }}
176
+ </div>
214
177
  </div>
215
178
  </div>
216
- </div>
217
- </div> <!--end of <div class="row">-->
218
- </div>
179
+ </div> <!--end of row>-->
180
+ </div> <!--end of card panel-default -->
219
181
 
220
182
  <!-- diagnoses-related code-->
221
183
  {% if not case.track == 'cancer' %}
@@ -259,8 +221,8 @@
259
221
  {{ reanalysis_modal(institute, case) }}
260
222
  {{ beacon_modal(institute, case) }}
261
223
  {{ matchmaker_modal(institute, case, suspects, mme_nodes) }}
262
- </div><!-- end of <div containter> -->
263
- </div><!-- end of <div col> -->
224
+ </div><!-- end of containter -->
225
+ </div><!-- end of col -->
264
226
  {% endmacro %}
265
227
 
266
228
  {% macro variants_buttons() %}
@@ -398,7 +360,7 @@
398
360
  </div>
399
361
  {% endfor %}
400
362
  {% endif %}
401
- </div> <!-- end of <div class="list-group" style="max-height:200px; overflow-y: scroll;" -->
363
+ </div> <!-- end of list-group -->
402
364
  </div>
403
365
  </div>
404
366
  {% endmacro %}
@@ -574,6 +536,51 @@
574
536
  </div>
575
537
  {% endmacro %}
576
538
 
539
+ {% macro matching_variants() %}
540
+ <div class="card mt-3">
541
+ <div class="row mt-0 ms-3">
542
+ <div class="col-sm-12 col-md-12">
543
+ <div data-bs-toggle='tooltip' class="panel-heading" title="Check if there are any variants in this case
544
+ marked as causative in another case for this institute, or are on the managed variants list.">
545
+ <strong>
546
+ {% if hide_matching == false %}
547
+ <a href="{{ url_for('cases.case', institute_id=institute._id, case_name=case.display_name, hide_matching='True') }}" class="text-body"><span class="me-1 fa fa-caret-down"></span>Search for matching causatives and managed variants</a>
548
+ {% else %}
549
+ <a href="{{ url_for('cases.case', institute_id=institute._id, case_name=case.display_name, hide_matching='False') }}" class="text-body"><span class="me-1 fa fa-caret-right"></span>Search for matching causatives and managed variants</a>
550
+ {% endif %}
551
+ </strong>
552
+ </div>
553
+ </div>
554
+ {% if hide_matching == false %}
555
+ {% if other_causatives|length > 0 %}
556
+ <div class="row mt-0 ms-3">
557
+ <div class="col-xs-12 col-md-12">{{ matching_causatives(other_causatives, institute, case) }}</div>
558
+ </div>
559
+ {% endif %}
560
+ {% if default_other_causatives|length > 0%}
561
+ <div class="row mt-0 ms-3">
562
+ <div class="col-xs-12 col-md-12">{{ matching_causatives(default_other_causatives, institute, case, default=True) }}</div>
563
+ </div>
564
+ {% endif %}
565
+ {% if managed_variants|length > 0%}
566
+ <div class="row mt-0 ms-3">
567
+ <div class="col-sm-12 col-md-12">{{ matching_managed_variants(managed_variants, institute, case) }}</div>
568
+ </div>
569
+ {% endif %}
570
+ {% if default_managed_variants|length > 0%}
571
+ <div class="row mt-0 ms-3">
572
+ <div class="col-sm-12 col-md-12">{{ matching_managed_variants(default_managed_variants, institute, case, default=True) }}</div>
573
+ </div>
574
+ {% endif %}
575
+ {% if other_causatives|length == 0 and default_other_causatives|length == 0 and managed_variants|length == 0 and default_managed_variants|length == 0%}
576
+ <div class="row mt-0 ms-3">
577
+ <div class="col-sm-12 col-md-12">No matching causatives or managed variants found</div>
578
+ </div>
579
+ {% endif %}
580
+ {% endif %}
581
+ </div>
582
+ </div>
583
+ {% endmacro %}
577
584
 
578
585
  {% block scripts %}
579
586
  {{ super() }}
@@ -1,4 +1,5 @@
1
1
  """Code for panel gene form"""
2
+
2
3
  from flask_wtf import FlaskForm
3
4
  from wtforms import BooleanField, SelectMultipleField, StringField
4
5
 
@@ -486,26 +486,21 @@ def observations(store: MongoAdapter, loqusdb: LoqusDB, variant_obj: dict) -> Di
486
486
  loqus_query = loqusdb.get_loqus_query(variant_obj, category)
487
487
 
488
488
  for loqus_id in inst_loqus_ids: # Loop over all loqusdb instances of an institute
489
- obs_data[loqus_id] = {}
490
- loqus_settings = loqusdb.loqusdb_settings.get(loqus_id)
489
+ # collect observation on that loqusdb instance
490
+ obs_data[loqus_id] = loqusdb.get_variant(loqus_query, loqusdb_id=loqus_id)
491
491
 
492
- if loqus_settings is None: # An instance might have been renamed or removed
492
+ if obs_data[loqus_id] is None:
493
493
  flash(
494
- f"Could not connect to the preselected loqusdb '{loqus_id}' instance",
494
+ f"Could not find a Loqus instance with id:{loqus_id}",
495
495
  "warning",
496
496
  )
497
- obs_data[loqus_id]["total"] = "N/A"
497
+ obs_data[loqus_id]["observations"] = "N/A"
498
498
  continue
499
- obs_data[loqus_id] = loqusdb.get_variant(
500
- loqus_query, loqusdb_id=loqus_id
501
- ) # collect observation on that loqus instance
502
-
503
- if not obs_data[loqus_id]: # data is an empty dictionary
504
- # Collect count of variants in variant's case
505
- obs_data[loqus_id] = loqusdb.get_variant(loqus_query, loqusdb_id=loqus_id)
506
- if obs_data[loqus_id].get("total"):
507
- obs_data[loqus_id]["observations"] = 0
499
+
500
+ if obs_data[loqus_id] == {}: # Variant was not found
501
+ obs_data[loqus_id]["observations"] = 0
508
502
  continue
503
+
509
504
  # Check if the current case is represented in the loqusdb instance
510
505
  obs_data[loqus_id]["case_match"] = variant_obj["case_id"] in obs_data[loqus_id].get(
511
506
  "families", []
@@ -3,12 +3,10 @@ import logging
3
3
  import re
4
4
  from typing import Any, Dict, List, Optional
5
5
 
6
- import bson
7
6
  from flask import Response, flash, session, url_for
8
7
  from flask_login import current_user
9
8
  from markupsafe import Markup
10
9
  from pymongo.cursor import CursorType
11
- from pymongo.errors import DocumentTooLarge
12
10
  from werkzeug.datastructures import Headers, ImmutableMultiDict, MultiDict
13
11
  from wtforms import DecimalField
14
12
 
@@ -513,7 +511,7 @@ def update_variant_genes(store, variant_obj, genome_build):
513
511
 
514
512
  if variant_genes is not None:
515
513
  for gene_obj in variant_genes:
516
- # If there is no hgnc id there is nothin we can do
514
+ # If there is no hgnc id there is nothing we can do
517
515
  if not gene_obj["hgnc_id"]:
518
516
  continue
519
517
  # Else we collect the gene object and check the id
@@ -530,27 +528,6 @@ def update_variant_genes(store, variant_obj, genome_build):
530
528
  return has_changed
531
529
 
532
530
 
533
- def update_variant_store(store, variant_obj):
534
- """
535
- Update variants in db store if anything changed.
536
- Args:
537
- store(scout.adapter.MongoAdapter)
538
- variant_obj(scout.models.Variant)
539
-
540
- update(boolean): upsert only if this is set true
541
-
542
- get_compounds(bool): if compounds should be added to added to the returned variant object
543
-
544
- """
545
- try:
546
- variant_obj = store.update_variant(variant_obj)
547
- except DocumentTooLarge:
548
- flash(
549
- f"An error occurred while updating info for variant: {variant_obj['_id']} (pymongo_errors.DocumentTooLarge: {len(bson.BSON.encode(variant_obj))})",
550
- "warning",
551
- )
552
-
553
-
554
531
  def _compound_follow_filter_freq(compound, compound_var_obj, query_form):
555
532
  """When compound follow filter is selected, apply relevant settings from the query filter onto dismissing compounds.
556
533
 
@@ -895,11 +872,18 @@ def parse_variant(
895
872
  compounds_have_changed = False
896
873
  if get_compounds:
897
874
  compounds_have_changed = update_compounds(store, variant_obj, case_dismissed_vars)
875
+ if update and compounds_have_changed:
876
+ store.variant_update_field(
877
+ variant_id=variant_obj["_id"],
878
+ field_name="compounds",
879
+ field_value=variant_obj["compounds"],
880
+ )
898
881
 
899
882
  genes_have_changed = update_variant_genes(store, variant_obj, genome_build)
900
-
901
- if update and (compounds_have_changed or genes_have_changed):
902
- update_variant_store(store, variant_obj)
883
+ if update and genes_have_changed:
884
+ store.variant_update_field(
885
+ variant_id=variant_obj["_id"], field_name="genes", field_value=variant_obj["genes"]
886
+ )
903
887
 
904
888
  variant_obj["comments"] = store.events(
905
889
  institute_obj,
@@ -6,6 +6,7 @@
6
6
  For further development, the server has a Swagger-like demo interface at https://bionano-access.scilifelab.se/Bnx/
7
7
  which is useful for details, and for sniffing actual message content structure, required cookie variable names etc.
8
8
  """
9
+
9
10
  import json
10
11
  import logging
11
12
  from typing import Dict, Iterable, List, Optional, Tuple
@@ -9,21 +9,22 @@ from flask_babel import Babel
9
9
  from markupsafe import Markup
10
10
 
11
11
  LOG = logging.getLogger(__name__)
12
- try:
13
- from chanjo_report.server.app import configure_template_filters
14
- from chanjo_report.server.blueprints import report_bp
15
- from chanjo_report.server.extensions import api as chanjo_api
16
- except ImportError as error:
17
- chanjo_api = None
18
- report_bp = None
19
- configure_template_filters = None
20
- LOG.warning("chanjo-report is not properly installed! %s.", error)
21
12
 
22
13
 
23
14
  class ChanjoReport:
24
15
  """Interfaces with chanjo-report. Creates the /reports endpoints in scout domain. Use Babel to set report language."""
25
16
 
26
17
  def init_app(self, app):
18
+ try:
19
+ from chanjo_report.server.app import configure_template_filters
20
+ from chanjo_report.server.blueprints import report_bp
21
+ from chanjo_report.server.extensions import api as chanjo_api
22
+ except ImportError as error:
23
+ chanjo_api = None
24
+ report_bp = None
25
+ configure_template_filters = None
26
+ LOG.error(error)
27
+
27
28
  if not chanjo_api:
28
29
  raise ImportError(
29
30
  "An SQL db path was given, but chanjo-report could not be registered."
@@ -2,6 +2,7 @@
2
2
 
3
3
  * Requires gens version 1.1.1 or greater
4
4
  """
5
+
5
6
  import logging
6
7
 
7
8
  LOG = logging.getLogger(__name__)
@@ -43,9 +43,11 @@ class LdapManager(LDAPConn):
43
43
  self.tls = Tls(
44
44
  local_private_key_file=app.config["LDAP_CLIENT_PRIVATE_KEY"],
45
45
  local_certificate_file=app.config["LDAP_CLIENT_CERT"],
46
- validate=app.config["LDAP_REQUIRE_CERT"]
47
- if app.config.get("LDAP_CLIENT_CERT")
48
- else ssl.CERT_NONE,
46
+ validate=(
47
+ app.config["LDAP_REQUIRE_CERT"]
48
+ if app.config.get("LDAP_CLIENT_CERT")
49
+ else ssl.CERT_NONE
50
+ ),
49
51
  version=app.config["LDAP_TLS_VERSION"],
50
52
  ca_certs_file=app.config["LDAP_CA_CERTS_FILE"],
51
53
  valid_names=app.config["LDAP_VALID_NAMES"],