aboutsummaryrefslogtreecommitdiff
path: root/wqflask
diff options
context:
space:
mode:
authorFrederick Muriuki Muriithi2023-06-16 10:53:08 +0300
committerFrederick Muriuki Muriithi2023-06-20 13:36:50 +0300
commit883a7cba581f34eba48978746e2ff8bbb93020d8 (patch)
tree433c1b0b6db451b841810b2fdb4f2fd07bc9377b /wqflask
parent7127095f2b2c54175d1360c1ddb3e0f87b6ede98 (diff)
downloadgenenetwork2-883a7cba581f34eba48978746e2ff8bbb93020d8.tar.gz
Add `create_app()` application factory
Create the application and set up configs and other things within an application factory function. Fix obvious egregious errors preventing the application from starting up correctly.
Diffstat (limited to 'wqflask')
-rw-r--r--wqflask/base/data_set/__init__.py2
-rw-r--r--wqflask/base/data_set/datasetgroup.py3
-rw-r--r--wqflask/gn2_main.py60
-rw-r--r--wqflask/run_gunicorn.py2
-rw-r--r--wqflask/runserver.py2
-rw-r--r--wqflask/utility/authentication_tools.py4
-rw-r--r--wqflask/utility/startup_config.py4
-rw-r--r--wqflask/wqflask/__init__.py172
-rw-r--r--wqflask/wqflask/app_errors.py5
-rw-r--r--wqflask/wqflask/oauth2/client.py34
-rw-r--r--wqflask/wqflask/oauth2/request_utils.py7
-rw-r--r--wqflask/wqflask/templates/base.html18
-rw-r--r--wqflask/wqflask/templates/search_result_page.html24
-rw-r--r--wqflask/wqflask/templates/show_trait.html30
-rw-r--r--wqflask/wqflask/templates/tool_buttons.html2
-rw-r--r--wqflask/wqflask/views.py1
16 files changed, 188 insertions, 182 deletions
diff --git a/wqflask/base/data_set/__init__.py b/wqflask/base/data_set/__init__.py
index ad51e47e..c2c0aef1 100644
--- a/wqflask/base/data_set/__init__.py
+++ b/wqflask/base/data_set/__init__.py
@@ -115,7 +115,7 @@ def datasets(group_name, this_group=None, redis_conn=Redis()):
dataset_menu.append(dict(tissue=tissue_name,
datasets=[(dataset, dataset_short)]))
- if get_setting_bool("USE_REDIS"):
+ if get_setting_bool(app, "USE_REDIS"):
redis_conn.set(key, pickle.dumps(dataset_menu, pickle.HIGHEST_PROTOCOL))
redis_conn.expire(key, 60 * 5)
diff --git a/wqflask/base/data_set/datasetgroup.py b/wqflask/base/data_set/datasetgroup.py
index 90c59a1e..a44cf18d 100644
--- a/wqflask/base/data_set/datasetgroup.py
+++ b/wqflask/base/data_set/datasetgroup.py
@@ -15,6 +15,7 @@ from wqflask.database import database_connection
from utility.configuration import (
locate,
flat_files,
+ get_setting,
flat_file_exists,
get_setting_bool,
locate_ignore_error)
@@ -128,7 +129,7 @@ class DatasetGroup:
return study_samples
def get_genofiles(self):
- jsonfile = "%s/%s.json" % (webqtlConfig.GENODIR, self.name)
+ jsonfile = "%s/%s.json" % (get_setting(app, "WEBQTL_GENODIR"), self.name)
try:
f = open(jsonfile)
except:
diff --git a/wqflask/gn2_main.py b/wqflask/gn2_main.py
new file mode 100644
index 00000000..923a35d3
--- /dev/null
+++ b/wqflask/gn2_main.py
@@ -0,0 +1,60 @@
+"""Main app creation module"""
+import time
+
+from flask import g, session, request
+
+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
diff --git a/wqflask/run_gunicorn.py b/wqflask/run_gunicorn.py
index 03f310eb..af117466 100644
--- a/wqflask/run_gunicorn.py
+++ b/wqflask/run_gunicorn.py
@@ -9,7 +9,7 @@
print("===> Starting up Gunicorn process")
-from wqflask import app
+from gn2_main import app
from utility.startup_config import app_config
app_config()
diff --git a/wqflask/runserver.py b/wqflask/runserver.py
index 8f01425e..fed3d356 100644
--- a/wqflask/runserver.py
+++ b/wqflask/runserver.py
@@ -7,7 +7,7 @@
#
# /sbin/iptables -A INPUT -p tcp -i eth0 -s ! 71.236.239.43 --dport 5003 -j DROP
-from wqflask import app
+from gn2_main import app
from utility.startup_config import app_config
from utility.configuration import get_setting, get_setting_int
diff --git a/wqflask/utility/authentication_tools.py b/wqflask/utility/authentication_tools.py
index 3d732228..0f48d26f 100644
--- a/wqflask/utility/authentication_tools.py
+++ b/wqflask/utility/authentication_tools.py
@@ -37,7 +37,7 @@ def check_resource_availability(dataset, user_id, trait_id=None):
return webqtlConfig.SUPER_PRIVILEGES
response = None
- the_url = f"{get_setting('GN_PROXY_URL')}available?resource={resource_id}&user={user_id}"
+ the_url = f"{get_setting(app, 'GN_PROXY_URL')}available?resource={resource_id}&user={user_id}"
try:
response = json.loads(requests.get(the_url).content)
except:
@@ -94,7 +94,7 @@ def get_group_code(dataset):
def check_admin(resource_id=None):
the_url = (
- f"{get_setting('GN_PROXY_URL')}available?resource={resource_id}"
+ f"{get_setting(app, 'GN_PROXY_URL')}available?resource={resource_id}"
f"&user={g.user_session.user_id}")
try:
response = json.loads(requests.get(the_url).content)['admin']
diff --git a/wqflask/utility/startup_config.py b/wqflask/utility/startup_config.py
index 5ab43b1a..59f78d55 100644
--- a/wqflask/utility/startup_config.py
+++ b/wqflask/utility/startup_config.py
@@ -1,6 +1,4 @@
-
-from wqflask import app
-
+"""Utility to print out some startup messages."""
from utility.configuration import show_settings
from utility.configuration import get_setting_int
from utility.configuration import get_setting
diff --git a/wqflask/wqflask/__init__.py b/wqflask/wqflask/__init__.py
index 86370183..3b7551e6 100644
--- a/wqflask/wqflask/__init__.py
+++ b/wqflask/wqflask/__init__.py
@@ -17,8 +17,6 @@ from utility.tools import set_mandatory_settings
from utility.hmac import data_hmac, url_for_hmac
from utility.configuration import tempdir, override_from_envvars
-from gn3.authentication import DataRole, AdminRole
-
from wqflask.database import parse_db_url
from wqflask.user_session import UserSession
from wqflask.group_manager import group_management
@@ -42,115 +40,6 @@ 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(toplevel)
-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():
- 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
@@ -160,5 +49,62 @@ from wqflask import update_search_results
from wqflask import docs
from wqflask import db_info
-import wqflask.views
-import wqflask.partial_correlations_views
+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(toplevel)
+ 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/app_errors.py b/wqflask/wqflask/app_errors.py
index c24fc9be..0a1f87ec 100644
--- a/wqflask/wqflask/app_errors.py
+++ b/wqflask/wqflask/app_errors.py
@@ -1,9 +1,12 @@
"""Handle errors at the application's top-level"""
+import os
+import sys
+import random
import datetime
import traceback
import werkzeug
-from flask import request, render_template, current_app as app
+from flask import request, make_response, render_template, current_app as app
from wqflask.decorators import AuthorisationError
diff --git a/wqflask/wqflask/oauth2/client.py b/wqflask/wqflask/oauth2/client.py
index 2a06b156..91cbb3e9 100644
--- a/wqflask/wqflask/oauth2/client.py
+++ b/wqflask/wqflask/oauth2/client.py
@@ -9,6 +9,8 @@ from pymonad.maybe import Just, Maybe, Nothing
from pymonad.either import Left, Right, Either
from authlib.integrations.requests_client import OAuth2Session
+from utility.configuration import get_setting
+
from wqflask.oauth2 import session
from wqflask.oauth2.checks import user_logged_in
@@ -17,10 +19,9 @@ SCOPE = ("profile group role resource register-client user masquerade "
def oauth2_client():
def __client__(token) -> OAuth2Session:
- from utility.tools import (
- GN_SERVER_URL, OAUTH2_CLIENT_ID, OAUTH2_CLIENT_SECRET)
return OAuth2Session(
- OAUTH2_CLIENT_ID, OAUTH2_CLIENT_SECRET,
+ get_setting(app, "OAUTH2_CLIENT_ID"),
+ get_setting(app, "OAUTH2_CLIENT_SECRET"),
scope=SCOPE, token_endpoint_auth_method="client_secret_post",
token=token)
return session.user_token().either(
@@ -39,13 +40,12 @@ def __no_token__(_err) -> Left:
def oauth2_get(uri_path: str, data: dict = {}, **kwargs) -> Either:
def __get__(token) -> Either:
- from utility.tools import (
- GN_SERVER_URL, OAUTH2_CLIENT_ID, OAUTH2_CLIENT_SECRET)
client = OAuth2Session(
- OAUTH2_CLIENT_ID, OAUTH2_CLIENT_SECRET,
+ get_setting(app, "OAUTH2_CLIENT_ID"),
+ get_setting(app, "OAUTH2_CLIENT_SECRET"),
token=token, scope=SCOPE)
resp = client.get(
- urljoin(GN_SERVER_URL, uri_path),
+ urljoin(get_setting(app, "GN_SERVER_URL"), uri_path),
data=data,
**kwargs)
if resp.status_code == 200:
@@ -59,13 +59,13 @@ def oauth2_post(
uri_path: str, data: Optional[dict] = None, json: Optional[dict] = None,
**kwargs) -> Either:
def __post__(token) -> Either:
- from utility.tools import (
- GN_SERVER_URL, OAUTH2_CLIENT_ID, OAUTH2_CLIENT_SECRET)
client = OAuth2Session(
- OAUTH2_CLIENT_ID, OAUTH2_CLIENT_SECRET,
+ get_setting(app, "OAUTH2_CLIENT_ID"),
+ get_setting(app, "OAUTH2_CLIENT_SECRET"),
token=token, scope=SCOPE)
resp = client.post(
- urljoin(GN_SERVER_URL, uri_path), data=data, json=json,
+ urljoin(get_setting(app, "GN_SERVER_URL"), uri_path),
+ data=data, json=json,
**kwargs)
if resp.status_code == 200:
return Right(resp.json())
@@ -75,22 +75,20 @@ def oauth2_post(
return session.user_token().either(__no_token__, __post__)
def no_token_get(uri_path: str, **kwargs) -> Either:
- from utility.tools import GN_SERVER_URL
- resp = requests.get(urljoin(GN_SERVER_URL, uri_path), **kwargs)
+ resp = requests.get(urljoin(
+ get_setting(app, "GN_SERVER_URL"), uri_path), **kwargs)
if resp.status_code == 200:
return Right(resp.json())
return Left(resp)
def no_token_post(uri_path: str, **kwargs) -> Either:
- from utility.tools import (
- GN_SERVER_URL, OAUTH2_CLIENT_ID, OAUTH2_CLIENT_SECRET)
data = kwargs.get("data", {})
the_json = kwargs.get("json", {})
request_data = {
**data,
**the_json,
- "client_id": OAUTH2_CLIENT_ID,
- "client_secret": OAUTH2_CLIENT_SECRET
+ "client_id": get_setting(app, "OAUTH2_CLIENT_ID"),
+ "client_secret": get_setting(app, "OAUTH2_CLIENT_SECRET")
}
new_kwargs = {
**{
@@ -99,7 +97,7 @@ def no_token_post(uri_path: str, **kwargs) -> Either:
},
("data" if bool(data) else "json"): request_data
}
- resp = requests.post(urljoin(GN_SERVER_URL, uri_path),
+ resp = requests.post(urljoin(get_setting(app, "GN_SERVER_URL"), uri_path),
**new_kwargs)
if resp.status_code == 200:
return Right(resp.json())
diff --git a/wqflask/wqflask/oauth2/request_utils.py b/wqflask/wqflask/oauth2/request_utils.py
index 992720f1..b7d57ad8 100644
--- a/wqflask/wqflask/oauth2/request_utils.py
+++ b/wqflask/wqflask/oauth2/request_utils.py
@@ -7,16 +7,17 @@ from flask import (
flash, request, session, url_for, redirect, Response, render_template,
current_app as app)
+from utility.configuration import get_setting
+
from .client import SCOPE, oauth2_get
def authserver_authorise_uri():
- from utility.tools import GN_SERVER_URL, OAUTH2_CLIENT_ID
req_baseurl = urlparse(request.base_url)
host_uri = f"{req_baseurl.scheme}://{req_baseurl.netloc}/"
return urljoin(
- GN_SERVER_URL,
+ get_setting(app, "GN_SERVER_URL"),
"oauth2/authorise?response_type=code"
- f"&client_id={OAUTH2_CLIENT_ID}"
+ f"&client_id={get_setting(app, 'OAUTH2_CLIENT_ID')}"
f"&redirect_uri={urljoin(host_uri, 'oauth2/code')}")
def raise_unimplemented():
diff --git a/wqflask/wqflask/templates/base.html b/wqflask/wqflask/templates/base.html
index 1328d229..5a881f51 100644
--- a/wqflask/wqflask/templates/base.html
+++ b/wqflask/wqflask/templates/base.html
@@ -12,7 +12,7 @@
</script>
<link rel="icon" type="image/png" sizes="64x64" href="/static/new/images/CITGLogo.png">
<link rel="apple-touch-icon" type="image/png" sizes="64x64" href="/static/new/images/CITGLogo.png">
- <link REL="stylesheet" TYPE="text/css" href="{{ url_for('css', filename='bootstrap/css/bootstrap.css') }}" />
+ <link REL="stylesheet" TYPE="text/css" href="{{ url_for('toplevel.main_views.css', filename='bootstrap/css/bootstrap.css') }}" />
<link REL="stylesheet" TYPE="text/css" href="/static/new/css/bootstrap-custom.css" />
<link REL="stylesheet" TYPE="text/css" href="/static/new/css/non-responsive.css" />
<link REL="stylesheet" TYPE="text/css" href="/static/new/css/docs.css" />
@@ -30,10 +30,10 @@
border-radius: 1rem;
}
table.dataTable thead .sorting_asc {
- background-image: url({{ url_for("js", filename="DataTables/images/sort_asc_disabled.png") }});
+ background-image: url({{ url_for("toplevel.main_views.js", filename="DataTables/images/sort_asc_disabled.png") }});
}
table.dataTable thead .sorting_desc {
- background-image: url({{ url_for("js", filename="DataTables/images/sort_desc_disabled.png") }});
+ background-image: url({{ url_for("toplevel.main_views.js", filename="DataTables/images/sort_desc_disabled.png") }});
}
@@ -336,8 +336,8 @@
<!-- <button class="btn btn-primary">Save changes</button>-->
<!--</div>-->
</div>
- <script src="{{ url_for('js', filename='jquery/jquery.min.js') }}" type="text/javascript"></script>
- <script src="{{ url_for('js', filename='bootstrap/js/bootstrap.min.js') }}" type="text/javascript"></script>
+ <script src="{{ url_for('toplevel.main_views.js', filename='jquery/jquery.min.js') }}" type="text/javascript"></script>
+ <script src="{{ url_for('toplevel.main_views.js', filename='bootstrap/js/bootstrap.min.js') }}" type="text/javascript"></script>
<script src="/static/new/javascript/search_autocomplete.js"></script>
<script>
//http://stackoverflow.com/questions/11521763/bootstrap-scrollspy-not-working
@@ -389,11 +389,11 @@
});
</script>
- <script src="{{ url_for('js', filename='jquery-cookie/jquery.cookie.js') }}" type="text/javascript"></script>
+ <script src="{{ url_for('toplevel.main_views.js', filename='jquery-cookie/jquery.cookie.js') }}" type="text/javascript"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jqueryui/1.12.1/jquery-ui.min.js"></script>
- <!-- <script src="{{ url_for('js', filename='jquery-ui/jquery-ui.min.js') }}" type="text/javascript"></script> -->
- <script language="javascript" type="text/javascript" src="{{ url_for('js', filename='colorbox/jquery.colorbox-min.js') }}"></script>
- <script language="javascript" type="text/javascript" src="{{ url_for('js', filename='js_alt/parsley.min.js') }}"></script>
+ <!-- <script src="{{ url_for('toplevel.main_views.js', filename='jquery-ui/jquery-ui.min.js') }}" type="text/javascript"></script> -->
+ <script language="javascript" type="text/javascript" src="{{ url_for('toplevel.main_views.js', filename='colorbox/jquery.colorbox-min.js') }}"></script>
+ <script language="javascript" type="text/javascript" src="{{ url_for('toplevel.main_views.js', filename='js_alt/parsley.min.js') }}"></script>
{% block js %}
{% endblock %}
<script type="text/javascript">
diff --git a/wqflask/wqflask/templates/search_result_page.html b/wqflask/wqflask/templates/search_result_page.html
index 495c5669..fb92b9ed 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 %}
- <link rel="stylesheet" type="text/css" href="{{ url_for('css', filename='DataTables/css/jquery.dataTables.css') }}" />
- <link rel="stylesheet" type="text/css" href="{{ url_for('css', filename='fontawesome/css/font-awesome.min.css') }}" />
- <link rel="stylesheet" type="text/css" href="{{ url_for('js', filename='DataTablesExtensions/buttonStyles/css/buttons.dataTables.min.css') }}">
- <link rel="stylesheet" type="text/css" href="{{ url_for('css', filename='fontawesome/css/all.min.css') }}"/>
+ <link rel="stylesheet" type="text/css" href="{{ url_for('toplevel.main_views.css', filename='DataTables/css/jquery.dataTables.css') }}" />
+ <link rel="stylesheet" type="text/css" href="{{ url_for('toplevel.main_views.css', filename='fontawesome/css/font-awesome.min.css') }}" />
+ <link rel="stylesheet" type="text/css" href="{{ url_for('toplevel.main_views.js', filename='DataTablesExtensions/buttonStyles/css/buttons.dataTables.min.css') }}">
+ <link rel="stylesheet" type="text/css" href="{{ url_for('toplevel.main_views.css', filename='fontawesome/css/all.min.css') }}"/>
<link href="https://code.jquery.com/ui/1.12.1/themes/base/jquery-ui.css" rel="stylesheet" type="text/css" />
<link rel="stylesheet" type="text/css" href="/static/new/css/show_trait.css" />
<link rel="stylesheet" type="text/css" href="static/new/css/trait_list.css" />
@@ -153,14 +153,14 @@
{% endblock %}
{% block js %}
- <script language="javascript" type="text/javascript" src="{{ url_for('js', filename='js_alt/md5.min.js') }}"></script>
- <script language="javascript" type="text/javascript" src="{{ url_for('js', filename='DataTables/js/jquery.dataTables.min.js') }}"></script>
- <script language="javascript" type="text/javascript" src="{{ url_for('js', filename='DataTablesExtensions/scroller/js/dataTables.scroller.min.js') }}"></script>
- <script language="javascript" type="text/javascript" src="{{ url_for('js', filename='jszip/jszip.min.js') }}"></script>
- <script language="javascript" type="text/javascript" src="{{ url_for('js', filename='DataTablesExtensions/plugins/sorting/natural.js') }}"></script>
- <script language="javascript" type="text/javascript" src="{{ url_for('js', filename='DataTablesExtensions/buttons/js/dataTables.buttons.min.js') }}"></script>
- <script language="javascript" type="text/javascript" src="{{ url_for('js', filename='DataTablesExtensions/buttons/js/buttons.colVis.min.js') }}"></script>
- <script language="javascript" type="text/javascript" src="{{ url_for('js', filename='fontawesome/js/all.min.js') }}"></script>
+ <script language="javascript" type="text/javascript" src="{{ url_for('toplevel.main_views.js', filename='js_alt/md5.min.js') }}"></script>
+ <script language="javascript" type="text/javascript" src="{{ url_for('toplevel.main_views.js', filename='DataTables/js/jquery.dataTables.min.js') }}"></script>
+ <script language="javascript" type="text/javascript" src="{{ url_for('toplevel.main_views.js', filename='DataTablesExtensions/scroller/js/dataTables.scroller.min.js') }}"></script>
+ <script language="javascript" type="text/javascript" src="{{ url_for('toplevel.main_views.js', filename='jszip/jszip.min.js') }}"></script>
+ <script language="javascript" type="text/javascript" src="{{ url_for('toplevel.main_views.js', filename='DataTablesExtensions/plugins/sorting/natural.js') }}"></script>
+ <script language="javascript" type="text/javascript" src="{{ url_for('toplevel.main_views.js', filename='DataTablesExtensions/buttons/js/dataTables.buttons.min.js') }}"></script>
+ <script language="javascript" type="text/javascript" src="{{ url_for('toplevel.main_views.js', filename='DataTablesExtensions/buttons/js/buttons.colVis.min.js') }}"></script>
+ <script language="javascript" type="text/javascript" src="{{ url_for('toplevel.main_views.js', filename='fontawesome/js/all.min.js') }}"></script>
<script language="javascript" type="text/javascript" src="/static/new/javascript/search_results.js"></script>
<script language="javascript" type="text/javascript" src="/static/new/javascript/table_functions.js"></script>
diff --git a/wqflask/wqflask/templates/show_trait.html b/wqflask/wqflask/templates/show_trait.html
index 84231d34..3b3a8ac7 100644
--- a/wqflask/wqflask/templates/show_trait.html
+++ b/wqflask/wqflask/templates/show_trait.html
@@ -8,9 +8,9 @@
<link rel="stylesheet" type="text/css" href="/static/new/css/box_plot.css" />
<link rel="stylesheet" type="text/css" href="/static/new/css/prob_plot.css" />
<link rel="stylesheet" type="text/css" href="/static/new/css/scatter-matrix.css" />
- <link rel="stylesheet" type="text/css" href="{{ url_for('css', filename='d3-tip/d3-tip.css') }}" />
- <link rel="stylesheet" type="text/css" href="{{ url_for('css', filename='DataTables/css/jquery.dataTables.css') }}" />
- <link rel="stylesheet" type="text/css" href="{{ url_for('css', filename='nouislider/nouislider.min.css') }}" />
+ <link rel="stylesheet" type="text/css" href="{{ url_for('toplevel.main_views.css', filename='d3-tip/d3-tip.css') }}" />
+ <link rel="stylesheet" type="text/css" href="{{ url_for('toplevel.main_views.css', filename='DataTables/css/jquery.dataTables.css') }}" />
+ <link rel="stylesheet" type="text/css" href="{{ url_for('toplevel.main_views.css', filename='nouislider/nouislider.min.css') }}" />
<link href="https://code.jquery.com/ui/1.12.1/themes/base/jquery-ui.css" rel="stylesheet" type="text/css" />
<link rel="stylesheet" type="text/css" href="/static/new/css/trait_list.css" />
<link rel="stylesheet" type="text/css" href="/static/new/css/show_trait.css" />
@@ -139,13 +139,13 @@
$('.collapse').collapse()
</script>
- <script language="javascript" type="text/javascript" src="{{ url_for('js', filename='d3js/d3.min.js') }}"></script>
- <script language="javascript" type="text/javascript" src="{{ url_for('js', filename='js_alt/underscore.min.js') }}"></script>
- <script language="javascript" type="text/javascript" src="{{ url_for('js', filename='underscore-string/underscore.string.min.js') }}"></script>
- <script language="javascript" type="text/javascript" src="{{ url_for('js', filename='d3-tip/d3-tip.js') }}"></script>
- <script language="javascript" type="text/javascript" src="{{ url_for('js', filename='js_alt/jstat.min.js') }}"></script>
- <script language="javascript" type="text/javascript" src="{{ url_for('js', filename='shapiro-wilk/shapiro-wilk.js') }}"></script>
- <script language="javascript" type="text/javascript" src="{{ url_for('js', filename='plotly/plotly.min.js') }}"></script>
+ <script language="javascript" type="text/javascript" src="{{ url_for('toplevel.main_views.js', filename='d3js/d3.min.js') }}"></script>
+ <script language="javascript" type="text/javascript" src="{{ url_for('toplevel.main_views.js', filename='js_alt/underscore.min.js') }}"></script>
+ <script language="javascript" type="text/javascript" src="{{ url_for('toplevel.main_views.js', filename='underscore-string/underscore.string.min.js') }}"></script>
+ <script language="javascript" type="text/javascript" src="{{ url_for('toplevel.main_views.js', filename='d3-tip/d3-tip.js') }}"></script>
+ <script language="javascript" type="text/javascript" src="{{ url_for('toplevel.main_views.js', filename='js_alt/jstat.min.js') }}"></script>
+ <script language="javascript" type="text/javascript" src="{{ url_for('toplevel.main_views.js', filename='shapiro-wilk/shapiro-wilk.js') }}"></script>
+ <script language="javascript" type="text/javascript" src="{{ url_for('toplevel.main_views.js', filename='plotly/plotly.min.js') }}"></script>
<script language="javascript" type="text/javascript" src="/static/new/javascript/colorbrewer.js"></script>
<script language="javascript" type="text/javascript" src="/static/new/javascript/stats.js"></script>
@@ -154,11 +154,11 @@
<script language="javascript" type="text/javascript" src="/static/new/javascript/compare_traits_scatterplot.js"></script>
- <script language="javascript" type="text/javascript" src="{{ url_for('js', filename='DataTables/js/jquery.dataTables.js') }}"></script>
- <script language="javascript" type="text/javascript" src="{{ url_for('js', filename='DataTablesExtensions/plugins/sorting/scientific.js') }}"></script>
- <script language="javascript" type="text/javascript" src="{{ url_for('js', filename='DataTablesExtensions/plugins/sorting/natural.js') }}"></script>
- <script language="javascript" type="text/javascript" src="{{ url_for('js', filename='DataTablesExtensions/scroller/js/dataTables.scroller.min.js') }}"></script>
- <script language="javascript" type="text/javascript" src="{{ url_for('js', filename='nouislider/nouislider.js') }}"></script>
+ <script language="javascript" type="text/javascript" src="{{ url_for('toplevel.main_views.js', filename='DataTables/js/jquery.dataTables.js') }}"></script>
+ <script language="javascript" type="text/javascript" src="{{ url_for('toplevel.main_views.js', filename='DataTablesExtensions/plugins/sorting/scientific.js') }}"></script>
+ <script language="javascript" type="text/javascript" src="{{ url_for('toplevel.main_views.js', filename='DataTablesExtensions/plugins/sorting/natural.js') }}"></script>
+ <script language="javascript" type="text/javascript" src="{{ url_for('toplevel.main_views.js', filename='DataTablesExtensions/scroller/js/dataTables.scroller.min.js') }}"></script>
+ <script language="javascript" type="text/javascript" src="{{ url_for('toplevel.main_views.js', filename='nouislider/nouislider.js') }}"></script>
<script language="javascript" type="text/javascript" src="/static/new/javascript/table_functions.js"></script>
<script language="javascript" type="text/javascript" src="/static/new/javascript/create_datatable.js"></script>
<script language="javascript" type="text/javascript" src="/static/new/javascript/initialize_show_trait_tables.js"></script>
diff --git a/wqflask/wqflask/templates/tool_buttons.html b/wqflask/wqflask/templates/tool_buttons.html
index c6d1476c..95064dbb 100644
--- a/wqflask/wqflask/templates/tool_buttons.html
+++ b/wqflask/wqflask/templates/tool_buttons.html
@@ -32,7 +32,7 @@
<button id="partial-correlations"
class="btn btn-primary submit_special"
- data-url="{{url_for('partial_correlations')}}"
+ data-url="{{url_for('toplevel.partial_correlations.partial_correlations')}}"
title="Run partial correlations with the selected traits">
Partial Correlations
</button>
diff --git a/wqflask/wqflask/views.py b/wqflask/wqflask/views.py
index ebd273af..689e3436 100644
--- a/wqflask/wqflask/views.py
+++ b/wqflask/wqflask/views.py
@@ -30,7 +30,6 @@ from flask import current_app as app
from flask import g
from flask import Response
from flask import request
-from flask import make_response
from flask import render_template
from flask import send_from_directory
from flask import redirect