Skip to content

Commit 96d2d90

Browse files
authored
Merge pull request #155 from gyorilab/ner_download
Add NER download as CSV option in web UI
2 parents f417b77 + f1a991a commit 96d2d90

File tree

2 files changed

+58
-1
lines changed

2 files changed

+58
-1
lines changed

gilda/app/templates/ner_matches.html

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,16 @@
77

88
<div class="panel panel-default">
99
<div class="panel-heading">
10-
<h3 class="panel-title">Named Entity Recognition Results</h3>
10+
<div class="row">
11+
<div class="col-md-6">
12+
<h3 class="panel-title">Named Entity Recognition Results</h3>
13+
</div>
14+
<div class="col-md-6 text-right">
15+
<button onclick="download_csv()" class="btn btn-primary">
16+
<i class="fas fa-download"></i> Download CSV
17+
</button>
18+
</div>
19+
</div>
1120
</div>
1221
<div class="panel-body">
1322
<blockquote>
@@ -53,4 +62,19 @@ <h3 class="panel-title">Named Entity Recognition Results</h3>
5362
</tbody>
5463
</table>
5564
</div>
65+
66+
<script>
67+
function download_csv() {
68+
const csvData = `{{ csv_data | safe }}`;
69+
const blob = new Blob([csvData], { type: 'text/csv' });
70+
const url = window.URL.createObjectURL(blob);
71+
const a = document.createElement('a');
72+
a.setAttribute('hidden', '');
73+
a.setAttribute('href', url);
74+
a.setAttribute('download', 'ner_results.csv');
75+
document.body.appendChild(a);
76+
a.click();
77+
document.body.removeChild(a);
78+
}
79+
</script>
5680
{% endblock %}

gilda/app/ui.py

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
11
from textwrap import dedent
2+
import csv
3+
from io import StringIO
24

35
from flask import Blueprint, render_template, request
46
from flask_wtf import FlaskForm
@@ -110,11 +112,42 @@ def view_ner():
110112
form = NERForm()
111113
if form.validate_on_submit():
112114
annotations = form.get_annotations()
115+
116+
# Generate CSV data
117+
si = StringIO()
118+
writer = csv.writer(si)
119+
writer.writerow([
120+
"Start", "End", "Text", "Grounding", "Standard Name", "Score",
121+
"Additional Groundings"
122+
])
123+
124+
# Write data
125+
for annotation in annotations:
126+
match = annotation.matches[0]
127+
match_curie = match.term.get_curie()
128+
additional_groundings = ", ".join(
129+
curie for curie in match.get_grounding_dict().keys()
130+
if curie != match_curie
131+
)
132+
133+
writer.writerow([
134+
f"{annotation.start}",
135+
f"{annotation.end}",
136+
annotation.text,
137+
match_curie,
138+
match.term.entry_name,
139+
f"{match.score:.4f}",
140+
additional_groundings
141+
])
142+
143+
csv_data = si.getvalue()
144+
113145
return render_template(
114146
"ner_matches.html",
115147
annotations=annotations,
116148
version=version,
117149
text=form.text.data,
150+
csv_data=csv_data,
118151
# Add a new form that doesn't auto-populate
119152
form=NERForm(formdata=None),
120153
)

0 commit comments

Comments
 (0)