From 19e781e9f8dc8bfaeacfb3f86c3823fe4f6f1218 Mon Sep 17 00:00:00 2001 From: Munyoki Kilyungi Date: Tue, 14 May 2024 12:56:43 +0300 Subject: Revert "Disable gnqa functionality." This reverts commit 01eba6e9b54e45bc937983e33b439a353118de2c. --- gn2/wqflask/views.py | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) (limited to 'gn2/wqflask/views.py') diff --git a/gn2/wqflask/views.py b/gn2/wqflask/views.py index 9f403ace..843ed07a 100644 --- a/gn2/wqflask/views.py +++ b/gn2/wqflask/views.py @@ -255,12 +255,8 @@ 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": -- cgit v1.2.3 From 292f4ab25508ef2e72a0caac6e609317113be232 Mon Sep 17 00:00:00 2001 From: Alexander_Kabui Date: Wed, 22 May 2024 14:00:30 +0300 Subject: View file code cleanup for gnqa. --- gn2/wqflask/views.py | 46 ++++++++++------------------------------------ 1 file changed, 10 insertions(+), 36 deletions(-) (limited to 'gn2/wqflask/views.py') diff --git a/gn2/wqflask/views.py b/gn2/wqflask/views.py index 843ed07a..5d0075c5 100644 --- a/gn2/wqflask/views.py +++ b/gn2/wqflask/views.py @@ -258,23 +258,14 @@ def gsearchtable(): @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( @@ -290,44 +281,27 @@ 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) - - -@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) + return render_template("gnqa.html") -@app.route("/gnqna/hist/search/", methods=["GET"]) +@app.route("/gnqna/hist", methods=["GET"]) @require_oauth2 -def fetch_hist_records(search_term): +def get_gnqa_history(): 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}"), + (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) + if request.args.get("search_term"): + return render_template("gnqa_answer.html", + **{"gn_server_url": "GN3_LOCAL_URL", **response}) + return render_template("gnqa_search_history.html", + prev_queries=response) @app.route("/gnqna/rating//", -- cgit v1.2.3 From 13a554a9744bc70da9606c0348ec675276147a29 Mon Sep 17 00:00:00 2001 From: Alexander_Kabui Date: Thu, 23 May 2024 14:47:27 +0300 Subject: Update endpoints and add search history functionality. --- gn2/wqflask/templates/gnqa_search_history.html | 29 +++++++++++++------------- gn2/wqflask/views.py | 11 ++++++---- 2 files changed, 22 insertions(+), 18 deletions(-) (limited to 'gn2/wqflask/views.py') diff --git a/gn2/wqflask/templates/gnqa_search_history.html b/gn2/wqflask/templates/gnqa_search_history.html index af38392a..890a3995 100644 --- a/gn2/wqflask/templates/gnqa_search_history.html +++ b/gn2/wqflask/templates/gnqa_search_history.html @@ -1,39 +1,40 @@
-
-

You search History

+

Your AI search History

-
- {% for (key,val) in prev_queries.items() %} -
-
- +
+
+
    + {% for item in prev_queries %} +
  • +
    -
    -
-
- {% endfor %} +
+ + {% endfor %} +
diff --git a/gn2/wqflask/views.py b/gn2/wqflask/views.py index 5d0075c5..5bb443c1 100644 --- a/gn2/wqflask/views.py +++ b/gn2/wqflask/views.py @@ -270,7 +270,7 @@ def gnqna(): lambda err: err, lambda tok: tok["access_token"]) return monad_requests.post( urljoin(GN3_LOCAL_URL, - "/api/llm/gnqna"), + "/api/llm/search"), json=dict(request.form), headers={ "Authorization": f"Bearer {token}" @@ -287,6 +287,10 @@ def gnqna(): @app.route("/gnqna/hist", methods=["GET"]) @require_oauth2 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"]) response = monad_requests.get(urljoin(GN3_LOCAL_URL, @@ -296,10 +300,9 @@ def get_gnqa_history(): "Authorization": f"Bearer {token}" } ).then(lambda resp: resp).either( - lambda x: x.json(), lambda x: x.json()) + _error_, lambda x: x.json()) if request.args.get("search_term"): - return render_template("gnqa_answer.html", - **{"gn_server_url": "GN3_LOCAL_URL", **response}) + return render_template("gnqa_answer.html", **response) return render_template("gnqa_search_history.html", prev_queries=response) -- cgit v1.2.3 From c7b1210c1a8716ef045a1291bca76c1d822c134f Mon Sep 17 00:00:00 2001 From: Alexander_Kabui Date: Tue, 28 May 2024 17:51:59 +0300 Subject: BugFix: return correct status code for generic exceptions handler. --- gn2/wqflask/views.py | 1 + 1 file changed, 1 insertion(+) (limited to 'gn2/wqflask/views.py') diff --git a/gn2/wqflask/views.py b/gn2/wqflask/views.py index 5bb443c1..5bfcce83 100644 --- a/gn2/wqflask/views.py +++ b/gn2/wqflask/views.py @@ -137,6 +137,7 @@ def handle_generic_exceptions(e): stack={formatted_lines}, error_image=animation, version=current_app.config.get("GN_VERSION"))) + resp.status_code = exc_type.code or 500 resp.set_cookie(err_msg[:32], animation) return resp -- cgit v1.2.3 From 034b50502a6d15bccd52211a8bb282d46ac1558e Mon Sep 17 00:00:00 2001 From: Alexander_Kabui Date: Wed, 29 May 2024 12:47:12 +0300 Subject: Handle attributeError when getting error codes. --- gn2/wqflask/views.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'gn2/wqflask/views.py') diff --git a/gn2/wqflask/views.py b/gn2/wqflask/views.py index 5bfcce83..8f1c62ff 100644 --- a/gn2/wqflask/views.py +++ b/gn2/wqflask/views.py @@ -137,7 +137,10 @@ def handle_generic_exceptions(e): stack={formatted_lines}, error_image=animation, version=current_app.config.get("GN_VERSION"))) - resp.status_code = exc_type.code or 500 + try: + resp.status_code = exc_type.code + except AttributeError: + resp.status_code = 500 resp.set_cookie(err_msg[:32], animation) return resp -- cgit v1.2.3 From 30e5a84940bd9715bea02d07c5092bbfd717f7c5 Mon Sep 17 00:00:00 2001 From: Alexander_Kabui Date: Wed, 29 May 2024 14:05:44 +0300 Subject: integrate gnqa history delete functionality. --- gn2/wqflask/views.py | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) (limited to 'gn2/wqflask/views.py') diff --git a/gn2/wqflask/views.py b/gn2/wqflask/views.py index 8f1c62ff..666e765a 100644 --- a/gn2/wqflask/views.py +++ b/gn2/wqflask/views.py @@ -288,7 +288,8 @@ def gnqna(): return render_template("gnqa.html") -@app.route("/gnqna/hist", methods=["GET"]) + +@app.route("/gnqna/hist", methods=["GET", "DELETE"]) @require_oauth2 def get_gnqa_history(): def _error_(resp): @@ -297,6 +298,14 @@ def get_gnqa_history(): **resp.json()}) token = session_info()["user"]["token"].either( lambda err: err, lambda tok: tok["access_token"]) + if request.method == "DELETE": + monad_requests.post(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={request.args.get('search_term')}" if request.args.get("search_term") else "/api/llm/history")), -- cgit v1.2.3 From 0f4c9fbe37ed74022d9fad35352b59d948789818 Mon Sep 17 00:00:00 2001 From: Alexander Kabui Date: Wed, 28 Aug 2024 14:58:16 +0300 Subject: Revert "Feature/gnqa search history" --- gn2/wqflask/templates/gnqa.html | 4 +- gn2/wqflask/templates/gnqa_answer.html | 33 ++++++------- gn2/wqflask/templates/gnqa_search_history.html | 46 ++++++++---------- gn2/wqflask/views.py | 64 +++++++++++++++----------- 4 files changed, 70 insertions(+), 77 deletions(-) (limited to 'gn2/wqflask/views.py') diff --git a/gn2/wqflask/templates/gnqa.html b/gn2/wqflask/templates/gnqa.html index b3bc74fd..8b50fe43 100644 --- a/gn2/wqflask/templates/gnqa.html +++ b/gn2/wqflask/templates/gnqa.html @@ -93,7 +93,7 @@ AI Search - @@ -107,7 +107,7 @@ + @@ -32,7 +32,7 @@
-

{{ reference.comboTxt|safe }}

+

{{ reference.comboTxt }}

{% if reference.pubmed %}
@@ -60,7 +60,7 @@
-

{{ reference.comboTxt|safe }}

+

{{reference.comboTxt}}

{% if reference.pubmed %}
@@ -93,27 +93,20 @@ {% block js %} {% endblock %} diff --git a/gn2/wqflask/templates/gnqa_search_history.html b/gn2/wqflask/templates/gnqa_search_history.html index 976fd7fd..2c07b8c0 100644 --- a/gn2/wqflask/templates/gnqa_search_history.html +++ b/gn2/wqflask/templates/gnqa_search_history.html @@ -1,52 +1,42 @@ -
+
+
-

Your AI search History

+

You search History

-
-
- -
-
-
-
-
    - {% for item in prev_queries %} -
  • - +
    + {% for record in prev_queries %} +
    +
    +
    + {% for id,val in record.items() %} -
    -
  • - {% endfor %} -
+ {% endfor %} +
+
+
+ {% endfor %}
-
- + diff --git a/gn2/wqflask/views.py b/gn2/wqflask/views.py index 666e765a..843ed07a 100644 --- a/gn2/wqflask/views.py +++ b/gn2/wqflask/views.py @@ -137,10 +137,6 @@ def handle_generic_exceptions(e): stack={formatted_lines}, error_image=animation, version=current_app.config.get("GN_VERSION"))) - try: - resp.status_code = exc_type.code - except AttributeError: - resp.status_code = 500 resp.set_cookie(err_msg[:32], animation) return resp @@ -262,19 +258,28 @@ def gsearchtable(): @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( urljoin(GN3_LOCAL_URL, - "/api/llm/search"), + "/api/llm/gnqna"), json=dict(request.form), headers={ "Authorization": f"Bearer {token}" @@ -285,39 +290,44 @@ def gnqna(): error_page, __success__) except Exception as error: return flask.jsonify({"error": str(error)}) - return render_template("gnqa.html") + 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) -@app.route("/gnqna/hist", methods=["GET", "DELETE"]) +@app.route("/gnqna/hist/", methods=["GET"]) @require_oauth2 -def get_gnqa_history(): - def _error_(resp): - return render_template("gnqa_errors.html", - **{"status_code": resp.status_code, - **resp.json()}) +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/", methods=["GET"]) +@require_oauth2 +def fetch_hist_records(search_term): token = session_info()["user"]["token"].either( lambda err: err, lambda tok: tok["access_token"]) - if request.method == "DELETE": - monad_requests.post(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={request.args.get('search_term')}" - if request.args.get("search_term") else "/api/llm/history")), + f"/api/llm/history/{search_term}"), headers={ "Authorization": f"Bearer {token}" } ).then(lambda resp: resp).either( - _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) + lambda x: x.json(), lambda x: x.json()) + return render_template("gnqa_answer.html", **response) @app.route("/gnqna/rating//", -- cgit v1.2.3 From 9671e9ef4bc20d562b831f97c52b40e91b1d4c20 Mon Sep 17 00:00:00 2001 From: Munyoki Kilyungi Date: Mon, 20 May 2024 12:55:52 +0300 Subject: Check metadata exists before setting 'editable' field in get_dataset. Signed-off-by: Munyoki Kilyungi --- gn2/wqflask/views.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'gn2/wqflask/views.py') diff --git a/gn2/wqflask/views.py b/gn2/wqflask/views.py index 843ed07a..a7bc8fa2 100644 --- a/gn2/wqflask/views.py +++ b/gn2/wqflask/views.py @@ -1230,8 +1230,8 @@ def get_dataset(name): lambda err: {"roles": []}, lambda val: val ) - - metadata["editable"] = "group:resource:edit-resource" in result["roles"] + if metadata: + metadata["editable"] = "group:resource:edit-resource" in result["roles"] return render_template( "dataset.html", name=name, -- cgit v1.2.3 From 6d6a22d592ec6f55a74769d5b9a13aea7eadfc8b Mon Sep 17 00:00:00 2001 From: zsloan Date: Wed, 3 Jul 2024 20:55:37 +0000 Subject: Add link to GeneCup to tool buttons This also includes a function for converting a list of traits/datasets to symbols, which was added to trait.py --- gn2/base/trait.py | 31 ++++++++++++++++++++++ gn2/base/webqtlConfig.py | 2 ++ .../static/new/javascript/search_results.js | 2 +- gn2/wqflask/templates/tool_buttons.html | 4 +++ gn2/wqflask/views.py | 24 ++++++++++++++--- 5 files changed, 58 insertions(+), 5 deletions(-) (limited to 'gn2/wqflask/views.py') diff --git a/gn2/base/trait.py b/gn2/base/trait.py index 701958d7..24288ba1 100644 --- a/gn2/base/trait.py +++ b/gn2/base/trait.py @@ -611,3 +611,34 @@ def retrieve_trait_info(trait, dataset, get_qtl_info=False): f"{repr(trait.name)} information is not found in the database " f"for dataset '{dataset.name}' with id '{dataset.id}'.") return trait + +def fetch_symbols(trait_db_list): + """ + Fetch list of trait symbols + + From a list of traits and datasets (where each item has + the trait and dataset name separated by a colon), return + + """ + + trimmed_trait_list = [trait_db for trait_db in trait_db_list + if 'Publish' not in trait_db and 'Geno' not in trait_db.split(":")[1]] + + symbol_list = [] + with database_connection(get_setting("SQL_URI")) as conn, conn.cursor() as cursor: + for trait_db in trimmed_trait_list: + symbol_query = """ + SELECT ps.Symbol + FROM ProbeSet as ps + INNER JOIN ProbeSetXRef psx ON psx.ProbeSetId = ps.Id + INNER JOIN ProbeSetFreeze psf ON psx.ProbeSetFreezeId = psf.Id + WHERE + ps.Name = %(trait_name)s AND + psf.Name = %(db_name)s + """ + + cursor.execute(symbol_query, {'trait_name': trait_db.split(":")[0], + 'db_name': trait_db.split(":")[1]}) + symbol_list.append(cursor.fetchone()[0]) + + return "+".join(symbol_list) \ No newline at end of file diff --git a/gn2/base/webqtlConfig.py b/gn2/base/webqtlConfig.py index 998c0efc..8018bf40 100644 --- a/gn2/base/webqtlConfig.py +++ b/gn2/base/webqtlConfig.py @@ -68,6 +68,8 @@ RGD_URL = "https://rgd.mcw.edu/rgdweb/elasticResults.html?term=%s&category=Gene& PHENOGEN_URL = "https://phenogen.org/gene.jsp?speciesCB=Rn&auto=Y&geneTxt=%s&genomeVer=rn7§ion=geneEQTL" RRID_MOUSE_URL = "https://www.jax.org/strain/%s" RRID_RAT_URL = "https://rgd.mcw.edu/rgdweb/report/strain/main.html?id=%s" +GENE_CUP_URL = "https://genecup.org/progress?type=GWAS&type=addiction&type=drug&type=brain&type=stress&type=psychiatric&type=cell&type=function&query=%s" + # Temporary storage (note that this TMPDIR can be set as an # environment variable - use utility.tools.TEMPDIR when you diff --git a/gn2/wqflask/static/new/javascript/search_results.js b/gn2/wqflask/static/new/javascript/search_results.js index 29050c2b..c89b4ce3 100644 --- a/gn2/wqflask/static/new/javascript/search_results.js +++ b/gn2/wqflask/static/new/javascript/search_results.js @@ -309,7 +309,7 @@ $(function() { return submit_special("/loading") }); - $("#send_to_webgestalt, #send_to_bnw, #send_to_geneweaver").on("click", function() { + $("#send_to_webgestalt, #send_to_bnw, #send_to_geneweaver, #send_to_genecup").on("click", function() { traits = getTraitsFromTable() $("#trait_list").val(traits) url = $(this).data("url") diff --git a/gn2/wqflask/templates/tool_buttons.html b/gn2/wqflask/templates/tool_buttons.html index c6d1476c..3e716d70 100644 --- a/gn2/wqflask/templates/tool_buttons.html +++ b/gn2/wqflask/templates/tool_buttons.html @@ -18,6 +18,10 @@ BNW + + diff --git a/gn2/wqflask/views.py b/gn2/wqflask/views.py index a7bc8fa2..152a1be6 100644 --- a/gn2/wqflask/views.py +++ b/gn2/wqflask/views.py @@ -46,12 +46,12 @@ from gn2.wqflask import search_results from gn2.wqflask import server_side # Used by YAML in marker_regression from gn2.base.data_set import create_dataset +from gn2.base.trait import fetch_symbols from gn2.wqflask.show_trait import show_trait from gn2.wqflask.show_trait import export_trait_data from gn2.wqflask.show_trait.show_trait import get_diff_of_vals from gn2.wqflask.heatmap import heatmap -from gn2.wqflask.external_tools import send_to_bnw -from gn2.wqflask.external_tools import send_to_webgestalt +from gn2.wqflask.external_tools import send_to_bnw, send_to_webgestalt from gn2.wqflask.external_tools import send_to_geneweaver from gn2.wqflask.comparison_bar_chart import comparison_bar_chart from gn2.wqflask.marker_regression import run_mapping @@ -88,8 +88,8 @@ from gn2.utility.redis_tools import get_redis_conn import gn2.utility.hmac as hmac -from gn2.base.webqtlConfig import TMPDIR -from gn2.base.webqtlConfig import GENERATED_IMAGE_DIR +from gn2.base.webqtlConfig import TMPDIR, GENERATED_IMAGE_DIR +from gn2.base.webqtlConfig import GENE_CUP_URL from gn2.wqflask.database import database_connection @@ -741,6 +741,22 @@ def geneweaver_page(): return rendered_template +@app.route("/genecup", methods=('POST',)) +def genecup_page(): + start_vars = request.form + + traits = [trait.strip() for trait in start_vars['trait_list'].split(',')] + + if traits[0] != "": + symbol_string = fetch_symbols(traits) + return redirect(GENE_CUP_URL % symbol_string) + else: + rendered_template = render_template( + "empty_collection.html", **{'tool': 'GeneWeaver'}) + + return rendered_template + + @app.route("/comparison_bar_chart", methods=('POST',)) def comp_bar_chart_page(): start_vars = request.form -- cgit v1.2.3 From a1eb080eca9611262f1a3fa4463d40653d6899c2 Mon Sep 17 00:00:00 2001 From: zsloan Date: Tue, 30 Jul 2024 20:56:14 +0000 Subject: Fix GN3 URIs for case attribute editing Also improve error logging somewhat (but still need to properly display the error in a template) --- gn2/wqflask/views.py | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) (limited to 'gn2/wqflask/views.py') diff --git a/gn2/wqflask/views.py b/gn2/wqflask/views.py index 152a1be6..9c1f7685 100644 --- a/gn2/wqflask/views.py +++ b/gn2/wqflask/views.py @@ -1362,7 +1362,7 @@ def edit_case_attributes(inbredset_id: int) -> Response: return monad_requests.post( urljoin( current_app.config["GN_SERVER_URL"], - f"/api/case-attribute/{inbredset_id}/edit"), + f"case-attribute/{inbredset_id}/edit"), json={ "edit-data": reduce(__process_data__, form.items(), {}) }, @@ -1374,29 +1374,33 @@ def edit_case_attributes(inbredset_id: int) -> Response: def __fetch_strains__(inbredset_group): return monad_requests.get(urljoin( current_app.config["GN_SERVER_URL"], - f"/api/case-attribute/{inbredset_id}/strains")).then( + f"case-attribute/{inbredset_id}/strains")).then( lambda resp: {**inbredset_group, "strains": resp.json()}) def __fetch_names__(strains): return monad_requests.get(urljoin( current_app.config["GN_SERVER_URL"], - f"/api/case-attribute/{inbredset_id}/names")).then( + f"case-attribute/{inbredset_id}/names")).then( lambda resp: {**strains, "case_attribute_names": resp.json()}) def __fetch_values__(canames): return monad_requests.get(urljoin( current_app.config["GN_SERVER_URL"], - f"/api/case-attribute/{inbredset_id}/values")).then( + f"case-attribute/{inbredset_id}/values")).then( lambda resp: {**canames, "case_attribute_values": { value["StrainName"]: value for value in resp.json()}}) + def __view_error__(err): + current_app.logger.error("%s", err) + return "We experienced an error" + return monad_requests.get(urljoin( current_app.config["GN_SERVER_URL"], - f"/api/case-attribute/{inbredset_id}")).then( + f"case-attribute/{inbredset_id}")).then( lambda resp: {"inbredset_group": resp.json()}).then( __fetch_strains__).then(__fetch_names__).then( __fetch_values__).either( - lambda err: err, # TODO: Handle error better + __view_error__, lambda values: render_template( "edit_case_attributes.html", inbredset_id=inbredset_id, **values)) -- cgit v1.2.3 From 7c727d76049de8b58de020357e172d30458ef47d Mon Sep 17 00:00:00 2001 From: Alexander_Kabui Date: Wed, 22 May 2024 14:00:30 +0300 Subject: View file code cleanup for gnqa. --- gn2/wqflask/views.py | 46 ++++++++++------------------------------------ 1 file changed, 10 insertions(+), 36 deletions(-) (limited to 'gn2/wqflask/views.py') diff --git a/gn2/wqflask/views.py b/gn2/wqflask/views.py index 9c1f7685..2a6eba44 100644 --- a/gn2/wqflask/views.py +++ b/gn2/wqflask/views.py @@ -258,23 +258,14 @@ def gsearchtable(): @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( @@ -290,44 +281,27 @@ 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) - - -@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) + return render_template("gnqa.html") -@app.route("/gnqna/hist/search/", methods=["GET"]) +@app.route("/gnqna/hist", methods=["GET"]) @require_oauth2 -def fetch_hist_records(search_term): +def get_gnqa_history(): 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}"), + (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) + if request.args.get("search_term"): + return render_template("gnqa_answer.html", + **{"gn_server_url": "GN3_LOCAL_URL", **response}) + return render_template("gnqa_search_history.html", + prev_queries=response) @app.route("/gnqna/rating//", -- cgit v1.2.3 From e30029041b3f533f5563f3d63f4cba6d1e31519d Mon Sep 17 00:00:00 2001 From: Alexander_Kabui Date: Thu, 23 May 2024 14:47:27 +0300 Subject: Update endpoints and add search history functionality. --- gn2/wqflask/templates/gnqa_search_history.html | 29 +++++++++++++------------- gn2/wqflask/views.py | 11 ++++++---- 2 files changed, 22 insertions(+), 18 deletions(-) (limited to 'gn2/wqflask/views.py') diff --git a/gn2/wqflask/templates/gnqa_search_history.html b/gn2/wqflask/templates/gnqa_search_history.html index af38392a..890a3995 100644 --- a/gn2/wqflask/templates/gnqa_search_history.html +++ b/gn2/wqflask/templates/gnqa_search_history.html @@ -1,39 +1,40 @@
-
-

You search History

+

Your AI search History

-
- {% for (key,val) in prev_queries.items() %} -
-
- +
+
+
    + {% for item in prev_queries %} +
  • +
    -
    -
-
- {% endfor %} +
+ + {% endfor %} +
diff --git a/gn2/wqflask/views.py b/gn2/wqflask/views.py index 2a6eba44..215837af 100644 --- a/gn2/wqflask/views.py +++ b/gn2/wqflask/views.py @@ -270,7 +270,7 @@ def gnqna(): lambda err: err, lambda tok: tok["access_token"]) return monad_requests.post( urljoin(GN3_LOCAL_URL, - "/api/llm/gnqna"), + "/api/llm/search"), json=dict(request.form), headers={ "Authorization": f"Bearer {token}" @@ -287,6 +287,10 @@ def gnqna(): @app.route("/gnqna/hist", methods=["GET"]) @require_oauth2 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"]) response = monad_requests.get(urljoin(GN3_LOCAL_URL, @@ -296,10 +300,9 @@ def get_gnqa_history(): "Authorization": f"Bearer {token}" } ).then(lambda resp: resp).either( - lambda x: x.json(), lambda x: x.json()) + _error_, lambda x: x.json()) if request.args.get("search_term"): - return render_template("gnqa_answer.html", - **{"gn_server_url": "GN3_LOCAL_URL", **response}) + return render_template("gnqa_answer.html", **response) return render_template("gnqa_search_history.html", prev_queries=response) -- cgit v1.2.3 From a34e4e2f0f19d2d62bb76eb09e6b156fd8d16b46 Mon Sep 17 00:00:00 2001 From: Alexander_Kabui Date: Tue, 28 May 2024 17:51:59 +0300 Subject: BugFix: return correct status code for generic exceptions handler. --- gn2/wqflask/views.py | 1 + 1 file changed, 1 insertion(+) (limited to 'gn2/wqflask/views.py') diff --git a/gn2/wqflask/views.py b/gn2/wqflask/views.py index 215837af..58b092a0 100644 --- a/gn2/wqflask/views.py +++ b/gn2/wqflask/views.py @@ -137,6 +137,7 @@ def handle_generic_exceptions(e): stack={formatted_lines}, error_image=animation, version=current_app.config.get("GN_VERSION"))) + resp.status_code = exc_type.code or 500 resp.set_cookie(err_msg[:32], animation) return resp -- cgit v1.2.3 From beb45534ba6abff2ef94c2de3e37e71fb61ecb3d Mon Sep 17 00:00:00 2001 From: Alexander_Kabui Date: Wed, 29 May 2024 12:47:12 +0300 Subject: Handle attributeError when getting error codes. --- gn2/wqflask/views.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'gn2/wqflask/views.py') diff --git a/gn2/wqflask/views.py b/gn2/wqflask/views.py index 58b092a0..fa8b6c78 100644 --- a/gn2/wqflask/views.py +++ b/gn2/wqflask/views.py @@ -137,7 +137,10 @@ def handle_generic_exceptions(e): stack={formatted_lines}, error_image=animation, version=current_app.config.get("GN_VERSION"))) - resp.status_code = exc_type.code or 500 + try: + resp.status_code = exc_type.code + except AttributeError: + resp.status_code = 500 resp.set_cookie(err_msg[:32], animation) return resp -- cgit v1.2.3 From 98f35d5117ea9510d54051574b07153d5687e628 Mon Sep 17 00:00:00 2001 From: Alexander_Kabui Date: Wed, 29 May 2024 14:05:44 +0300 Subject: integrate gnqa history delete functionality. --- gn2/wqflask/views.py | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) (limited to 'gn2/wqflask/views.py') diff --git a/gn2/wqflask/views.py b/gn2/wqflask/views.py index fa8b6c78..08ee61f5 100644 --- a/gn2/wqflask/views.py +++ b/gn2/wqflask/views.py @@ -288,7 +288,8 @@ def gnqna(): return render_template("gnqa.html") -@app.route("/gnqna/hist", methods=["GET"]) + +@app.route("/gnqna/hist", methods=["GET", "DELETE"]) @require_oauth2 def get_gnqa_history(): def _error_(resp): @@ -297,6 +298,14 @@ def get_gnqa_history(): **resp.json()}) token = session_info()["user"]["token"].either( lambda err: err, lambda tok: tok["access_token"]) + if request.method == "DELETE": + monad_requests.post(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={request.args.get('search_term')}" if request.args.get("search_term") else "/api/llm/history")), -- cgit v1.2.3 From fa3493164857ba78165a025db59aa8d02ddd6876 Mon Sep 17 00:00:00 2001 From: Alexander_Kabui Date: Thu, 29 Aug 2024 09:30:57 +0300 Subject: Modify gnqna search method from post to put. --- gn2/wqflask/views.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'gn2/wqflask/views.py') diff --git a/gn2/wqflask/views.py b/gn2/wqflask/views.py index 08ee61f5..97247182 100644 --- a/gn2/wqflask/views.py +++ b/gn2/wqflask/views.py @@ -272,7 +272,7 @@ def gnqna(): return render_template("gnqa_answer.html", **{"gn_server_url": GN3_LOCAL_URL, **(resp.json())}) 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/search"), json=dict(request.form), -- cgit v1.2.3 From 6db49002d4d2e69fcf4fdd6be6aceeea7b95664f Mon Sep 17 00:00:00 2001 From: Alexander_Kabui Date: Thu, 29 Aug 2024 10:10:22 +0300 Subject: Add delete to monad requests http methods. --- gn2/wqflask/requests.py | 5 +++++ gn2/wqflask/views.py | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) (limited to 'gn2/wqflask/views.py') diff --git a/gn2/wqflask/requests.py b/gn2/wqflask/requests.py index 16c56e13..182201a5 100644 --- a/gn2/wqflask/requests.py +++ b/gn2/wqflask/requests.py @@ -19,3 +19,8 @@ def post(url, data=None, json=None, **kwargs) -> Either: 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/views.py b/gn2/wqflask/views.py index 97247182..993c6f0c 100644 --- a/gn2/wqflask/views.py +++ b/gn2/wqflask/views.py @@ -299,7 +299,7 @@ def get_gnqa_history(): token = session_info()["user"]["token"].either( lambda err: err, lambda tok: tok["access_token"]) if request.method == "DELETE": - monad_requests.post(urljoin(GN3_LOCAL_URL, "/api/llm/history"), + monad_requests.delete(urljoin(GN3_LOCAL_URL, "/api/llm/history"), json=dict(request.form), headers={ "Authorization": f"Bearer {token}" -- cgit v1.2.3