From 24450cd319ad3bc43f119933cd9d6cf165bc4682 Mon Sep 17 00:00:00 2001 From: Frederick Muriuki Muriithi Date: Tue, 20 Jun 2023 08:03:50 +0300 Subject: Remove use of Flask Blueprints for the modules recently changed. --- wqflask/base/trait.py | 6 +- wqflask/gn2_main.py | 67 +------ wqflask/wqflask/__init__.py | 193 +++++++++++++-------- wqflask/wqflask/api/__init__.py | 5 - wqflask/wqflask/api/router.py | 74 ++++---- wqflask/wqflask/collect.py | 23 ++- wqflask/wqflask/partial_correlations_views.py | 7 +- wqflask/wqflask/templates/base.html | 18 +- .../wqflask/templates/correlation_error_page.html | 8 +- wqflask/wqflask/templates/correlation_page.html | 28 +-- wqflask/wqflask/templates/loading.html | 6 +- wqflask/wqflask/templates/loading_corrs.html | 6 +- wqflask/wqflask/templates/search_result_page.html | 24 +-- wqflask/wqflask/templates/show_trait.html | 30 ++-- wqflask/wqflask/templates/show_trait_details.html | 4 +- wqflask/wqflask/templates/tool_buttons.html | 2 +- wqflask/wqflask/user_login.py | 29 ++-- wqflask/wqflask/user_session.py | 9 +- wqflask/wqflask/views.py | 133 +++++++------- 19 files changed, 322 insertions(+), 350 deletions(-) (limited to 'wqflask') diff --git a/wqflask/base/trait.py b/wqflask/base/trait.py index 3a52e889..eb043769 100644 --- a/wqflask/base/trait.py +++ b/wqflask/base/trait.py @@ -1,8 +1,9 @@ import requests import simplejson as json -from flask import g, request, url_for, Blueprint, current_app as app +from flask import g, request, url_for +from wqflask import app import utility.hmac as hmac from base import webqtlConfig from base.webqtlCaseData import webqtlCaseData @@ -15,7 +16,6 @@ from wqflask.database import database_connection Redis = get_redis_conn() -trait_bp = Blueprint("trait", __name__) def create_trait(**kw): assert bool(kw.get('dataset')) != bool( @@ -256,7 +256,7 @@ def retrieve_sample_data(trait, dataset, samplelist=None): return trait -@trait_bp.route("/trait/get_sample_data") +@app.route("/trait/get_sample_data") def get_sample_data(): params = request.args trait = params['trait'] diff --git a/wqflask/gn2_main.py b/wqflask/gn2_main.py index 923a35d3..3fd18b6d 100644 --- a/wqflask/gn2_main.py +++ b/wqflask/gn2_main.py @@ -1,60 +1,11 @@ -"""Main app creation module""" -import time +"""Application entry-point module""" -from flask import g, session, request +from wqflask import app -from wqflask import create_app -from wqflask.user_session import UserSession -from gn3.authentication import DataRole, AdminRole - -app = create_app() - -@app.before_request -def before_request(): - g.request_start_time = time.time() - g.request_time = lambda: "%.5fs" % (time.time() - g.request_start_time) - - token = session.get("oauth2_token", False) - if token and not bool(session.get("user_details", False)): - config = current_app.config - client = OAuth2Session( - config["OAUTH2_CLIENT_ID"], config["OAUTH2_CLIENT_SECRET"], - token=token) - resp = client.get( - urljoin(config["GN_SERVER_URL"], "oauth2/user")) - user_details = resp.json() - session["user_details"] = user_details - - if user_details.get("error") == "invalid_token": - flash(user_details["error_description"], "alert-danger") - flash("You are now logged out.", "alert-info") - session.pop("user_details", None) - session.pop("oauth2_token", None) - -@app.context_processor -def include_admin_role_class(): - return {'AdminRole': AdminRole} - - -@app.context_processor -def include_data_role_class(): - return {'DataRole': DataRole} - -@app.before_request -def get_user_session(): - g.user_session = UserSession() - # I think this should solve the issue of deleting the cookie and redirecting to the home page when a user's session has expired - if not g.user_session: - response = make_response(redirect(url_for('login'))) - response.set_cookie('session_id_v2', '', expires=0) - return response - -@app.after_request -def set_user_session(response): - if hasattr(g, 'user_session'): - if not request.cookies.get(g.user_session.cookie_name): - response.set_cookie(g.user_session.cookie_name, - g.user_session.cookie) - else: - response.set_cookie('session_id_v2', '', expires=0) - return response +from base import trait +from wqflask import views +from wqflask import collect +from wqflask.api import router +from wqflask import user_login +from wqflask import user_session +from wqflask import partial_correlations_views diff --git a/wqflask/wqflask/__init__.py b/wqflask/wqflask/__init__.py index b9ad5c84..fab66e60 100644 --- a/wqflask/wqflask/__init__.py +++ b/wqflask/wqflask/__init__.py @@ -9,7 +9,10 @@ import jinja2 import werkzeug from flask_session import Session from authlib.integrations.requests_client import OAuth2Session -from flask import g, Flask, flash, session, url_for, redirect, current_app +from flask import ( + g, Flask, flash, session, request, url_for, redirect, current_app) + +from gn3.authentication import DataRole, AdminRole from base import webqtlConfig from utility import formatting @@ -18,19 +21,10 @@ from utility.hmac import data_hmac, url_for_hmac from utility.configuration import tempdir, override_from_envvars from wqflask.database import parse_db_url -from wqflask.user_session import UserSession from wqflask.group_manager import group_management from wqflask.resource_manager import resource_management from wqflask.metadata_edits import metadata_edit -from base.trait import trait_bp -from wqflask.api import api_bp -from wqflask.views import main_views -from wqflask.user_login import ulogin_bp -from wqflask.user_session import usession_bp -from wqflask.collect import collections_bp -from wqflask.partial_correlations_views import pcorrs_bp - from wqflask.api.markdown import glossary_blueprint from wqflask.api.markdown import references_blueprint from wqflask.api.markdown import links_blueprint @@ -47,6 +41,118 @@ from wqflask.oauth2.request_utils import user_details, authserver_authorise_uri from wqflask.jupyter_notebooks import jupyter_notebooks + +app = Flask(__name__) + + +# See http://flask.pocoo.org/docs/config/#configuring-from-files +# Note no longer use the badly named WQFLASK_OVERRIDES (nyi) +app.config.from_envvar('GN2_SETTINGS') + +DB_HOST, DB_USER, DB_PASS, DB_NAME, DB_PORT = parse_db_url(app.config.get('SQL_URI')) +app.config["DB_HOST"] = DB_HOST +app.config["DB_USER"] = DB_USER +app.config["DB_PASS"] = DB_PASS +app.config["DB_NAME"] = DB_NAME +app.config["DB_PORT"] = DB_PORT + +app.jinja_env.globals.update( + undefined=jinja2.StrictUndefined, + numify=formatting.numify, + logged_in=user_logged_in, + authserver_authorise_uri=authserver_authorise_uri, + user_details=user_details, + num_collections=num_collections, + url_for_hmac=url_for_hmac, + data_hmac=data_hmac) + +app.config["SESSION_REDIS"] = redis.from_url(app.config["REDIS_URL"]) + +# Override settings +app = override_from_envvars(app) +app = set_mandatory_settings(app) +app = webqtlConfig.init_app(app) + +# Registering blueprints +app.register_blueprint(glossary_blueprint, url_prefix="/glossary") +app.register_blueprint(references_blueprint, url_prefix="/references") +app.register_blueprint(links_blueprint, url_prefix="/links") +app.register_blueprint(policies_blueprint, url_prefix="/policies") +app.register_blueprint(environments_blueprint, url_prefix="/environments") +app.register_blueprint(facilities_blueprint, url_prefix="/facilities") +app.register_blueprint(blogs_blueprint, url_prefix="/blogs") +app.register_blueprint(news_blueprint, url_prefix="/news") +app.register_blueprint(jupyter_notebooks, url_prefix="/jupyter_notebooks") + +app.register_blueprint(resource_management, url_prefix="/resource-management") +app.register_blueprint(metadata_edit, url_prefix="/datasets/") +app.register_blueprint(group_management, url_prefix="/group-management") +app.register_blueprint(jobs_bp, url_prefix="/jobs") +app.register_blueprint(oauth2, url_prefix="/oauth2") + +from wqflask.decorators import AuthorisationError +from wqflask.app_errors import ( + handle_generic_exceptions, handle_authorisation_error) +app.register_error_handler(Exception, handle_generic_exceptions) +app.register_error_handler(AuthorisationError, handle_authorisation_error) + +server_session = Session(app) + +@app.before_request +def before_request(): + g.request_start_time = time.time() + g.request_time = lambda: "%.5fs" % (time.time() - g.request_start_time) + + token = session.get("oauth2_token", False) + if token and not bool(session.get("user_details", False)): + config = current_app.config + client = OAuth2Session( + config["OAUTH2_CLIENT_ID"], config["OAUTH2_CLIENT_SECRET"], + token=token) + resp = client.get( + urljoin(config["GN_SERVER_URL"], "oauth2/user")) + user_details = resp.json() + session["user_details"] = user_details + + if user_details.get("error") == "invalid_token": + flash(user_details["error_description"], "alert-danger") + flash("You are now logged out.", "alert-info") + session.pop("user_details", None) + session.pop("oauth2_token", None) + +@app.context_processor +def include_admin_role_class(): + return {'AdminRole': AdminRole} + + +@app.context_processor +def include_data_role_class(): + return {'DataRole': DataRole} + +@app.before_request +def get_user_session(): + # import here to prevent circular import issues + from wqflask.user_session import UserSession + g.user_session = UserSession() + # I think this should solve the issue of deleting the cookie and redirecting to the home page when a user's session has expired + if not g.user_session: + response = make_response(redirect(url_for('login'))) + response.set_cookie('session_id_v2', '', expires=0) + return response + +@app.after_request +def set_user_session(response): + if hasattr(g, 'user_session'): + if not request.cookies.get(g.user_session.cookie_name): + response.set_cookie(g.user_session.cookie_name, + g.user_session.cookie) + else: + response.set_cookie('session_id_v2', '', expires=0) + return response + + + + from wqflask import group_manager from wqflask import resource_manager from wqflask import search_results @@ -55,70 +161,3 @@ from wqflask import gsearch from wqflask import update_search_results from wqflask import docs from wqflask import db_info - -def create_app(): - """Create the application object.""" - app = Flask(__name__) - - - # See http://flask.pocoo.org/docs/config/#configuring-from-files - # Note no longer use the badly named WQFLASK_OVERRIDES (nyi) - app.config.from_envvar('GN2_SETTINGS') - - DB_HOST, DB_USER, DB_PASS, DB_NAME, DB_PORT = parse_db_url(app.config.get('SQL_URI')) - app.config["DB_HOST"] = DB_HOST - app.config["DB_USER"] = DB_USER - app.config["DB_PASS"] = DB_PASS - app.config["DB_NAME"] = DB_NAME - app.config["DB_PORT"] = DB_PORT - - app.jinja_env.globals.update( - undefined=jinja2.StrictUndefined, - numify=formatting.numify, - logged_in=user_logged_in, - authserver_authorise_uri=authserver_authorise_uri, - user_details=user_details, - num_collections=num_collections, - url_for_hmac=url_for_hmac, - data_hmac=data_hmac) - - app.config["SESSION_REDIS"] = redis.from_url(app.config["REDIS_URL"]) - - # Override settings - app = override_from_envvars(app) - app = set_mandatory_settings(app) - app = webqtlConfig.init_app(app) - - # Registering blueprints - app.register_blueprint(trait_bp) - app.register_blueprint(pcorrs_bp) - app.register_blueprint(ulogin_bp) - app.register_blueprint(main_views) - app.register_blueprint(usession_bp) - app.register_blueprint(collections_bp) - app.register_blueprint(api_bp, url_prefix="/api") - - app.register_blueprint(glossary_blueprint, url_prefix="/glossary") - app.register_blueprint(references_blueprint, url_prefix="/references") - app.register_blueprint(links_blueprint, url_prefix="/links") - app.register_blueprint(policies_blueprint, url_prefix="/policies") - app.register_blueprint(environments_blueprint, url_prefix="/environments") - app.register_blueprint(facilities_blueprint, url_prefix="/facilities") - app.register_blueprint(blogs_blueprint, url_prefix="/blogs") - app.register_blueprint(news_blueprint, url_prefix="/news") - app.register_blueprint(jupyter_notebooks, url_prefix="/jupyter_notebooks") - - app.register_blueprint(resource_management, url_prefix="/resource-management") - app.register_blueprint(metadata_edit, url_prefix="/datasets/") - app.register_blueprint(group_management, url_prefix="/group-management") - app.register_blueprint(jobs_bp, url_prefix="/jobs") - app.register_blueprint(oauth2, url_prefix="/oauth2") - - from wqflask.decorators import AuthorisationError - from wqflask.app_errors import ( - handle_generic_exceptions, handle_authorisation_error) - app.register_error_handler(Exception, handle_generic_exceptions) - app.register_error_handler(AuthorisationError, handle_authorisation_error) - - server_session = Session(app) - return app diff --git a/wqflask/wqflask/api/__init__.py b/wqflask/wqflask/api/__init__.py index abeb6e56..4f6e348c 100644 --- a/wqflask/wqflask/api/__init__.py +++ b/wqflask/wqflask/api/__init__.py @@ -1,9 +1,4 @@ """ Set up the package's top-level objects. """ -from flask import Blueprint -from . import router as router - -api_bp = Blueprint("api", __name__) -api_bp.register_blueprint(router.pre1_router) diff --git a/wqflask/wqflask/api/router.py b/wqflask/wqflask/api/router.py index afa150dc..f180527d 100644 --- a/wqflask/wqflask/api/router.py +++ b/wqflask/wqflask/api/router.py @@ -12,26 +12,24 @@ from zipfile import ZipFile, ZIP_DEFLATED import flask from flask import request -from flask import Blueprint from flask import send_file from flask import make_response -from flask import current_app as app from utility.configuration import flat_files +from wqflask import app from wqflask.database import database_connection from wqflask.api import correlation, mapping, gen_menu version = "pre1" -pre1_router = Blueprint("pre1_router", __name__) -@pre1_router.route("/v_{}/".format(version)) +@app.route("/v_{}/".format(version)) def hello_world(): return flask.jsonify({"hello": "world"}) -@pre1_router.route("/v_{}/species".format(version)) +@app.route("/v_{}/species".format(version)) def get_species_list(): species_list = [] with database_connection() as conn, conn.cursor() as cursor: @@ -49,8 +47,8 @@ def get_species_list(): return flask.jsonify(species_list) -@pre1_router.route("/v_{}/species/".format(version)) -@pre1_router.route("/v_{}/species/.".format(version)) +@app.route("/v_{}/species/".format(version)) +@app.route("/v_{}/species/.".format(version)) def get_species_info(species_name, file_format="json"): with database_connection() as conn, conn.cursor() as cursor: cursor.execute( @@ -68,8 +66,8 @@ def get_species_info(species_name, file_format="json"): return flask.jsonify(species_dict) -@pre1_router.route("/v_{}/groups".format(version)) -@pre1_router.route("/v_{}/groups/".format(version)) +@app.route("/v_{}/groups".format(version)) +@app.route("/v_{}/groups/".format(version)) def get_groups_list(species_name=None): _groups = () with database_connection() as conn, conn.cursor() as cursor: @@ -114,10 +112,10 @@ def get_groups_list(species_name=None): return return_error(code=204, source=request.url_rule.rule, title="No Results", details="") -@pre1_router.route("/v_{}/group/".format(version)) -@pre1_router.route("/v_{}/group/.".format(version)) -@pre1_router.route("/v_{}/group//".format(version)) -@pre1_router.route("/v_{}/group//.".format(version)) +@app.route("/v_{}/group/".format(version)) +@app.route("/v_{}/group/.".format(version)) +@app.route("/v_{}/group//".format(version)) +@app.route("/v_{}/group//.".format(version)) def get_group_info(group_name, species_name=None, file_format="json"): group = () with database_connection() as conn, conn.cursor() as cursor: @@ -169,8 +167,8 @@ def get_group_info(group_name, species_name=None, file_format="json"): return return_error(code=204, source=request.url_rule.rule, title="No Results", details="") -@pre1_router.route("/v_{}/datasets/".format(version)) -@pre1_router.route("/v_{}/datasets//".format(version)) +@app.route("/v_{}/datasets/".format(version)) +@app.route("/v_{}/datasets//".format(version)) def get_datasets_for_group(group_name, species_name=None): _datasets = () with database_connection() as conn, conn.cursor() as cursor: @@ -234,10 +232,10 @@ def get_datasets_for_group(group_name, species_name=None): return return_error(code=204, source=request.url_rule.rule, title="No Results", details="") -@pre1_router.route("/v_{}/dataset/".format(version)) -@pre1_router.route("/v_{}/dataset/.".format(version)) -@pre1_router.route("/v_{}/dataset//".format(version)) -@pre1_router.route("/v_{}/dataset//.".format(version)) +@app.route("/v_{}/dataset/".format(version)) +@app.route("/v_{}/dataset/.".format(version)) +@app.route("/v_{}/dataset//".format(version)) +@app.route("/v_{}/dataset//.".format(version)) def get_dataset_info(dataset_name, group_name=None, file_format="json"): # ZS: First get ProbeSet (mRNA expression) datasets and then get Phenotype datasets @@ -340,8 +338,8 @@ def get_dataset_info(dataset_name, group_name=None, file_format="json"): return return_error(code=204, source=request.url_rule.rule, title="No Results", details="") -@pre1_router.route("/v_{}/traits/".format(version), methods=("GET",)) -@pre1_router.route("/v_{}/traits/.".format(version), methods=("GET",)) +@app.route("/v_{}/traits/".format(version), methods=("GET",)) +@app.route("/v_{}/traits/.".format(version), methods=("GET",)) def fetch_traits(dataset_name, file_format="json"): trait_ids, trait_names, data_type, dataset_id = get_dataset_trait_ids( dataset_name, request.args) @@ -489,8 +487,8 @@ def fetch_traits(dataset_name, file_format="json"): details="") -@pre1_router.route("/v_{}/sample_data/".format(version)) -@pre1_router.route("/v_{}/sample_data/.".format(version)) +@app.route("/v_{}/sample_data/".format(version)) +@app.route("/v_{}/sample_data/.".format(version)) def all_sample_data(dataset_name, file_format="csv"): trait_ids, trait_names, data_type, dataset_id = get_dataset_trait_ids( dataset_name, request.args) @@ -598,8 +596,8 @@ def all_sample_data(dataset_name, file_format="csv"): return return_error(code=204, source=request.url_rule.rule, title="No Results", details="") -@pre1_router.route("/v_{}/sample_data//".format(version)) -@pre1_router.route("/v_{}/sample_data//.".format(version)) +@app.route("/v_{}/sample_data//".format(version)) +@app.route("/v_{}/sample_data//.".format(version)) def trait_sample_data(dataset_name, trait_name, file_format="json"): with database_connection() as conn, conn.cursor() as cursor: cursor.execute( @@ -685,10 +683,10 @@ def trait_sample_data(dataset_name, trait_name, file_format="json"): return return_error(code=204, source=request.url_rule.rule, title="No Results", details="") -@pre1_router.route("/v_{}/trait//".format(version)) -@pre1_router.route("/v_{}/trait//.".format(version)) -@pre1_router.route("/v_{}/trait_info//".format(version)) -@pre1_router.route("/v_{}/trait_info//.".format(version)) +@app.route("/v_{}/trait//".format(version)) +@app.route("/v_{}/trait//.".format(version)) +@app.route("/v_{}/trait_info//".format(version)) +@app.route("/v_{}/trait_info//.".format(version)) def get_trait_info(dataset_name, trait_name, file_format="json"): with database_connection() as conn, conn.cursor() as cursor: cursor.execute( @@ -750,7 +748,7 @@ def get_trait_info(dataset_name, trait_name, file_format="json"): return return_error(code=204, source=request.url_rule.rule, title="No Results", details="") -@pre1_router.route("/v_{}/correlation".format(version), methods=("GET",)) +@app.route("/v_{}/correlation".format(version), methods=("GET",)) def get_corr_results(): results = correlation.do_correlation(request.args) @@ -761,7 +759,7 @@ def get_corr_results(): return return_error(code=204, source=request.url_rule.rule, title="No Results", details="") -@pre1_router.route("/v_{}/mapping".format(version), methods=("GET",)) +@app.route("/v_{}/mapping".format(version), methods=("GET",)) def get_mapping_results(): results, format = mapping.do_mapping_for_api(request.args) @@ -785,18 +783,18 @@ def get_mapping_results(): return return_error(code=204, source=request.url_rule.rule, title="No Results", details="") -@pre1_router.route("/v_{}/genotypes/view/".format(version)) +@app.route("/v_{}/genotypes/view/".format(version)) def view_genotype_files(group_name): if os.path.isfile("{0}/{1}.json".format(flat_files(app, "genotype"), group_name)): with open("{0}/{1}.json".format(flat_files(app, "genotype"), group_name)) as geno_json: return flask.jsonify(json.load(geno_json)) -@pre1_router.route("/v_{}/genotypes///.zip".format(version)) -@pre1_router.route("/v_{}/genotypes///".format(version)) -@pre1_router.route("/v_{}/genotypes//.zip".format(version)) -@pre1_router.route("/v_{}/genotypes//".format(version)) -@pre1_router.route("/v_{}/genotypes/.".format(version)) +@app.route("/v_{}/genotypes///.zip".format(version)) +@app.route("/v_{}/genotypes///".format(version)) +@app.route("/v_{}/genotypes//.zip".format(version)) +@app.route("/v_{}/genotypes//".format(version)) +@app.route("/v_{}/genotypes/.".format(version)) def get_genotypes(group_name, file_format="csv", dataset_name=None): limit_num = None if 'limit_to' in request.args: @@ -887,7 +885,7 @@ def get_genotypes(group_name, file_format="csv", dataset_name=None): return output -@pre1_router.route("/v_{}/gen_dropdown".format(version), methods=("GET",)) +@app.route("/v_{}/gen_dropdown".format(version), methods=("GET",)) def gen_dropdown_menu(): with database_connection() as conn: results = gen_menu.gen_dropdown_json(conn) diff --git a/wqflask/wqflask/collect.py b/wqflask/wqflask/collect.py index dd3f3330..5c97b69c 100644 --- a/wqflask/wqflask/collect.py +++ b/wqflask/wqflask/collect.py @@ -11,7 +11,6 @@ from flask import url_for from flask import request from flask import redirect from flask import flash -from flask import Blueprint from flask import current_app from utility import hmac @@ -23,6 +22,7 @@ from base.trait import retrieve_trait_info from base.trait import jsonable from base.data_set import create_dataset +from wqflask import app from wqflask.oauth2 import client from wqflask.oauth2 import session from wqflask.oauth2.session import session_info @@ -34,7 +34,6 @@ from wqflask.oauth2.client import ( Redis = get_redis_conn() -collections_bp = Blueprint("collections", __name__) def process_traits(unprocessed_traits): if isinstance(unprocessed_traits, bytes): @@ -59,7 +58,7 @@ def report_change(len_before, len_now): numify(new_length, 'new trait', 'new traits'))) -@collections_bp.route("/collections/store_trait_list", methods=('POST',)) +@app.route("/collections/store_trait_list", methods=('POST',)) def store_traits_list(): params = request.form @@ -71,7 +70,7 @@ def store_traits_list(): return hash -@collections_bp.route("/collections/add", methods=["POST"]) +@app.route("/collections/add", methods=["POST"]) def collections_add(): anon_id = session_info()["anon_id"] traits = request.args.get("traits", request.form.get("traits")) @@ -114,7 +113,7 @@ def __compute_traits__(params): unprocessed_traits = params['traits'] return process_traits(unprocessed_traits) -@collections_bp.route("/collections/new") +@app.route("/collections/new") def collections_new(): params = request.args anon_id = session_info()["anon_id"] @@ -179,7 +178,7 @@ def create_new(collection_name): return redirect(url_for('view_collection', uc_id=uc_id)) -@collections_bp.route("/collections/list") +@app.route("/collections/list") def list_collections(): params = request.args anon_id = session.session_info()["anon_id"] @@ -199,7 +198,7 @@ def list_collections(): **user_collections, **anon_collections) -@collections_bp.route("/collections/handle_anonymous", methods=["POST"]) +@app.route("/collections/handle_anonymous", methods=["POST"]) def handle_anonymous_collections(): """Handle any anonymous collection on logging in.""" choice = request.form.get("anon_choice") @@ -220,7 +219,7 @@ def handle_anonymous_collections(): "anon_id": str(session_info()["anon_id"]) }).either(__impdel_error__, __impdel_success__) -@collections_bp.route("/collections/remove", methods=('POST',)) +@app.route("/collections/remove", methods=('POST',)) def remove_traits(): params = request.form uc_id = params['uc_id'] @@ -234,7 +233,7 @@ def remove_traits(): }).either(with_flash_error(resp), with_flash_success(resp)) -@collections_bp.route("/collections/delete", methods=('POST',)) +@app.route("/collections/delete", methods=('POST',)) def delete_collection(): def __error__(err): error = process_error(err) @@ -303,7 +302,7 @@ def trait_info_str(trait): trait.name, trait.dataset.name, __trait_desc(trait), __symbol(trait), __location(trait), __mean(trait), __lrs(trait), __lrs_location(trait)) -@collections_bp.route("/collections/import", methods=('POST',)) +@app.route("/collections/import", methods=('POST',)) def import_collection(): import_file = request.files['import_file'] if import_file.filename != '': @@ -319,7 +318,7 @@ def import_collection(): return render_template( "collections/list.html") -@collections_bp.route("/collections/view") +@app.route("/collections/view") def view_collection(): params = request.args @@ -382,7 +381,7 @@ def view_collection(): return coll.either(__error__, __view__) -@collections_bp.route("/collections/change_name", methods=('POST',)) +@app.route("/collections/change_name", methods=('POST',)) def change_collection_name(): collection_id = request.form['collection_id'] resp = redirect(url_for("view_collection", uc_id=collection_id)) diff --git a/wqflask/wqflask/partial_correlations_views.py b/wqflask/wqflask/partial_correlations_views.py index f5f88147..5911860d 100644 --- a/wqflask/wqflask/partial_correlations_views.py +++ b/wqflask/wqflask/partial_correlations_views.py @@ -14,12 +14,11 @@ from flask import ( current_app, render_template) +from wqflask import app from utility.configuration import get_setting from wqflask.database import database_connection from gn3.db.partial_correlations import traits_info -pcorrs_bp = Blueprint("partial_correlations", __name__) - def publish_target_databases(conn, groups, threshold): query = ( "SELECT PublishFreeze.FullName,PublishFreeze.Name " @@ -268,7 +267,7 @@ def handle_response(response): message = response_error_message(response)) return handle_200_response(response.json()) -@pcorrs_bp.route("/partial_correlations", methods=["POST"]) +@app.route("/partial_correlations", methods=["POST"]) def partial_correlations(): form = request.form traits = tuple( @@ -349,7 +348,7 @@ def process_pcorrs_command_output(result): return render_error( f"({result['error_type']}: {result['message']})") -@pcorrs_bp.route("/partial_correlations/", methods=["GET"]) +@app.route("/partial_correlations/", methods=["GET"]) def poll_partial_correlation_results(command_id): response = requests.get( url=urljoin(get_setting(current_app, "GN_SERVER_URL"), diff --git a/wqflask/wqflask/templates/base.html b/wqflask/wqflask/templates/base.html index 7cda4bab..1328d229 100644 --- a/wqflask/wqflask/templates/base.html +++ b/wqflask/wqflask/templates/base.html @@ -12,7 +12,7 @@ - + @@ -30,10 +30,10 @@ border-radius: 1rem; } table.dataTable thead .sorting_asc { - background-image: url({{ url_for("main_views.js", filename="DataTables/images/sort_asc_disabled.png") }}); + background-image: url({{ url_for("js", filename="DataTables/images/sort_asc_disabled.png") }}); } table.dataTable thead .sorting_desc { - background-image: url({{ url_for("main_views.js", filename="DataTables/images/sort_desc_disabled.png") }}); + background-image: url({{ url_for("js", filename="DataTables/images/sort_desc_disabled.png") }}); } @@ -336,8 +336,8 @@ - - + + - + - - - + + + {% block js %} {% endblock %} - - - - - - - - - + + + + + + + + + + diff --git a/wqflask/wqflask/templates/loading.html b/wqflask/wqflask/templates/loading.html index 3d4c4643..a6d9ae5e 100644 --- a/wqflask/wqflask/templates/loading.html +++ b/wqflask/wqflask/templates/loading.html @@ -1,5 +1,5 @@ Loading {{ start_vars.tool_used }} Results - +
{% for key, value in start_vars.items() %} @@ -100,8 +100,8 @@
- - + + - + + diff --git a/wqflask/wqflask/templates/search_result_page.html b/wqflask/wqflask/templates/search_result_page.html index 15ec75d7..495c5669 100644 --- a/wqflask/wqflask/templates/search_result_page.html +++ b/wqflask/wqflask/templates/search_result_page.html @@ -1,10 +1,10 @@ {% extends "base.html" %} {% block title %}Search Results{% endblock %} {% block css %} - - - - + + + + @@ -153,14 +153,14 @@ {% endblock %} {% block js %} - - - - - - - - + + + + + + + + diff --git a/wqflask/wqflask/templates/show_trait.html b/wqflask/wqflask/templates/show_trait.html index 414a6ec0..84231d34 100644 --- a/wqflask/wqflask/templates/show_trait.html +++ b/wqflask/wqflask/templates/show_trait.html @@ -8,9 +8,9 @@ - - - + + + @@ -139,13 +139,13 @@ $('.collapse').collapse() - - - - - - - + + + + + + + @@ -154,11 +154,11 @@ - - - - - + + + + + diff --git a/wqflask/wqflask/templates/show_trait_details.html b/wqflask/wqflask/templates/show_trait_details.html index 795267dd..c745fce8 100644 --- a/wqflask/wqflask/templates/show_trait_details.html +++ b/wqflask/wqflask/templates/show_trait_details.html @@ -63,7 +63,7 @@ {{ dataset.fullname }}
- + GN2 Link: {{ dataset.fullname }} @@ -229,7 +229,7 @@ {% endif %} {% if this_trait.symbol != None %} - + {% if dataset.group.species == "mouse" or dataset.group.species == "rat" %} {% endif %} diff --git a/wqflask/wqflask/templates/tool_buttons.html b/wqflask/wqflask/templates/tool_buttons.html index 50e26486..c6d1476c 100644 --- a/wqflask/wqflask/templates/tool_buttons.html +++ b/wqflask/wqflask/templates/tool_buttons.html @@ -32,7 +32,7 @@ diff --git a/wqflask/wqflask/user_login.py b/wqflask/wqflask/user_login.py index 69ae9e10..4d9cc021 100644 --- a/wqflask/wqflask/user_login.py +++ b/wqflask/wqflask/user_login.py @@ -17,11 +17,10 @@ from flask import ( url_for, request, redirect, - Blueprint, make_response, - render_template, - current_app as app) + render_template) +from wqflask import app from wqflask import pbkdf2 from wqflask.user_session import UserSession @@ -33,8 +32,6 @@ Redis = get_redis_conn() THREE_DAYS = 60 * 60 * 24 * 3 -ulogin_bp = Blueprint("user_login", __name__) - def timestamp(): return datetime.datetime.utcnow().isoformat() @@ -160,7 +157,7 @@ def send_invitation_email(user_email, temp_password, template_name="email/user_i return {"recipient": recipient, "subject": subject, "body": body} -@ulogin_bp.route("/manage/verify_email") +@app.route("/manage/verify_email") def verify_email(): if 'code' in request.args: user_details = check_verification_code(request.args['code']) @@ -180,7 +177,7 @@ def verify_email(): "Invalid code: Password reset code does not exist or might have expired!", "error") -@ulogin_bp.route("/n/login", methods=('GET', 'POST')) +@app.route("/n/login", methods=('GET', 'POST')) def login(): params = request.form if request.form else request.args if not params: # ZS: If coming to page for first time @@ -260,7 +257,7 @@ def login(): return response -@ulogin_bp.route("/n/login/github_oauth2", methods=('GET', 'POST')) +@app.route("/n/login/github_oauth2", methods=('GET', 'POST')) def github_oauth2(): from utility.tools import GITHUB_CLIENT_ID, GITHUB_CLIENT_SECRET, GITHUB_AUTH_URL code = request.args.get("code") @@ -303,7 +300,7 @@ def get_github_user_details(access_token): return json.loads(result) -@ulogin_bp.route("/n/login/orcid_oauth2", methods=('GET', 'POST')) +@app.route("/n/login/orcid_oauth2", methods=('GET', 'POST')) def orcid_oauth2(): from uuid import uuid4 from utility.tools import ORCID_CLIENT_ID, ORCID_CLIENT_SECRET, ORCID_TOKEN_URL, ORCID_AUTH_URL @@ -350,7 +347,7 @@ def get_github_user_details(access_token): return json.loads(result) -@ulogin_bp.route("/n/logout") +@app.route("/n/logout") def logout(): UserSession().delete_session() flash("You are now logged out. We hope you come back soon!") @@ -360,7 +357,7 @@ def logout(): return response -@ulogin_bp.route("/n/forgot_password", methods=['GET']) +@app.route("/n/forgot_password", methods=['GET']) def forgot_password(): """Entry point for forgotten password""" print("ARGS: ", request.args) @@ -402,7 +399,7 @@ def send_forgot_password_email(verification_email): return subject -@ulogin_bp.route("/n/forgot_password_submit", methods=('POST',)) +@app.route("/n/forgot_password_submit", methods=('POST',)) def forgot_password_submit(): """When a forgotten password form is submitted we get here""" params = request.form @@ -426,7 +423,7 @@ def forgot_password_submit(): return redirect(url_for("forgot_password")) -@ulogin_bp.route("/n/password_reset", methods=['GET']) +@app.route("/n/password_reset", methods=['GET']) def password_reset(): """Entry point after user clicks link in E-mail""" verification_code = request.args.get('code') @@ -445,7 +442,7 @@ def password_reset(): return redirect(url_for("login")) -@ulogin_bp.route("/n/password_reset_step2", methods=('POST',)) +@app.route("/n/password_reset_step2", methods=('POST',)) def password_reset_step2(): """Handle confirmation E-mail for password reset""" errors = [] @@ -507,7 +504,7 @@ def register_user(params): return errors -@ulogin_bp.route("/n/register", methods=('GET', 'POST')) +@app.route("/n/register", methods=('GET', 'POST')) def register(): errors = [] @@ -525,6 +522,6 @@ def register(): return render_template("new_security/register_user.html", values=params, errors=errors) -@ulogin_bp.errorhandler(401) +@app.errorhandler(401) def unauthorized(error): return redirect(url_for('login')) diff --git a/wqflask/wqflask/user_session.py b/wqflask/wqflask/user_session.py index 54bfb609..60125b57 100644 --- a/wqflask/wqflask/user_session.py +++ b/wqflask/wqflask/user_session.py @@ -12,11 +12,10 @@ from flask import ( url_for, request, redirect, - Blueprint, make_response, - render_template, - current_app as app) + render_template) +from wqflask import app from utility import hmac from utility.redis_tools import get_redis_conn, get_user_id, get_user_by_unique_column, set_user_attribute, get_user_collections, save_collections @@ -26,8 +25,6 @@ Redis = get_redis_conn() THREE_DAYS = 60 * 60 * 24 * 3 THIRTY_DAYS = 60 * 60 * 24 * 30 -usession_bp = Blueprint("user_session", __name__) - def verify_cookie(cookie): the_uuid, separator, the_signature = cookie.partition(':') @@ -45,7 +42,7 @@ def create_signed_cookie(): return the_uuid, uuid_signed -@usession_bp.route("/user/manage", methods=('GET', 'POST')) +@app.route("/user/manage", methods=('GET', 'POST')) def manage_user(): params = request.form if request.form else request.args if 'new_full_name' in params: diff --git a/wqflask/wqflask/views.py b/wqflask/wqflask/views.py index 3ce7d0cb..de2e803a 100644 --- a/wqflask/wqflask/views.py +++ b/wqflask/wqflask/views.py @@ -26,7 +26,6 @@ from uuid import UUID from urllib.parse import urljoin from gn3.computations.gemma import generate_hash_of_string -from flask import current_app as app from flask import g from flask import Response from flask import request @@ -37,10 +36,10 @@ from flask import send_file from flask import url_for from flask import flash from flask import session -from flask import Blueprint # Some of these (like collect) might contain endpoints, so they're still used. # Blueprints should probably be used instead. +from wqflask import app from wqflask import search_results from wqflask import server_side from base.data_set import create_dataset # Used by YAML in marker_regression @@ -94,15 +93,13 @@ from wqflask.oauth2.checks import user_logged_in Redis = get_redis_conn() -main_views = Blueprint("main_views", __name__) - -@main_views.route("/authentication_needed") +@app.route("/authentication_needed") def no_access_page(): return render_template("new_security/not_authenticated.html") -@main_views.route("/") +@app.route("/") def index_page(): anon_id = session_info()["anon_id"] def __render__(colls): @@ -118,7 +115,7 @@ def index_page(): __render__) -@main_views.route("/tmp/") +@app.route("/tmp/") def tmp_page(img_path): initial_start_vars = request.form imgfile = open(get_setting(app, "WEBQTL_GENERATED_IMAGE_DIR") + img_path, 'rb') @@ -129,7 +126,7 @@ def tmp_page(img_path): img_base64=bytesarray) -@main_views.route("/js/") +@app.route("/js/") def js(filename): js_path = get_setting(app, "JS_GUIX_PATH") name = filename @@ -139,7 +136,7 @@ def js(filename): return send_from_directory(js_path, name) -@main_views.route("/css/") +@app.route("/css/") def css(filename): js_path = get_setting(app, "JS_GUIX_PATH") name = filename @@ -149,13 +146,13 @@ def css(filename): return send_from_directory(js_path, name) -@main_views.route("/twitter/") +@app.route("/twitter/") def twitter(filename): return send_from_directory(get_setting(app, "JS_TWITTER_POST_FETCHER_PATH"), filename) -@main_views.route("/search", methods=('GET',)) +@app.route("/search", methods=('GET',)) def search_page(): result = None if get_setting(app, "USE_REDIS"): @@ -176,7 +173,7 @@ def search_page(): return render_template("search_error.html") -@main_views.route("/search_table", methods=('GET',)) +@app.route("/search_table", methods=('GET',)) def search_page_table(): the_search = search_results.SearchResultPage(request.args) current_page = server_side.ServerSideTable( @@ -189,7 +186,7 @@ def search_page_table(): return flask.jsonify(current_page) -@main_views.route("/gsearch", methods=('GET',)) +@app.route("/gsearch", methods=('GET',)) def gsearchact(): result = GSearch(request.args).__dict__ type = request.args['type'] @@ -199,7 +196,7 @@ def gsearchact(): return render_template("gsearch_pheno.html", **result) -@main_views.route("/gsearch_table", methods=('GET',)) +@app.route("/gsearch_table", methods=('GET',)) def gsearchtable(): gsearch_table_data = GSearch(request.args) current_page = server_side.ServerSideTable( @@ -212,13 +209,13 @@ def gsearchtable(): return flask.jsonify(current_page) -@main_views.route("/gsearch_updating", methods=('POST',)) +@app.route("/gsearch_updating", methods=('POST',)) def gsearch_updating(): result = UpdateGSearch(request.args).__dict__ return result['results'] -@main_views.route("/docedit") +@app.route("/docedit") def docedit(): try: if g.user_session.record['user_email_address'] == "zachary.a.sloan@gmail.com" or g.user_session.record['user_email_address'] == "labwilliams@gmail.com": @@ -230,45 +227,45 @@ def docedit(): return "You shouldn't be here!" -@main_views.route('/generated/') +@app.route('/generated/') def generated_file(filename): return send_from_directory(get_setting(app, "WEBQTL_GENERATED_IMAGE_DIR"), filename) -@main_views.route("/help") +@app.route("/help") def help(): doc = Docs("help", request.args) return render_template("docs.html", **doc.__dict__) -@main_views.route("/wgcna_setup", methods=('POST',)) +@app.route("/wgcna_setup", methods=('POST',)) def wcgna_setup(): # We are going to get additional user input for the analysis # Display them using the template return render_template("wgcna_setup.html", **request.form) -@main_views.route("/wgcna_results", methods=('POST',)) +@app.route("/wgcna_results", methods=('POST',)) def wcgna_results(): """call the gn3 api to get wgcna response data""" results = run_wgcna(dict(request.form)) return render_template("gn3_wgcna_results.html", **results) -@main_views.route("/ctl_setup", methods=('POST',)) +@app.route("/ctl_setup", methods=('POST',)) def ctl_setup(): # We are going to get additional user input for the analysis # Display them using the template return render_template("ctl_setup.html", **request.form) -@main_views.route("/ctl_results", methods=["POST"]) +@app.route("/ctl_results", methods=["POST"]) def ctl_results(): ctl_results = run_ctl(request.form) return render_template("gn3_ctl_results.html", **ctl_results) -@main_views.route("/ctl_network_files//") +@app.route("/ctl_network_files//") def fetch_network_files(file_name, file_type): file_path = f"{file_name}.{file_type}" @@ -277,30 +274,30 @@ def fetch_network_files(file_name, file_type): return send_file(file_path) -@main_views.route("/intro") +@app.route("/intro") def intro(): doc = Docs("intro", request.args) return render_template("docs.html", **doc.__dict__) -@main_views.route("/tutorials") +@app.route("/tutorials") def tutorials(): return render_template("tutorials.html") -@main_views.route("/credits") +@app.route("/credits") def credits(): return render_template("credits.html") -@main_views.route("/update_text", methods=('POST',)) +@app.route("/update_text", methods=('POST',)) def update_page(): update_text(request.form) doc = Docs(request.form['entry_type'], request.form) return render_template("docs.html", **doc.__dict__) -@main_views.route("/submit_trait") +@app.route("/submit_trait") def submit_trait_form(): species_and_groups = get_species_groups() return render_template( @@ -310,13 +307,13 @@ def submit_trait_form(): version=get_setting(app, "GN_VERSION")) -@main_views.route("/create_temp_trait", methods=('POST',)) +@app.route("/create_temp_trait", methods=('POST',)) def create_temp_trait(): doc = Docs("links") return render_template("links.html", **doc.__dict__) -@main_views.route('/export_trait_excel', methods=('POST',)) +@app.route('/export_trait_excel', methods=('POST',)) def export_trait_excel(): """Excel file consisting of the sample data from the trait data and analysis page""" trait_name, sample_data = export_trait_data.export_sample_table( @@ -337,7 +334,7 @@ def export_trait_excel(): headers={"Content-Disposition": "attachment;filename=" + trait_name + ".xlsx"}) -@main_views.route('/export_trait_csv', methods=('POST',)) +@app.route('/export_trait_csv', methods=('POST',)) def export_trait_csv(): """CSV file consisting of the sample data from the trait data and analysis page""" trait_name, sample_data = export_trait_data.export_sample_table( @@ -355,7 +352,7 @@ def export_trait_csv(): headers={"Content-Disposition": "attachment;filename=" + trait_name + ".csv"}) -@main_views.route('/export_traits_csv', methods=('POST',)) +@app.route('/export_traits_csv', methods=('POST',)) def export_traits_csv(): """CSV file consisting of the traits from the search result page""" file_list = export_traits(request.form, "metadata") @@ -378,7 +375,7 @@ def export_traits_csv(): headers={"Content-Disposition": "attachment;filename=" + file_list[0][0]}) -@main_views.route('/export_collection', methods=('POST',)) +@app.route('/export_collection', methods=('POST',)) def export_collection_csv(): """CSV file consisting of trait list so collections can be exported/shared""" out_file = export_traits(request.form, "collection") @@ -387,7 +384,7 @@ def export_collection_csv(): headers={"Content-Disposition": "attachment;filename=" + out_file[0] + ".csv"}) -@main_views.route('/export_perm_data', methods=('POST',)) +@app.route('/export_perm_data', methods=('POST',)) def export_perm_data(): """CSV file consisting of the permutation data for the mapping results""" perm_info = json.loads(request.form['perm_info']) @@ -434,7 +431,7 @@ def export_perm_data(): headers={"Content-Disposition": "attachment;filename=" + file_name + ".csv"}) -@main_views.route("/show_temp_trait", methods=('POST',)) +@app.route("/show_temp_trait", methods=('POST',)) def show_temp_trait_page(): with database_connection() as conn, conn.cursor() as cursor: user_id = ((g.user_session.record.get(b"user_id") or b"").decode("utf-8") @@ -448,7 +445,7 @@ def show_temp_trait_page(): return render_template("show_trait.html", **template_vars.__dict__) -@main_views.route("/show_trait") +@app.route("/show_trait") def show_trait_page(): def __show_trait__(privileges_data): assert len(privileges_data) == 1 @@ -486,7 +483,7 @@ def show_trait_page(): }).either(__failure__, __show_trait__) -@main_views.route("/heatmap", methods=('POST',)) +@app.route("/heatmap", methods=('POST',)) def heatmap_page(): start_vars = request.form temp_uuid = uuid.uuid4() @@ -522,7 +519,7 @@ def heatmap_page(): return rendered_template -@main_views.route("/bnw_page", methods=('POST',)) +@app.route("/bnw_page", methods=('POST',)) def bnw_page(): start_vars = request.form @@ -539,7 +536,7 @@ def bnw_page(): return rendered_template -@main_views.route("/webgestalt_page", methods=('POST',)) +@app.route("/webgestalt_page", methods=('POST',)) def webgestalt_page(): start_vars = request.form @@ -556,7 +553,7 @@ def webgestalt_page(): return rendered_template -@main_views.route("/geneweaver_page", methods=('POST',)) +@app.route("/geneweaver_page", methods=('POST',)) def geneweaver_page(): start_vars = request.form @@ -573,7 +570,7 @@ def geneweaver_page(): return rendered_template -@main_views.route("/comparison_bar_chart", methods=('POST',)) +@app.route("/comparison_bar_chart", methods=('POST',)) def comp_bar_chart_page(): start_vars = request.form @@ -594,12 +591,12 @@ def comp_bar_chart_page(): return rendered_template -@main_views.route("/mapping_results_container") +@app.route("/mapping_results_container") def mapping_results_container_page(): return render_template("mapping_results_container.html") -@main_views.route("/loading", methods=('POST',)) +@app.route("/loading", methods=('POST',)) def loading_page(): initial_start_vars = request.form start_vars_container = {} @@ -656,7 +653,7 @@ def loading_page(): return rendered_template -@main_views.route("/run_mapping", methods=('POST','GET')) +@app.route("/run_mapping", methods=('POST','GET')) def mapping_results_page(): if request.method == "GET" and (hash_of_inputs := request.args.get("hash")): hash_of_inputs = request.args.get("hash") @@ -781,7 +778,7 @@ def mapping_results_page(): return rendered_template -@main_views.route("/cache_mapping_inputs", methods=('POST',)) +@app.route("/cache_mapping_inputs", methods=('POST',)) def cache_mapping_inputs(): ONE_MONTH = 60 * 60 * 24 * 30 cache_id = request.form.get("inputs_hash") @@ -790,7 +787,7 @@ def cache_mapping_inputs(): return "Success" -@main_views.route("/export_mapping_results", methods=('POST',)) +@app.route("/export_mapping_results", methods=('POST',)) def export_mapping_results(): file_path = request.form.get("results_path") results_csv = open(file_path, "r").read() @@ -801,7 +798,7 @@ def export_mapping_results(): return response -@main_views.route("/export_corr_matrix", methods=('POST',)) +@app.route("/export_corr_matrix", methods=('POST',)) def export_corr_matrix(): file_path = request.form.get("export_filepath") file_name = request.form.get("export_filename") @@ -813,7 +810,7 @@ def export_corr_matrix(): return response -@main_views.route("/export", methods=('POST',)) +@app.route("/export", methods=('POST',)) def export(): svg_xml = request.form.get("data", "Invalid data") filename = request.form.get("filename", "manhattan_plot_snp") @@ -822,7 +819,7 @@ def export(): return response -@main_views.route("/export_pdf", methods=('POST',)) +@app.route("/export_pdf", methods=('POST',)) def export_pdf(): import cairosvg svg_xml = request.form.get("data", "Invalid data") @@ -833,7 +830,7 @@ def export_pdf(): return response -@main_views.route("/network_graph", methods=('POST',)) +@app.route("/network_graph", methods=('POST',)) def network_graph_page(): start_vars = request.form traits = [trait.strip() for trait in start_vars['trait_list'].split(',')] @@ -857,7 +854,7 @@ def __handle_correlation_error__(exc): "error-message": exc.args[0] }) -@main_views.route("/corr_compute", methods=('POST', 'GET')) +@app.route("/corr_compute", methods=('POST', 'GET')) def corr_compute_page(): with Redis.from_url(get_setting(app, "REDIS_URL"), decode_responses=True) as rconn: if request.method == "POST": @@ -876,7 +873,7 @@ def corr_compute_page(): }) jobs.run(job_id, get_setting(app, "REDIS_URL")) - return redirect(url_for("main_views.corr_compute_page", job_id=str(job_id))) + return redirect(url_for("corr_compute_page", job_id=str(job_id))) job = jobs.job( rconn, UUID(request.args.get("job_id"))).maybe( @@ -902,7 +899,7 @@ def corr_compute_page(): return render_template("loading_corrs.html") -@main_views.route("/corr_matrix", methods=('POST',)) +@app.route("/corr_matrix", methods=('POST',)) def corr_matrix_page(): start_vars = request.form traits = [trait.strip() for trait in start_vars['trait_list'].split(',')] @@ -917,7 +914,7 @@ def corr_matrix_page(): return render_template("empty_collection.html", **{'tool': 'Correlation Matrix'}) -@main_views.route("/corr_scatter_plot") +@app.route("/corr_scatter_plot") def corr_scatter_plot_page(): template_vars = corr_scatter_plot.CorrScatterPlot(request.args) template_vars.js_data = json.dumps(template_vars.js_data, @@ -926,21 +923,21 @@ def corr_scatter_plot_page(): return render_template("corr_scatterplot.html", **template_vars.__dict__) -@main_views.route("/snp_browser", methods=('GET',)) +@app.route("/snp_browser", methods=('GET',)) def snp_browser_page(): with database_connection() as conn, conn.cursor() as cursor: template_vars = snp_browser.SnpBrowser(cursor, request.args) return render_template("snp_browser.html", **template_vars.__dict__) -@main_views.route("/db_info", methods=('GET',)) +@app.route("/db_info", methods=('GET',)) def db_info_page(): template_vars = InfoPage(request.args) return render_template("info_page.html", **template_vars.__dict__) -@main_views.route("/snp_browser_table", methods=('GET',)) +@app.route("/snp_browser_table", methods=('GET',)) def snp_browser_table(): with database_connection() as conn, conn.cursor() as cursor: snp_table_data = snp_browser.SnpBrowser(cursor, request.args) @@ -954,32 +951,32 @@ def snp_browser_table(): return flask.jsonify(current_page) -@main_views.route("/tutorial/WebQTLTour", methods=('GET',)) +@app.route("/tutorial/WebQTLTour", methods=('GET',)) def tutorial_page(): # ZS: Currently just links to GN1 return redirect("http://gn1.genenetwork.org/tutorial/WebQTLTour/") -@main_views.route("/tutorial/security", methods=('GET',)) +@app.route("/tutorial/security", methods=('GET',)) def security_tutorial_page(): # ZS: Currently just links to GN1 return render_template("admin/security_help.html") -@main_views.route("/submit_bnw", methods=('POST',)) +@app.route("/submit_bnw", methods=('POST',)) def submit_bnw(): return render_template("empty_collection.html", **{'tool': 'Correlation Matrix'}) # Take this out or secure it before putting into production -@main_views.route("/get_temp_data") +@app.route("/get_temp_data") def get_temp_data(): temp_uuid = request.args['key'] return flask.jsonify(temp_data.TempData(temp_uuid).get_all()) -@main_views.route("/browser_input", methods=('GET',)) +@app.route("/browser_input", methods=('GET',)) def browser_inputs(): """ Returns JSON from tmp directory for the purescript genome browser""" @@ -1007,7 +1004,7 @@ def json_default_handler(obj): type(obj), repr(obj))) -@main_views.route("/admin/data-sample/diffs/") +@app.route("/admin/data-sample/diffs/") @edit_access_required def display_diffs_admin(): TMPDIR = app.config.get("TMPDIR") @@ -1021,7 +1018,7 @@ def display_diffs_admin(): files=files) -@main_views.route("/user/data-sample/diffs/") +@app.route("/user/data-sample/diffs/") def display_diffs_users(): TMPDIR = app.config.get("TMPDIR") DIFF_DIR = f"{TMPDIR}/sample-data/diffs" @@ -1036,7 +1033,7 @@ def display_diffs_users(): files=files) -@main_views.route("/genewiki/") +@app.route("/genewiki/") def display_generif_page(symbol): """Fetch GeneRIF metadata from GN3 and display it""" entries = requests.get( @@ -1052,7 +1049,7 @@ def display_generif_page(symbol): ) -@main_views.route("/dataset/", methods=('GET',)) +@app.route("/dataset/", methods=('GET',)) def get_dataset(name): metadata = requests.get( urljoin( @@ -1075,7 +1072,7 @@ def get_dataset(name): ) -@main_views.route("/publication/", methods=('GET',)) +@app.route("/publication/", methods=('GET',)) def get_publication(name): metadata = requests.get( urljoin( @@ -1088,7 +1085,7 @@ def get_publication(name): ) -@main_views.route("/phenotype/", methods=('GET',)) +@app.route("/phenotype/", methods=('GET',)) def get_phenotype(name): metadata = requests.get( urljoin( -- cgit v1.2.3