aboutsummaryrefslogtreecommitdiff
path: root/gn2/wqflask
diff options
context:
space:
mode:
authorAlexander_Kabui2024-08-30 17:22:00 +0300
committerAlexander_Kabui2024-08-30 17:22:00 +0300
commitf0ccf6271a577dd55f88733b2a4841b579576fe6 (patch)
tree4a5754720a95e917369a1963c87d75c37b5e3000 /gn2/wqflask
parent39cb5deed5f33122ea2cc8502945f171367db5df (diff)
parented20621c23a9a41152f3d6a48334f2a31c018033 (diff)
downloadgenenetwork2-f0ccf6271a577dd55f88733b2a4841b579576fe6.tar.gz
fix merge conflict
Diffstat (limited to 'gn2/wqflask')
-rw-r--r--gn2/wqflask/requests.py10
-rw-r--r--gn2/wqflask/templates/base.html3
-rw-r--r--gn2/wqflask/templates/gnqa.html10
-rw-r--r--gn2/wqflask/templates/gnqa_answer.html33
-rw-r--r--gn2/wqflask/templates/gnqa_search_history.html46
-rw-r--r--gn2/wqflask/views.py69
6 files changed, 87 insertions, 84 deletions
diff --git a/gn2/wqflask/requests.py b/gn2/wqflask/requests.py
index 43c8001f..182201a5 100644
--- a/gn2/wqflask/requests.py
+++ b/gn2/wqflask/requests.py
@@ -14,3 +14,13 @@ def get(url, params=None, **kwargs) -> Either:
def post(url, data=None, json=None, **kwargs) -> Either:
"""Wrap requests post method with Either monad"""
return __wrap_response__(requests.post(url, data=data, json=json, **kwargs))
+
+
+def put(url, data=None, json=None, **kwargs) -> Either:
+ """Wrap requests put method with Either monad"""
+ return __wrap_response__(requests.put(url, data=data, json=json, **kwargs))
+
+
+def delete(url, **kwargs) -> Either:
+ """Wrap requests delete method with Either monad"""
+ return __wrap_response__(requests.delete(url, **kwargs))
diff --git a/gn2/wqflask/templates/base.html b/gn2/wqflask/templates/base.html
index eb4e9e91..6c545646 100644
--- a/gn2/wqflask/templates/base.html
+++ b/gn2/wqflask/templates/base.html
@@ -183,11 +183,10 @@
</div>
<!-- todo fix text overlap for this;;responsiveness-->
- <!-- this functionality is currently use;ga.genenetwork.org/gnqna
<span style="padding: 5px;margin-left: 65px;" id="gnqna_home">
<a href="/gnqna">GNQA Search</a>
</span>
- -->
+
<span style="padding: 5px;margin-left: 65px;" >
<a style="text-decoration: none" target="_blank" href="/search-syntax">
<i style="text-align: center;color:#336699;;" class="fa fa-question-circle fa-2x" title="see more search hints" aria-hidden="true"></i>
diff --git a/gn2/wqflask/templates/gnqa.html b/gn2/wqflask/templates/gnqa.html
index 1268ef39..b3bc74fd 100644
--- a/gn2/wqflask/templates/gnqa.html
+++ b/gn2/wqflask/templates/gnqa.html
@@ -93,7 +93,7 @@
AI Search
<small>
<sup>
- <button class="search-hist-btn" hx-get="/gnqna/hist/" hx-target="#swap" hx-swap="innerHTML" >
+ <button class="search-hist-btn" hx-get="/gnqna/hist" hx-target="#swap" hx-swap="innerHTML">
[Search History]
</button>
</sup>
@@ -107,7 +107,7 @@
<button class="btn btn-default btn-sm col-xs-1 col-sm-1 col-sm-offset-3"
hx-post="/gnqna"
hx-target="#swap"
- hx-swap="innerHTML"
+ hx-swap="innerHTML"
hx-indicator="#indicator">
<i class="fa fa-search fa-3x" aria-hidden="true" title="Search"></i>
<img id="indicator" class="htmx-indicator" src="/static/gif/loader.gif"/>
@@ -118,12 +118,8 @@
type="text" autocomplete="on"
required
placeholder="Ask More Questions or Topics (E.g Genes)"
- value=''
+ value=''
name="querygnqa"
- hx-post="/gnqna"
- hx-target="#swap"
- hx-swap="innerHTML"
- hx-indicator="#indicator"
/>
</div>
</form>
diff --git a/gn2/wqflask/templates/gnqa_answer.html b/gn2/wqflask/templates/gnqa_answer.html
index 0ddcfde7..41c1b338 100644
--- a/gn2/wqflask/templates/gnqa_answer.html
+++ b/gn2/wqflask/templates/gnqa_answer.html
@@ -3,10 +3,10 @@
<div class="row container gnqa-answer" style="margin-bottom: 1em">
<p class="row lead">
<mark style="font-family: 'Linux Libertine','Georgia','Times','Source Serif Pro',serif;"><b><i>{{ query }}</i></b></mark><br/>
- {{ answer }}
+ {{ answer|safe }}
</p>
<div class="rating row" data-doc-id="{{query}}">
- <button class="btn" id="upvote" data-toggle="tooltip" data-placement="top" title="Vote Up"><i class="fa fa-thumbs-up fa-sm fa-1x" aria-hidden="true"></i></button>
+ <button class="btn" id="upvote" data-toggle="tooltip" data-placement="top" title="Vote Up"><i class="fa fa-thumbs-up fa-sm fa-1x" aria-hidden="true"></i></button>
<button class="btn" id="downvote" data-toggle="tooltip" data-placement="top" title="Vote Down"><i class="fa fa-thumbs-down fa-sm fa-1x" aria-hidden="true"></i></button>
<sub id="rate" class="text-info">
</sub>
@@ -32,7 +32,7 @@
</div>
<div id="collapse{{reference.doc_id}}" class="panel-collapse collapse in" role="tabpanel" aria-labelledby="heading{{reference.doc_id}}">
<div class="panel-body">
- <p class="node-references">{{ reference.comboTxt }}</p>
+ <p class="node-references">{{ reference.comboTxt|safe }}</p>
<div>
{% if reference.pubmed %}
<details open>
@@ -60,7 +60,7 @@
</div>
<div id="collapse{{reference.doc_id}}" class="panel-collapse collapse" role="tabpanel" aria-labelledby="heading{{reference.doc_id}}">
<div class="panel-body">
- <p class="node-references">{{reference.comboTxt}}</p>
+ <p class="node-references">{{ reference.comboTxt|safe }}</p>
<div>
{% if reference.pubmed %}
<details >
@@ -93,20 +93,27 @@
{% block js %}
<script>
+ function updateRatingHandler(target, responseObj, args){
+ let {status, response} = responseObj.xhr
+ if (status==200 && args == "upvote"){
+ htmx.toggleClass(htmx.find('#upvote'), 'btn-success');
+ htmx.removeClass(htmx.find("#downvote"), "btn-danger");
+ }
+ else if(status == 200 && args == "downvote") {
+ htmx.toggleClass(htmx.find('#downvote'), 'btn-danger');
+ htmx.removeClass(htmx.find("#upvote"), "btn-success");
+ }
+ else {
+ alert(`Error occurred with status ${status} and Error ${response}` )
+}}
var query = {{ query|tojson }};
var answer = {{ answer|tojson }}
var {task_id} = {{ task_id|tojson }}
- htmx.on("#upvote", "click", function(evt){
+htmx.on("#upvote", "click", function(evt){
vote_count = htmx.find(".btn-success") ? 0 : 1
- htmx.ajax("POST", `/gnqna/rating/${task_id}/${vote_count}`, {target: "#rate", swap:"innerHTML",values: {'query': query, 'answer': answer}}).then(()=>{
- htmx.toggleClass(htmx.find('#upvote'), 'btn-success');
- htmx.removeClass(htmx.find("#downvote"), "btn-danger");
-})});
+ htmx.ajax("POST", `/gnqna/rating/${task_id}/${vote_count}`, {target: "#rate", handler: (target,obj)=> updateRatingHandler(target,obj,"upvote"), swap:"innerHTML",values: {'query': query, 'answer': answer}})});
htmx.on("#downvote", "click", function(evt){
vote_count = htmx.find(".btn-danger") ? 0 : -1
- htmx.ajax("POST", `/gnqna/rating/${task_id}/${vote_count}`, {target: "#rate", swap:"innerHTML",values: {'query': query, 'answer': answer}}).then(()=>{
- htmx.toggleClass(htmx.find('#downvote'), 'btn-danger');
- htmx.removeClass(htmx.find("#upvote"), "btn-success")
- })});
+ htmx.ajax("POST", `/gnqna/rating/${task_id}/${vote_count}`, {target: "#rate",handler: (target,obj)=> updateRatingHandler(target,obj,"downvote") , swap:"innerHTML",values: {'query': query, 'answer': answer}})});
</script>
{% endblock %}
diff --git a/gn2/wqflask/templates/gnqa_search_history.html b/gn2/wqflask/templates/gnqa_search_history.html
index 2c07b8c0..976fd7fd 100644
--- a/gn2/wqflask/templates/gnqa_search_history.html
+++ b/gn2/wqflask/templates/gnqa_search_history.html
@@ -1,42 +1,52 @@
-<section class="container-fluid gnqa-copy">
+<section class="container-fluid gnqa-copy" id="search-hist">
<header class="row">
-
<div class="panel panel default col-sm-6 col-sm-offset-3">
<div class="panel panel-default">
<div class="panel-heading">
<div>
- <h4 class="text-primary">You search History </h4>
+ <h4 class="text-secondary" style="font-family: 'Linux Libertine','Georgia','Times','Source Serif Pro',serif;font-size:2.3rem">Your AI search History </h4>
</div>
</div>
</div>
</div>
</header>
<div class="container row">
- <div class="panel panel-default col-sm-6 col-sm-offset-3 ">
- {% for record in prev_queries %}
- <div class="panel-body">
- <div class="row">
- <input name="" type="checkbox" value="" class="col-sm-1">
+ <div>
+ <div class="col-sm-6 col-sm-offset-3" style="margin-bottom:10px">
+ <button type="button" class="btn btn-danger" id="delete-btn">Delete Selected </button>
+ </div>
+ <div >
+ <div class="panel panel-default col-sm-6 col-sm-offset-3 ">
+ <div>
+ <ul class="list-group list-group-flush" style="overflow-y:scroll">
+ {% for item in prev_queries %}
+ <li class="row list-group-item">
+ <input name="" type="checkbox" value="{{item['task_id']}}" class="col-sm-1" style="height: 20px;
+ width: 20px;">
<div class="col-sm-10">
- {% for id,val in record.items() %}
<button
- hx-get="/gnqna/hist/search/{{id}}"
+ hx-get="/gnqna/hist?query={{item['query']}}&search_term={{item['task_id']}}"
hx-target="#swap"
hx-swap="innerHTML"
hx-trigger= "click"
data-bs-toggle="tooltip"
data-bs-placement="left"
- title="/gnqna/hist/search?{{id}}"
+ title="/gnqna/hist?query={{item['query']}}&search_term={{item['task_id']}}"
style="background:transparent;border:none;cursor:pointer"
>
- <b class="text-info">{{val}} </b>
+ <p class="text-info">{{item.get('query')}} </p>
</button>
- {% endfor %}
- </div>
- </div>
- </div>
- {% endfor %}
+ </div>
+ </li>
+ {% endfor %}
+ </ul>
</div>
</div>
</div>
- </section>
+</section>
+<script>
+ htmx.on("#delete-btn", "click", function(evt){
+ htmx.ajax("DELETE","/gnqna/hist", {target: "#search-hist","swap" :"outerHTML",
+ values: Array.from(htmx.findAll("input[type=checkbox]:checked"), e => e.value)})
+ })
+</script>
diff --git a/gn2/wqflask/views.py b/gn2/wqflask/views.py
index 995b2b31..4421011b 100644
--- a/gn2/wqflask/views.py
+++ b/gn2/wqflask/views.py
@@ -261,35 +261,22 @@ def gsearchtable():
return flask.jsonify(current_page)
-"""@app.route("/gnqna", methods=["POST", "GET"]) ;;feature currently disabled
-;;use ga.genenetwork.org
+@app.route("/gnqna", methods=["POST", "GET"])
@require_oauth2
-"""
-
-
def gnqna():
-
if request.method == "POST":
try:
- def __error__(resp):
- return resp.json()
-
def error_page(resp):
return render_template("gnqa_errors.html",
**{"status_code": resp.status_code, **resp.json()})
def __success__(resp):
return render_template("gnqa_answer.html", **{"gn_server_url": GN3_LOCAL_URL, **(resp.json())})
- """
- disable gn-auth currently not stable
- if not user_logged_in():
- return error_page("Please Login/Register to Genenetwork to access this Service")
- """
token = session_info()["user"]["token"].either(
lambda err: err, lambda tok: tok["access_token"])
- return monad_requests.post(
+ return monad_requests.put(
urljoin(GN3_LOCAL_URL,
- "/api/llm/gnqna"),
+ "/api/llm/search"),
json=dict(request.form),
headers={
"Authorization": f"Bearer {token}"
@@ -300,14 +287,7 @@ def gnqna():
error_page, __success__)
except Exception as error:
return flask.jsonify({"error": str(error)})
- prev_queries = (monad_requests.get(
- urljoin(GN3_LOCAL_URL,
- "/api/llm/get_hist_names")
- ).then(
- lambda resp: resp
- ).either(lambda x: [], lambda x: x.json()["prev_queries"]))
-
- return render_template("gnqa.html", prev_queries=prev_queries)
+ return render_template("gnqa.html")
@app.route("/editor/edit", methods=["GET"])
@@ -343,34 +323,35 @@ def commit_gn_doc():
return render_template("gn_editor_results_page.html", **data)
-@app.route("/gnqna/hist/", methods=["GET"])
-@require_oauth2
-def get_hist_titles():
- token = session_info()["user"]["token"].either(
- lambda err: err, lambda tok: tok["access_token"])
- response = monad_requests.get(urljoin(GN3_LOCAL_URL,
- "/api/llm/hist/titles"),
- headers={
- "Authorization": f"Bearer {token}"
- }
- ).then(lambda resp: resp).either(
- lambda x: x.json(), lambda x: x.json())
- return render_template("gnqa_search_history.html", **response)
-
-
-@app.route("/gnqna/hist/search/<search_term>", methods=["GET"])
+@app.route("/gnqna/hist", methods=["GET", "DELETE"])
@require_oauth2
-def fetch_hist_records(search_term):
+def get_gnqa_history():
+ def _error_(resp):
+ return render_template("gnqa_errors.html",
+ **{"status_code": resp.status_code,
+ **resp.json()})
token = session_info()["user"]["token"].either(
lambda err: err, lambda tok: tok["access_token"])
+ if request.method == "DELETE":
+ monad_requests.delete(urljoin(GN3_LOCAL_URL, "/api/llm/history"),
+ json=dict(request.form),
+ headers={
+ "Authorization": f"Bearer {token}"
+ }
+ ).either(
+ _error_, lambda x: x.json())
response = monad_requests.get(urljoin(GN3_LOCAL_URL,
- f"/api/llm/history/{search_term}"),
+ (f"/api/llm/history?search_term={request.args.get('search_term')}"
+ if request.args.get("search_term") else "/api/llm/history")),
headers={
"Authorization": f"Bearer {token}"
}
).then(lambda resp: resp).either(
- lambda x: x.json(), lambda x: x.json())
- return render_template("gnqa_answer.html", **response)
+ _error_, lambda x: x.json())
+ if request.args.get("search_term"):
+ return render_template("gnqa_answer.html", **response)
+ return render_template("gnqa_search_history.html",
+ prev_queries=response)
@app.route("/gnqna/rating/<task_id>/<int(signed=True):weight>",