diff options
-rw-r--r-- | etc/default_settings.py | 10 | ||||
-rw-r--r-- | wqflask/wqflask/__init__.py | 15 | ||||
-rw-r--r-- | wqflask/wqflask/startup.py | 43 | ||||
-rw-r--r-- | wqflask/wqflask/templates/startup_errors.html | 20 |
4 files changed, 81 insertions, 7 deletions
diff --git a/etc/default_settings.py b/etc/default_settings.py index 38c0a110..0ffe6ae9 100644 --- a/etc/default_settings.py +++ b/etc/default_settings.py @@ -27,7 +27,7 @@ import sys with open("../etc/VERSION", "r") as version_file: GN_VERSION = version_file.read() -SECRET_KEY = "pleaseChangeThisToSomethingSecretInAnExternalConfigFileOrEnvvars" +SECRET_KEY = "" # Redis REDIS_URL = "redis://:@localhost:6379/0" @@ -43,6 +43,7 @@ GN_PROXY_URL="https://genenetwork.org/gn3-proxy/" SQL_URI = "mysql://gn2:mysql_password@localhost/db_webqtl_s" SQL_ALCHEMY_POOL_RECYCLE = 3600 GN_SERVER_URL = "http://localhost:8880/api/" # REST API server +AUTH_SERVER_URL="https://auth.genenetwork.org/" GN2_BASE_URL = "http://genenetwork.org/" # to pick up REST API GN2_BRANCH_URL = GN2_BASE_URL @@ -55,12 +56,7 @@ SECURITY_RECOVERABLE = True SECURITY_EMAIL_SENDER = "no-reply@genenetwork.org" SECURITY_POST_LOGIN_VIEW = "/thank_you" -# ---- SERVER_PORT needs an override before firing up the server -SERVER_PORT = os.environ['SERVER_PORT'] -if isinstance(SERVER_PORT, str): - SERVER_PORT = int(SERVER_PORT) # don't do this for other settings! -else: - SERVER_PORT = 5003 +SERVER_PORT = 5003 SECRET_HMAC_CODE = '\x08\xdf\xfa\x93N\x80\xd9\\H@\\\x9f`\x98d^\xb4a;\xc6OM\x946a\xbc\xfc\x80:*\xebc' diff --git a/wqflask/wqflask/__init__.py b/wqflask/wqflask/__init__.py index 9a608474..f4599a0b 100644 --- a/wqflask/wqflask/__init__.py +++ b/wqflask/wqflask/__init__.py @@ -3,6 +3,7 @@ import time import datetime from typing import Tuple +from pathlib import Path from urllib.parse import urljoin, urlparse import redis @@ -36,11 +37,19 @@ from wqflask.oauth2.request_utils import user_details, authserver_authorise_uri from wqflask.jupyter_notebooks import jupyter_notebooks +from wqflask.startup import ( + StartupError, + startup_errors, + check_mandatory_configs) + app = Flask(__name__) # See http://flask.pocoo.org/docs/config/#configuring-from-files # Note no longer use the badly named WQFLASK_OVERRIDES (nyi) +default_settings_file = Path(Path(__file__).parent.parent.parent, + "etc/default_settings.py") +app.config.from_pyfile(default_settings_file) app.config.from_envvar('GN2_SETTINGS') app.jinja_env.globals.update( @@ -54,6 +63,7 @@ app.jinja_env.globals.update( app.config["SESSION_REDIS"] = redis.from_url(app.config["REDIS_URL"]) + # Registering blueprints app.register_blueprint(glossary_blueprint, url_prefix="/glossary") app.register_blueprint(references_blueprint, url_prefix="/references") @@ -74,6 +84,11 @@ app.register_blueprint(oauth2, url_prefix="/oauth2") from wqflask.decorators import AuthorisationError from wqflask.app_errors import handle_authorisation_error app.register_error_handler(AuthorisationError, handle_authorisation_error) +try: + check_mandatory_configs(app) +except StartupError as serr: + app.startup_error = serr + app.register_blueprint(startup_errors, url_prefix="/") server_session = Session(app) diff --git a/wqflask/wqflask/startup.py b/wqflask/wqflask/startup.py new file mode 100644 index 00000000..e531aacb --- /dev/null +++ b/wqflask/wqflask/startup.py @@ -0,0 +1,43 @@ +"""Checks to do before the application is started.""" +from typing import Tuple + +from flask import Blueprint, current_app, render_template + +class StartupError(Exception): + """Base class for Application Check Errors.""" + +class MissingConfigurationError(StartupError): + """Raised in case of a missing required setting.""" + + def __init__(self, missing=Tuple[str, ...]): + """Initialise the MissingConfigurationError object.""" + super().__init__("At least one required configuration is missing.") + self.missing = missing + +startup_errors = Blueprint("app_check_errors", __name__) +__MANDATORY_CONFIGURATIONS__ = ( + "SECRET_KEY", + "REDIS_URL", # URI to Redis server + "SQL_URI", # URI to MariaDB server + "GN_SERVER_URL", # REST API Server + "AUTH_SERVER_URL" # Auth(entic/oris)ation Server +) + +def check_mandatory_configs(app): + """Check that all mandatory configuration settings are defined.""" + missing = tuple( + setting for setting in __MANDATORY_CONFIGURATIONS__ + if (setting not in app.config + or app.config.get(setting) is None + or app.config.get(setting).strip() == "")) + if len(missing) > 0: + print(missing) + raise MissingConfigurationError(missing) + +@startup_errors.route("/") +def error_index(): + """Display errors experienced at application startup""" + return render_template( + "startup_errors.html", + error_type = type(current_app.startup_error).__name__, + error_value = current_app.startup_error) diff --git a/wqflask/wqflask/templates/startup_errors.html b/wqflask/wqflask/templates/startup_errors.html new file mode 100644 index 00000000..82d85572 --- /dev/null +++ b/wqflask/wqflask/templates/startup_errors.html @@ -0,0 +1,20 @@ +{%extends "base.html"%} +{%block title%}Startup Error{%endblock%} +{%block content %} +{%if error_type == "MissingConfigurationError"%} + +<div class="container"> + <h1>Startup Error</h1> + + <p> + The application could not start due to the missing configuration settings + below: + <ul> + {%for setting in error_value.missing%} + <li class="text-danger"><strong>{{setting}}</strong></li> + {%endfor%} + </ul> + </p> +</div> +{%endif%} +{%endblock%} |