diff options
author | Alexander Kabui | 2024-09-06 11:17:34 +0300 |
---|---|---|
committer | GitHub | 2024-09-06 11:17:34 +0300 |
commit | a221d82a16428012a577924279af262a9c9f67a4 (patch) | |
tree | 15dce78331b9b9cd775bcf73f0be204095f598aa /gn2/wqflask | |
parent | fdf14becd8913d0e53cfad45bc4045a77e718769 (diff) | |
parent | 8b45ac5e26a1dd266b0de9bb442afe50169739c6 (diff) | |
download | genenetwork2-a221d82a16428012a577924279af262a9c9f67a4.tar.gz |
Merge pull request #863 from genenetwork/chores/merge-gnqa-systems
Chores/merge gnqa systems
Diffstat (limited to 'gn2/wqflask')
-rw-r--r-- | gn2/wqflask/requests.py | 10 | ||||
-rw-r--r-- | gn2/wqflask/templates/base.html | 3 | ||||
-rw-r--r-- | gn2/wqflask/templates/gnqa.html | 145 | ||||
-rw-r--r-- | gn2/wqflask/templates/gnqa_answer.html | 277 | ||||
-rw-r--r-- | gn2/wqflask/templates/gnqa_search_history.html | 106 | ||||
-rw-r--r-- | gn2/wqflask/views.py | 123 |
6 files changed, 404 insertions, 260 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..158b0b4e 100644 --- a/gn2/wqflask/templates/gnqa.html +++ b/gn2/wqflask/templates/gnqa.html @@ -1,9 +1,7 @@ {% extends "base.html" %} {% block title %}GNQA{% endblock %} - {% block css %} -<style> - + <style> .htmx-indicator{ display:none; opacity: 0; @@ -82,79 +80,78 @@ background-color: #ccf; } -</style> + </style> {% endblock %} - {% block search %}{% endblock %} -{% block content %} <!-- Start of body --> -<section class="container-fluid"> - <header class="row"> - <h1 class="col-sm-12 text-center search-header"> - AI Search - <small> - <sup> - <button class="search-hist-btn" hx-get="/gnqna/hist/" hx-target="#swap" hx-swap="innerHTML" > - [Search History] - </button> - </sup> - </small> - </h1> - </header> - <form class="row form-horizontal" id="gnqna_search_home" - action="/gnqna" method="POST"> - <!--- init gnqa codebase here --> - <div class="form-group form-group-lg col col-xs-12 col-sm-6 col-sm-offset-3"> - <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-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"/> - </button> - <input - class="text-left input-lg col-sm-5" - id="gnqna_search_home_input" - type="text" autocomplete="on" - required - placeholder="Ask More Questions or Topics (E.g Genes)" - value='' - name="querygnqa" - hx-post="/gnqna" - hx-target="#swap" - hx-swap="innerHTML" - hx-indicator="#indicator" - /> - </div> - </form> - <article id="swap" class="row"> - <div class="row gnqa-copy"> - <p class="col-sm-10 col-sm-offset-1 col-md-offset-3 col-md-6"> - Welcome to the GeneNetwork Question and Answer (GNQA)system. We utilize a large language model and 3000 scientific publications to make GNQA a subject matter expert in three areas: <b><a href="/">GeneNetwork.org </a></b>, <b>genomics/genetics with regards to diabetes</b> and <b>genomics/genetics with regards to agin.</b>. - </p> - <p class="col-sm-11 col-md-offset-3 col-md-6">At the moment when you ask GNQA something it will attempt to return a sensible answer with <q>real</q> references. To this end we aim to reduce hallucinations and provide a knowledge launchpad for a researcher to enhance their knowledge on the relevant subject matter.</p> - <p class="col-sm-11 col-md-offset-3 col-md-6"> - GNQA is not a finished product as we are working diligently to improve it daily. - </p> - <p class="col-sm-11 col-md-offset-3 col-md-6"><b>Thanks for using GNQA!</b> </p> - - </div> - </article> -</section> - -{% endblock %} - -{% block js %} -<script src="{{ url_for('js', filename='jquery/jquery.min.js') }}" type="text/javascript"></script> - -<script language="javascript" type="text/javascript" src="{{ url_for('js', filename='jquery-ui/jquery-ui.min.js') }}"></script> - -<script language="javascript" type="text/javascript" src="{{ url_for('js', filename='htmx.min.js') }}"></script> - -<script type="text/javascript"> +{% block content %} + <!-- Start of body --> + <section class="container-fluid"> + <header class="row"> + <h1 class="col-sm-12 text-center search-header"> + AI Search + <small> + <sup> + <button class="search-hist-btn" + hx-get="/gnqna/records" + hx-target="#swap" + hx-swap="innerHTML">[Search History]</button> + </sup> + </small> + </h1> + </header> + <form class="row form-horizontal" + id="gnqna_search_home" + action="/gnqna" + method="post"> + <!--- init gnqa codebase here --> + <div class="form-group form-group-lg col col-xs-12 col-sm-6 col-sm-offset-3"> + <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-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" /> + </button> + <input class="text-left input-lg col-sm-5" + id="gnqna_search_home_input" + type="text" + autocomplete="on" + required + placeholder="Ask More Questions or Topics (E.g Genes)" + value='' + name="querygnqa" /> + </div> + </form> + <article id="swap" class="row"> + <div class="row gnqa-copy"> + <div class="col-sm-10 col-sm-offset-1 col-md-offset-3 col-md-6"> + <p> + Welcome to the GeneNetwork Question and Answer (GNQA)system. We utilize a large language model and 3000 scientific publications to make GNQA a subject matter expert in three areas: <b><a href="/">GeneNetwork.org</a></b>, <b>genomics/genetics with regards to diabetes</b> and <b>genomics/genetics with regards to agin.</b>. + </p> + <p> + At the moment when you ask GNQA something it will attempt to return a sensible answer with <q>real</q> references. To this end we aim to reduce hallucinations and provide a knowledge launchpad for a researcher to enhance their knowledge on the relevant subject matter. + </p> + <p>GNQA is not a finished product as we are working diligently to improve it daily.</p> + <p> + <b>Thanks for using GNQA!</b> + </p> + <div></div> + </article> + </section> + {% endblock %} + {% block js %} + <script src="{{ url_for('js', filename='jquery/jquery.min.js') }}" + type="text/javascript"></script> + <script language="javascript" + type="text/javascript" + src="{{ url_for('js', filename='jquery-ui/jquery-ui.min.js') }}"></script> + <script language="javascript" + type="text/javascript" + src="{{ url_for('js', filename='htmx.min.js') }}"></script> + <script type="text/javascript"> document.addEventListener('DOMContentLoaded', function() { $('footer').hide() }); -</script> -{% endblock %} - + </script> + {% endblock %} diff --git a/gn2/wqflask/templates/gnqa_answer.html b/gn2/wqflask/templates/gnqa_answer.html index 0ddcfde7..7a637b20 100644 --- a/gn2/wqflask/templates/gnqa_answer.html +++ b/gn2/wqflask/templates/gnqa_answer.html @@ -1,112 +1,191 @@ - <section class="container-fluid answers gnqa-copy"> <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 }} - </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="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> - </div> + <p class="row lead"> + <mark style="font-family: 'Linux Libertine','Georgia','Times','Source Serif Pro',serif"><b><i>{{ query }}</i></b></mark> + <br /> + {{ 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="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> + </div> </div> <div class="row container"> - <details open> - <summary><h3 style="font-family: 'Linux Libertine','Georgia','Times','Source Serif Pro',serif;">References</h3></summary> - {% if references %} - <ul class="list-unstyled"> - {% for reference in references %} - <li> - <div class="panel-group" role="tablist" aria-multiselectable="true" style="margin-bottom:0;"> - <div class="panel panel-default"> - {% if loop.first %} - <div class="panel-heading active" role="tab" id="heading{{ reference.doc_id }}"> - <h4 class="panel-title" style="font-family: 'Linux Libertine','Georgia','Times','Source Serif Pro',serif;"> - - <a class="collapsed" role="button" data-toggle="collapse" data-parent="#accordion" href="#collapse{{ reference.doc_id }}" aria-expanded="true" aria-controls="collapse{{reference.doc_id}}"> - {{ reference.bibInfo }} - </a> - </h4> - </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> - <div> - {% if reference.pubmed %} - <details open> - <summary>See PubMed Info</summary> - <div style="font-family: 'Linux Libertine','Georgia','Times','Source Serif Pro',serif;margin-top:1.4em"> - <h3><b>{{ reference.pubmed[0].get('title') }}:</b></h3> - <p><b>Authors:</b><span class="text-muted">{{ reference.pubmed[0].get('authors') }}</span></p> - <p><b>PMID: <span class="text-info">{{ reference.pubmed[0].get('pub_id') }}</span></b></p> - <p><b>Abstract: </b></p> - <p>{{ reference.pubmed[0].get('abstract')|safe }}</p> - <p><a href="{{reference.pubmed[0].get('source')}}" target="_blank">See full Article on Pubmed</a></p> - </div> - </details> - {% endif %} - </div> - </div> - {% else %} - <div class="panel-heading" role="tab" id="heading{{reference.doc_id}}"> - <h4 class="panel-title" style="font-family: 'Linux Libertine','Georgia','Times','Source Serif Pro',serif;"> - - <a class="collapsed" role="button" data-toggle="collapse" data-parent="#accordion" href="#collapse{{reference.doc_id}}" aria-expanded="false" aria-controls="collapse{{reference.doc_id}}"> - {{ reference.bibInfo }} - </a> - </h4> - </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> - <div> - {% if reference.pubmed %} - <details > - <summary>See PubMed Info</summary> - <div style="font-family: 'Linux Libertine','Georgia','Times','Source Serif Pro',serif;margin-top:1.4em"> - <h3><b>{{ reference.pubmed[0].get('title') }}:</b></h3> - <p><b>Authors:</b><span class="text-muted">{{ reference.pubmed[0].get('authors') }}</span></p> - <p><b>PMID: <span class="text-info">{{ reference.pubmed[0].get('pub_id') }}</span></b></p> - <p><b>Abstract: </b></p> - <p>{{ reference.pubmed[0].get('abstract')|safe }}</p> - <p><a href="{{reference.pubmed[0].get('source')}}" target="_blank" style="float:left;">See full Article on Pubmed</a></p> - </div> - </details> - {% endif %} - </div> - </div> - </div> - {% endif %} - </div> - </div> - </li> - {% endfor %} - </ul> - {% else %} - <p><i>No references available.</i></p> - {% endif %} - </details> - </div> + <details open> + <summary> + <h3 style="font-family: 'Linux Libertine','Georgia','Times','Source Serif Pro',serif">References</h3> + </summary> + {% if references %} + <ul class="list-unstyled"> + {% for reference in references %} + <li> + <div class="panel-group" + role="tablist" + aria-multiselectable="true" + style="margin-bottom:0"> + <div class="panel panel-default"> + {% if loop.first %} + <div class="panel-heading active" + role="tab" + id="heading{{ reference.doc_id }}"> + <h4 class="panel-title" + style="font-family: 'Linux Libertine','Georgia','Times','Source Serif Pro',serif"> + <a class="collapsed" + role="button" + data-toggle="collapse" + data-parent="#accordion" + href="#collapse{{ reference.doc_id }}" + aria-expanded="true" + aria-controls="collapse{{ reference.doc_id }}"> + {{ reference.bibInfo }} + </a> + </h4> + </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|safe }}</p> + <div> + {% if reference.pubmed %} + <details open> + <summary>See PubMed Info</summary> + <div style="font-family: 'Linux Libertine','Georgia','Times','Source Serif Pro',serif; + margin-top:1.4em"> + <h3> + <b>{{ reference.pubmed[0].get("title") }}:</b> + </h3> + <p> + <b>Authors:</b><span class="text-muted">{{ reference.pubmed[0].get("authors") }}</span> + </p> + <p> + <b>PMID: <span class="text-info">{{ reference.pubmed[0].get("pub_id") }}</span></b> + </p> + <p> + <b>Abstract: </b> + </p> + <p>{{ reference.pubmed[0].get("abstract") |safe }}</p> + <p> + <a href="{{ reference.pubmed[0].get("source") }}" target="_blank">See full Article on Pubmed</a> + </p> + </div> + </details> + {% endif %} + </div> + </div> + {% else %} + <div class="panel-heading" role="tab" id="heading{{ reference.doc_id }}"> + <h4 class="panel-title" + style="font-family: 'Linux Libertine','Georgia','Times','Source Serif Pro',serif"> + <a class="collapsed" + role="button" + data-toggle="collapse" + data-parent="#accordion" + href="#collapse{{ reference.doc_id }}" + aria-expanded="false" + aria-controls="collapse{{ reference.doc_id }}"> + {{ reference.bibInfo }} + </a> + </h4> + </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|safe }}</p> + <div> + {% if reference.pubmed %} + <details> + <summary>See PubMed Info</summary> + <div style="font-family: 'Linux Libertine','Georgia','Times','Source Serif Pro',serif; + margin-top:1.4em"> + <h3> + <b>{{ reference.pubmed[0].get("title") }}:</b> + </h3> + <p> + <b>Authors:</b><span class="text-muted">{{ reference.pubmed[0].get("authors") }}</span> + </p> + <p> + <b>PMID: <span class="text-info">{{ reference.pubmed[0].get("pub_id") }}</span></b> + </p> + <p> + <b>Abstract: </b> + </p> + <p>{{ reference.pubmed[0].get("abstract") |safe }}</p> + <p> + <a href="{{ reference.pubmed[0].get("source") }}" + target="_blank" + style="float:left">See full Article on Pubmed</a> + </p> + </div> + </details> + {% endif %} + </div> + </div> + </div> + {% endif %} + </div> + </div> + </li> + {% endfor %} + </ul> + {% else %} + <p> + <i>No references available.</i> + </p> + {% endif %} + </details> + </div> + </div> </section> {% block js %} - -<script> + <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") - })}); -</script> + 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..8d54ad80 100644 --- a/gn2/wqflask/templates/gnqa_search_history.html +++ b/gn2/wqflask/templates/gnqa_search_history.html @@ -1,42 +1,66 @@ -<section class="container-fluid gnqa-copy"> - <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> - </div> - </div> - </div> +<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-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> + <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"> + <button hx-get="/gnqna/record?query={{ item['query'] }}&search_task_id={{ item['task_id'] }}" + hx-target="#swap" + hx-swap="innerHTML" + hx-trigger="click" + data-bs-toggle="tooltip" + data-bs-placement="left" + title="/gnqna/record?query={{ item['query'] }}&search_task_id={{ item['task_id'] }}" + style="background:transparent; + border:none; + cursor:pointer"> + <p class="text-info">{{ item["query"] }}</p> + </button> + </div> + </li> + {% endfor %} + </ul> + </div> + </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 class="col-sm-10"> - {% for id,val in record.items() %} - <button - hx-get="/gnqna/hist/search/{{id}}" - hx-target="#swap" - hx-swap="innerHTML" - hx-trigger= "click" - data-bs-toggle="tooltip" - data-bs-placement="left" - title="/gnqna/hist/search?{{id}}" - style="background:transparent;border:none;cursor:pointer" - > - <b class="text-info">{{val}} </b> - </button> - {% endfor %} - </div> - </div> - </div> - {% endfor %} - </div> - </div> - </div> - </section> +</section> +<script> + htmx.on("#delete-btn", "click", function(evt){ + htmx.ajax("DELETE","/gnqna/records", {target: "#search-hist", swap :"none", + handler: (target,obj) =>{ + htmx.ajax("GET", "gnqna/records", { + target: "#search-hist", + swap: "innerHTML" + }) + }, + 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 7e8cd901..7699c303 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}" @@ -299,15 +286,8 @@ def gnqna(): ).either( 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 flask.jsonify({"error": str(error)}), 500 + return render_template("gnqa.html") @app.route("/editor/edit", methods=["GET"]) @@ -343,34 +323,89 @@ def commit_gn_doc(): return render_template("gn_editor_results_page.html", **data) -@app.route("/gnqna/hist/", methods=["GET"]) +@app.route("/gnqna/records", methods=["GET"]) @require_oauth2 -def get_hist_titles(): +def get_gnqa_records(): + """Call the Api endpoint for fetching all gnqa records""" + def _error_(resp): + return render_template("gnqa_errors.html", + **{"status_code": resp.status_code, + **resp.json()}) + + def _success_(resp): + response = resp.json() + return render_template("gnqa_search_history.html", + prev_queries=response) 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) + response_url = "/api/llm/search/records" + return (monad_requests.get(urljoin(GN3_LOCAL_URL, response_url), + headers={ + "Authorization": f"Bearer {token}" + } + ).then(lambda resp: resp).either( + _error_, _success_)) -@app.route("/gnqna/hist/search/<search_term>", methods=["GET"]) +@app.route("/gnqna/record", methods=["GET"]) @require_oauth2 -def fetch_hist_records(search_term): +def get_gnqa_record_by_task_id(): + """Get specific record using task""" + def _error_(resp): + return render_template("gnqa_errors.html", + **{"status_code": resp.status_code, + **resp.json()}) + + def _success_(resp): + response = resp.json() + return render_template("gnqa_answer.html", **response) token = session_info()["user"]["token"].either( lambda err: err, lambda tok: tok["access_token"]) - response = monad_requests.get(urljoin(GN3_LOCAL_URL, - f"/api/llm/history/{search_term}"), + response_url = f"api/llm/search/record/{request.args.get('search_task_id')}" + return (monad_requests.get(urljoin(GN3_LOCAL_URL, response_url), + headers={ + "Authorization": f"Bearer {token}" + }).then(lambda resp: resp).either( + _error_, _success_)) + + +@app.route("/gnqna/records", methods=["DELETE"]) +@require_oauth2 +def delete_gnqa_records(): + """Call the Api endpoint for fetching all gnqa records""" + 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"]) + return (monad_requests.delete(urljoin(GN3_LOCAL_URL, + "/api/llm/search/records"), + json=dict(request.form), 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) + "Authorization": f"Bearer {token}"}) + .then(lambda resp: resp).either( + _error_, lambda x: x.json())) + + +@app.route("/gnqna/record", methods=["DELETE"]) +@require_oauth2 +def delete_gnqa_record_by_task_id(): + """Get specific record using task""" + 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"]) + response_url = f"api/llm/search/record/{request.args.get('search_task_id')}" + return (monad_requests.get(urljoin(GN3_LOCAL_URL, response_url), + headers={ + "Authorization": f"Bearer {token}"}).then(lambda resp: resp) + .either( + _error_, lambda x: x.json())) @app.route("/gnqna/rating/<task_id>/<int(signed=True):weight>", |