Skip to content

Commit a6a1e32

Browse files
Form Updates with API
1 parent a2c3ff8 commit a6a1e32

File tree

9 files changed

+114
-63
lines changed

9 files changed

+114
-63
lines changed

app/historeport/forms.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -97,15 +97,15 @@ class ReportForm(FlaskForm):
9797
)
9898

9999
pheno_terms = StringField(
100-
"HPO Phenotype terms",
100+
"Phenotype terms (HPO API)",
101101
render_kw={
102102
"class": "form-control",
103103
"placeholder": "HPO Phenotype Description",
104104
},
105105
)
106106

107107
gene_diag = StringField(
108-
"Diagnosed Gene",
108+
"Diagnosed Gene (HGNC API)",
109109
render_kw={
110110
"placeholder": "Diagnosed Gene",
111111
"class": "form-control",
@@ -123,7 +123,7 @@ class ReportForm(FlaskForm):
123123
},
124124
)
125125
conclusion = StringField(
126-
"Final Diagnosis",
126+
"Final Diagnosis (Orphanet API)",
127127
render_kw={
128128
"placeholder": "Final Diagnosis",
129129
"class": "form-control",

app/historeport/routes.py

Lines changed: 27 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import json
2-
2+
from contextlib import suppress
33
from app import db
44
from app.historeport import bp
55
from app.historeport.boqa import *
@@ -106,6 +106,20 @@ def historeport():
106106
if report_entry is not None:
107107
form.populate_obj(report_entry)
108108
onto_jstree = StandardVocabulary(report_entry.ontology_tree)
109+
# Process Tagify Output JSON
110+
with suppress(json.decoder.JSONDecodeError):
111+
pheno_terms_list = [
112+
i["value"] for i in json.loads(report_entry.pheno_terms)
113+
]
114+
report_entry.pheno_terms = ",".join(pheno_terms_list)
115+
with suppress(json.decoder.JSONDecodeError):
116+
report_entry.gene_diag = json.loads(report_entry.gene_diag)[0][
117+
"value"
118+
]
119+
with suppress(json.decoder.JSONDecodeError):
120+
report_entry.conclusion = json.loads(report_entry.conclusion)[0][
121+
"value"
122+
]
109123
report_entry.ontology_tree = onto_jstree.clean_tree()
110124
report_entry.expert_id = current_user.id
111125
try:
@@ -129,6 +143,18 @@ def historeport():
129143
else:
130144
report_entry = ReportHisto()
131145
form.populate_obj(report_entry)
146+
# Process Tagify Output JSON
147+
with suppress(json.decoder.JSONDecodeError):
148+
pheno_terms_list = [
149+
i["value"] for i in json.loads(report_entry.pheno_terms)
150+
]
151+
report_entry.pheno_terms = ",".join(pheno_terms_list)
152+
with suppress(json.decoder.JSONDecodeError):
153+
report_entry.gene_diag = json.loads(report_entry.gene_diag)[0]["value"]
154+
with suppress(json.decoder.JSONDecodeError):
155+
report_entry.conclusion = json.loads(report_entry.conclusion)[0][
156+
"value"
157+
]
132158
onto_jstree = StandardVocabulary(report_entry.ontology_tree)
133159
report_entry.ontology_tree = onto_jstree.clean_tree()
134160
report_entry.expert_id = current_user.id

app/historeport/static/historeport.js

Lines changed: 12 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -18,22 +18,11 @@ var input7 = document.querySelector("input[id=correlates_with]");
1818
var input7_tag = new Tagify(input7);
1919

2020
// HPO Terms Field Handler
21-
// Load previous terms annotated to the report from DB as a list (whitelist for tagify)
22-
var term_previous_list = [];
23-
if ($("input[id=pheno_terms]").val() !== "") {
24-
var term_previous_json = JSON.parse($("input[id=pheno_terms]").val());
25-
var term_previous_list = [];
26-
27-
for (var i = 0; i < term_previous_json.length; i++) {
28-
term_previous_list.push(term_previous_json[i]["value"]);
29-
}
30-
}
31-
3221
// Tagify Field handler with whitelist and HPO ajax
3322
var pheno_terms = document.querySelector("input[id=pheno_terms]");
3423
var pheno_terms_tag = new Tagify(pheno_terms, {
3524
enforceWhitelist: true,
36-
whitelist: term_previous_list,
25+
whitelist: $("input[id=pheno_terms]").val().split(","),
3726
}); // for aborting the call
3827

3928
pheno_terms_tag.on("input", onInputHPO);
@@ -68,25 +57,11 @@ function onInputHPO(e) {
6857
}, 700);
6958
}
7059

71-
// HNC Genes Names Field Handler
72-
// Tagify Field handler with whitelist and HPO ajax
73-
var previous_gene = $("input[id=gene_diag]").val();
74-
var previous_gene_list = [];
75-
if ($("input[id=gene_diag]").val() !== "") {
76-
var previous_gene_json = JSON.parse($("input[id=gene_diag]").val());
77-
var previous_gene_list = [];
78-
79-
for (var i = 0; i < previous_gene_json.length; i++) {
80-
previous_gene_list.push(previous_gene_json[i]["value"]);
81-
}
82-
}
83-
8460
var gene_diag_tag = new Tagify(gene_diag, {
8561
enforceWhitelist: true,
86-
whitelist: previous_gene_list,
62+
whitelist: [$("input[id=gene_diag]").val()],
8763
mode: "select",
8864
});
89-
9065
gene_diag_tag.on("input", onInputGene);
9166

9267
// Tagify AJAX Function to get a list of HPO terms
@@ -97,13 +72,11 @@ function onInputGene(e) {
9772
gene_diag_tag.loading(true).dropdown.hide();
9873
clearTimeout(delayTimer);
9974
var myHeaders = new Headers({
100-
"content-type": "application/json",
101-
"Access-Control-Allow-Origin": "*",
75+
accept: "application/json",
10276
});
10377
var options = {
10478
method: "GET",
10579
headers: myHeaders,
106-
mode: "cors",
10780
};
10881
delayTimer = setTimeout(function () {
10982
var value = e.detail.value;
@@ -116,10 +89,11 @@ function onInputGene(e) {
11689
.then((RES) => RES.json())
11790
.then(function (newWhitelist) {
11891
var terms_list = [];
119-
for (var i = 0; i < 5; i++) {
120-
terms_list.push(
121-
newWhitelist.terms[i]["id"] + " " + newWhitelist.terms[i]["name"]
122-
);
92+
var response = newWhitelist.response.docs;
93+
console.log(newWhitelist);
94+
95+
for (var i = 0; i < response.length; i++) {
96+
terms_list.push(response[i]["hgnc_id"] + " " + response[i]["symbol"]);
12397
}
12498
gene_diag_tag.whitelist = terms_list;
12599
gene_diag_tag.loading(false);
@@ -130,20 +104,10 @@ function onInputGene(e) {
130104

131105
// Orphanet Disease Names Field Handler
132106
// Tagify Field handler with whitelist and Orphanet ajax
133-
var previous_conclusion = $("input[id=conclusion]").val();
134-
var previous_conclusion_list = [];
135-
if ($("input[id=conclusion]").val() !== "") {
136-
var previous_conclusion_json = JSON.parse($("input[id=conclusion]").val());
137-
var previous_conclusion_list = [];
138-
139-
for (var i = 0; i < previous_conclusion_json.length; i++) {
140-
previous_conclusion_list.push(previous_conclusion_json[i]["value"]);
141-
}
142-
}
143107
var conclusion = document.querySelector("input[id=conclusion]");
144108
var conclusion_tag = new Tagify(conclusion, {
145109
enforceWhitelist: true,
146-
whitelist: previous_conclusion_list,
110+
whitelist: [$("input[id=conclusion]").val(), "UNCLEAR", "HEALTHY", "OTHER"],
147111
mode: "select",
148112
});
149113

@@ -175,11 +139,13 @@ function onInputConclusion(e) {
175139
var terms_list = [];
176140
for (var i = 0; i < newWhitelist.length; i++) {
177141
terms_list.push(
178-
newWhitelist[i]["ORPHAcode"] +
142+
"ORPHA:" +
143+
newWhitelist[i]["ORPHAcode"] +
179144
" " +
180145
newWhitelist[i]["Preferred term"]
181146
);
182147
}
148+
terms_list.push("UNCLEAR", "HEALTHY", "OTHER");
183149
conclusion_tag.whitelist = terms_list;
184150
conclusion_tag.loading(false);
185151
conclusion_tag.dropdown.show(); // render the suggestions dropdown

app/historeport/templates/historeport.html

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,6 @@
1212
integrity="sha512-bU6dl4fd2XN3Do3aWypPP2DcKywDyR3YlyszV+rOw9OpglrGyBs6TyTsbglf9umgE+sy+dKm1UHhi07Lv+Vtfg=="
1313
crossorigin="anonymous"></script>
1414

15-
<!-- Tagify -->
1615
<!-- Tagify -->
1716
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/tagify/4.9.5/tagify.css"
1817
integrity="sha512-BaWShaAj9H6cyD1SI+/ekd0OtzwPiGXz6R1SP39S3n9URHluzg6asEPsbbldma1UVTGAf1NEYHFAnWcA5bxHzg=="

app/imgupload/forms.py

Lines changed: 4 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -26,12 +26,11 @@ class ImageForm(FlaskForm):
2626
)
2727
patient_ID = StringField(
2828
"Patient ID",
29-
validators=[Regexp(r"^[\w.-_]+$"), DataRequired()],
29+
validators=[DataRequired(), Regexp(r"^[\w.-_]+$")],
3030
render_kw={"placeholder": "Patient ID", "class": "form-control"},
3131
)
3232
biopsy_report_ID = StringField(
3333
"Biopsy ID",
34-
validators=[DataRequired(), Regexp(r"^[\w.-_]*$")],
3534
render_kw={"placeholder": "Biopsy Report ID", "class": "form-control"},
3635
)
3736
type_coloration = SelectField(
@@ -62,13 +61,11 @@ class ImageForm(FlaskForm):
6261
"class": "form-control custom-select",
6362
},
6463
)
65-
diagnostic = SelectField(
66-
"Diagnosis",
67-
validators=[DataRequired()],
68-
choices=Common.create_diag_list(os.path.join("config", "diagnostic.tsv")),
64+
diagnostic = StringField(
65+
"Diagnosis (Orphanet API)",
6966
render_kw={
7067
"placeholder": "Disease diagnostic",
71-
"class": "form-control custom-select",
68+
"class": "form-control",
7269
},
7370
)
7471

app/imgupload/routes.py

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import os
2-
2+
from contextlib import suppress
3+
import json
34
from app import db
45
from app.imgupload import bp
56
from app.imgupload.forms import DeleteButton, ImageForm
@@ -46,7 +47,6 @@ def img_index():
4647
"""
4748
form = DeleteButton()
4849
image_history = Image.query.all()
49-
5050
return render_template("img_index.html", form=form, image_history=image_history)
5151

5252

@@ -175,8 +175,10 @@ def create_img():
175175
age_at_biopsy=form.age_histo.data,
176176
image_path=os.path.join(data_patient_dir, filename),
177177
image_background_path=os.path.join(data_patient_dir, filename_back),
178-
diagnostic=form.diagnostic.data,
179178
)
179+
180+
with suppress(json.decoder.JSONDecodeError):
181+
image.diagnostic = json.loads(form.diagnostic.data)[0]["value"]
180182
# Check if the image already exist in DB (same filename & patient ID)
181183
# If not: add it to DB
182184

app/imgupload/static/imgupload.js

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
// Orphanet Disease Names Field Handler
2+
// Tagify Field handler with whitelist and Orphanet ajax
3+
var conclusion = document.querySelector("input[id=diagnostic]");
4+
var conclusion_tag = new Tagify(conclusion, {
5+
enforceWhitelist: true,
6+
whitelist: [$("input[id=diagnostic]").val(), "UNCLEAR", "HEALTHY", "OTHER"],
7+
mode: "select",
8+
});
9+
10+
conclusion_tag.on("input", onInputConclusion);
11+
12+
// Tagify AJAX Function to get a list of Orphanet names
13+
var myHeaders_orpha = new Headers({
14+
apiKey: "ehroes",
15+
});
16+
var options_orpha = {
17+
headers: myHeaders_orpha,
18+
};
19+
20+
var delayTimer;
21+
function onInputConclusion(e) {
22+
conclusion_tag.whitelist = null; // reset the whitelist
23+
// show loading animation and hide the suggestions dropdown
24+
conclusion_tag.loading(true).dropdown.hide();
25+
clearTimeout(delayTimer);
26+
delayTimer = setTimeout(function () {
27+
var value = e.detail.value;
28+
29+
fetch(
30+
"https://api.orphacode.org/EN/ClinicalEntity/ApproximateName/" + value,
31+
options_orpha
32+
)
33+
.then((RES) => RES.json())
34+
.then(function (newWhitelist) {
35+
var terms_list = [];
36+
for (var i = 0; i < newWhitelist.length; i++) {
37+
terms_list.push(
38+
"ORPHA:" +
39+
newWhitelist[i]["ORPHAcode"] +
40+
" " +
41+
newWhitelist[i]["Preferred term"]
42+
);
43+
}
44+
terms_list.push("UNCLEAR", "HEALTHY", "OTHER");
45+
conclusion_tag.whitelist = terms_list;
46+
conclusion_tag.loading(false);
47+
conclusion_tag.dropdown.show(); // render the suggestions dropdown
48+
});
49+
}, 700);
50+
}

app/imgupload/templates/create_img.html

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,15 @@
11
{% extends "base.html"%}
22
{% block content %}
3+
4+
<!-- Tagify -->
5+
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/tagify/4.9.5/tagify.css"
6+
integrity="sha512-BaWShaAj9H6cyD1SI+/ekd0OtzwPiGXz6R1SP39S3n9URHluzg6asEPsbbldma1UVTGAf1NEYHFAnWcA5bxHzg=="
7+
crossorigin="anonymous" referrerpolicy="no-referrer" />
8+
<script src="https://cdnjs.cloudflare.com/ajax/libs/tagify/4.9.5/tagify.min.js"
9+
integrity="sha512-BGEMEI3qqrE/xefnyaPBBZ7luE9L7+kUNxCP0hyQMDYqxyC6w4vQbjjrqiSQxGIHs8C2cl65zvbhmXt5JZUHow=="
10+
crossorigin="anonymous" referrerpolicy="no-referrer"></script>
11+
12+
313
<div class="row">
414
<div class="col-xl-3"></div>
515
<div class="col-xl-6">
@@ -25,4 +35,5 @@ <h4>Select an image file</h4>
2535
</div>
2636
<div class="col-xl-3"></div>
2737
</div>
38+
<script src="{{ url_for('imgupload.static', filename='imgupload.js') }}"></script>
2839
{% endblock %}

app/imgupload/templates/img_index.html

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,10 +27,10 @@ <h1>Image Database</h1> <a href="{{ url_for('imgupload.img_download') }}"><i cla
2727
</thead>
2828
{% for image in image_history %}
2929
<tr>
30-
<td class="align-middle text-center">{{ image.biopsie_id }}</td>
30+
<td class="align-middle text-center">{{ image.biopsy_id }}</td>
3131
<td class="align-middle text-center">{{ image.patient_id }}</td>
3232
<td class="align-middle text-center">{{ image.image_name }}</td>
33-
<td class="align-middle text-center">{{ image.conclusion }}</td>
33+
<td class="align-middle text-center">{{ image.diagnostic }}</td>
3434
<td class="align-middle text-center">
3535
<a class="btn btn-warning btn-sm" role="button" href="dashboard?id={{image.id}}"><i
3636
class="fa-solid fa-draw-polygon"></i>

0 commit comments

Comments
 (0)