Externalize all configuration parameters Pt.I
This commit is contained in:
parent
dc98b1d500
commit
c1e3e8939a
@ -1,6 +1,7 @@
|
|||||||
from flask import Flask
|
from flask import Flask
|
||||||
|
|
||||||
import os
|
import os
|
||||||
|
import sys
|
||||||
import logging
|
import logging
|
||||||
from . import local_db
|
from . import local_db
|
||||||
|
|
||||||
@ -36,7 +37,6 @@ from BreCal.stubs.df_times import get_df_times
|
|||||||
from BreCal.services.schedule_routines import setup_schedule, run_schedule_permanently_in_background
|
from BreCal.services.schedule_routines import setup_schedule, run_schedule_permanently_in_background
|
||||||
|
|
||||||
def create_app(test_config=None, instance_path=None):
|
def create_app(test_config=None, instance_path=None):
|
||||||
|
|
||||||
app = Flask(__name__, instance_relative_config=True)
|
app = Flask(__name__, instance_relative_config=True)
|
||||||
app.config.from_mapping(
|
app.config.from_mapping(
|
||||||
SECRET_KEY='dev'
|
SECRET_KEY='dev'
|
||||||
@ -48,6 +48,8 @@ def create_app(test_config=None, instance_path=None):
|
|||||||
|
|
||||||
if instance_path is not None:
|
if instance_path is not None:
|
||||||
app.instance_path = instance_path
|
app.instance_path = instance_path
|
||||||
|
elif app.config.get("INSTANCE_PATH"):
|
||||||
|
app.instance_path = app.config["INSTANCE_PATH"]
|
||||||
|
|
||||||
try:
|
try:
|
||||||
import os
|
import os
|
||||||
@ -69,13 +71,23 @@ def create_app(test_config=None, instance_path=None):
|
|||||||
app.register_blueprint(history.bp)
|
app.register_blueprint(history.bp)
|
||||||
app.register_blueprint(ports.bp)
|
app.register_blueprint(ports.bp)
|
||||||
|
|
||||||
logging.basicConfig(filename='brecaltest.log', level=logging.DEBUG, format='%(asctime)s | %(name)s | %(levelname)s | %(message)s')
|
log_level = getattr(logging, app.config.get("LOG_LEVEL", "DEBUG"))
|
||||||
local_db.initPool(os.path.dirname(app.instance_path))
|
log_kwargs = {"format": "%(asctime)s | %(name)s | %(levelname)s | %(message)s"}
|
||||||
|
if app.config.get("LOG_TO_STDERR"):
|
||||||
|
log_kwargs["stream"] = sys.stderr
|
||||||
|
else:
|
||||||
|
log_kwargs["filename"] = app.config.get("LOG_FILE", "brecaltest.log")
|
||||||
|
logging.basicConfig(level=log_level, **log_kwargs)
|
||||||
|
|
||||||
|
if app.config.get("SECRET_KEY"):
|
||||||
|
os.environ["SECRET_KEY"] = app.config["SECRET_KEY"]
|
||||||
|
|
||||||
|
local_db.initPool(os.path.dirname(app.instance_path), config=app.config)
|
||||||
logging.info('App started')
|
logging.info('App started')
|
||||||
|
|
||||||
# Setup Routine jobs (e.g., reevaluation of shipcalls)
|
# Setup Routine jobs (e.g., reevaluation of shipcalls)
|
||||||
setup_schedule(update_shipcalls_interval_in_minutes=60)
|
setup_schedule(update_shipcalls_interval_in_minutes=app.config.get("SCHEDULE_UPDATE_SHIPCALLS_MINUTES", 60))
|
||||||
run_schedule_permanently_in_background(latency=30)
|
run_schedule_permanently_in_background(latency=app.config.get("SCHEDULE_BACKGROUND_LATENCY_SECONDS", 30))
|
||||||
logging.info('Routine Jobs are defined.')
|
logging.info('Routine Jobs are defined.')
|
||||||
|
|
||||||
return app
|
return app
|
||||||
|
|||||||
@ -8,6 +8,7 @@ import sys
|
|||||||
from BreCal.schemas import defs
|
from BreCal.schemas import defs
|
||||||
|
|
||||||
config_path = None
|
config_path = None
|
||||||
|
secure_dir = None
|
||||||
_connection_pool = None
|
_connection_pool = None
|
||||||
|
|
||||||
|
|
||||||
@ -23,17 +24,26 @@ def _build_pool_config(connection_data, pool_name, pool_size):
|
|||||||
return pool_config
|
return pool_config
|
||||||
|
|
||||||
|
|
||||||
def initPool(instancePath, connection_filename="connection_data_prod.json",
|
def initPool(instancePath, config=None, connection_filename="connection_data_prod.json",
|
||||||
pool_name="brecal_pool", pool_size=10):
|
credentials_file="email_credentials_test.json", pool_name="brecal_pool", pool_size=10,
|
||||||
|
secure_directory=None):
|
||||||
"""
|
"""
|
||||||
Initialize the MySQL connection pool and load email credentials.
|
Initialize the MySQL connection pool and load email credentials.
|
||||||
"""
|
"""
|
||||||
global config_path, _connection_pool
|
global config_path, secure_dir, _connection_pool
|
||||||
try:
|
try:
|
||||||
|
if config:
|
||||||
|
connection_filename = config.get("DB_CONNECTION_FILE", connection_filename)
|
||||||
|
credentials_file = config.get("EMAIL_CREDENTIALS_FILE", credentials_file)
|
||||||
|
pool_name = config.get("DB_POOL_NAME", pool_name)
|
||||||
|
pool_size = config.get("DB_POOL_SIZE", pool_size)
|
||||||
|
secure_directory = config.get("SECURE_DIR", secure_directory)
|
||||||
|
|
||||||
|
if secure_dir is None:
|
||||||
|
secure_dir = secure_directory if secure_directory else os.path.join(instancePath, '../../../secure')
|
||||||
|
|
||||||
if config_path is None:
|
if config_path is None:
|
||||||
config_path = os.path.join(instancePath, f'../../../secure/{connection_filename}')
|
config_path = os.path.join(secure_dir, connection_filename)
|
||||||
|
|
||||||
# config_path = 'C:\\temp\\connection_data_test.json'
|
|
||||||
|
|
||||||
print(config_path)
|
print(config_path)
|
||||||
if not os.path.exists(config_path):
|
if not os.path.exists(config_path):
|
||||||
@ -54,10 +64,7 @@ def initPool(instancePath, connection_filename="connection_data_prod.json",
|
|||||||
finally:
|
finally:
|
||||||
conn_from_pool.close()
|
conn_from_pool.close()
|
||||||
|
|
||||||
credentials_file = "email_credentials_test.json"
|
credentials_path = os.path.join(secure_dir, credentials_file)
|
||||||
credentials_path = os.path.join(instancePath, f'../../../secure/{credentials_file}')
|
|
||||||
|
|
||||||
# credentials_path = "E:/temp/email_credentials_devel.json"
|
|
||||||
|
|
||||||
if not os.path.exists(credentials_path):
|
if not os.path.exists(credentials_path):
|
||||||
print('cannot find ' + os.path.abspath(credentials_path))
|
print('cannot find ' + os.path.abspath(credentials_path))
|
||||||
|
|||||||
40
src/server/config.py.sample
Normal file
40
src/server/config.py.sample
Normal file
@ -0,0 +1,40 @@
|
|||||||
|
"""
|
||||||
|
Sample configuration for the Flask instance.
|
||||||
|
|
||||||
|
Copy this file to `src/server/instance/config.py` (the instance folder is git-ignored)
|
||||||
|
and adjust the values for each deployment target.
|
||||||
|
"""
|
||||||
|
|
||||||
|
# Flask
|
||||||
|
SECRET_KEY = "change-me"
|
||||||
|
|
||||||
|
# Python path adjustments used by the WSGI entrypoint (flaskapp.wsgi)
|
||||||
|
APP_ROOT = "/var/www/brecal/src/server"
|
||||||
|
SITE_PACKAGES = "/var/www/venv/lib/python3.12/site-packages/"
|
||||||
|
|
||||||
|
# Paths to environment-specific secrets and instance data
|
||||||
|
SECURE_DIR = "/var/www/secure" # directory that holds connection/email JSON files
|
||||||
|
INSTANCE_PATH = "/var/www/brecal/src/server/instance"
|
||||||
|
|
||||||
|
# Logging
|
||||||
|
LOG_FILE = "brecal.log"
|
||||||
|
LOG_LEVEL = "INFO" # e.g. DEBUG, INFO, WARNING
|
||||||
|
LOG_TO_STDERR = False
|
||||||
|
|
||||||
|
# Database pool setup
|
||||||
|
DB_CONNECTION_FILE = "connection_data_prod.json"
|
||||||
|
DB_POOL_NAME = "brecal_pool"
|
||||||
|
DB_POOL_SIZE = 10
|
||||||
|
|
||||||
|
# Email + notifications
|
||||||
|
EMAIL_CREDENTIALS_FILE = "email_credentials_prod.json"
|
||||||
|
EMAIL_URL_TEMPLATE = "https://brecal.example.com/shipcalls/" # base URL for links in emails
|
||||||
|
SMTP_DEBUG_LEVEL = 0 # 0 = quiet, 1 = verbose
|
||||||
|
|
||||||
|
# Scheduler cadence
|
||||||
|
SCHEDULE_UPDATE_SHIPCALLS_MINUTES = 60
|
||||||
|
SCHEDULE_BACKGROUND_LATENCY_SECONDS = 30
|
||||||
|
|
||||||
|
# Notification cleanup / escalation windows
|
||||||
|
NOTIFICATION_COOLDOWN_MINS = 10
|
||||||
|
NOTIFICATION_MAX_AGE_DAYS = 3
|
||||||
@ -1,20 +1,29 @@
|
|||||||
import os
|
|
||||||
import sys
|
|
||||||
import logging
|
import logging
|
||||||
|
import os
|
||||||
|
import runpy
|
||||||
|
import sys
|
||||||
|
from pathlib import Path
|
||||||
|
|
||||||
sys.path.insert(0, '/var/www/brecal_test/src/server')
|
BASE_DIR = Path(__file__).resolve().parent
|
||||||
sys.path.insert(0, '/var/www/venv/lib/python3.12/site-packages/')
|
INSTANCE_DIR = BASE_DIR / "instance"
|
||||||
|
CONFIG_PATH = INSTANCE_DIR / "config.py"
|
||||||
|
|
||||||
import schedule
|
config = {}
|
||||||
|
if CONFIG_PATH.exists():
|
||||||
|
config = runpy.run_path(str(CONFIG_PATH))
|
||||||
|
|
||||||
# set the key
|
app_root = config.get("APP_ROOT", str(BASE_DIR))
|
||||||
os.environ['SECRET_KEY'] = 'zdiTz8P3jXOc7jztIQAoelK4zztyuCpJ'
|
site_packages = config.get("SITE_PACKAGES")
|
||||||
|
|
||||||
# Set up logging
|
sys.path.insert(0, app_root)
|
||||||
logging.basicConfig(stream=sys.stderr, level=logging.DEBUG)
|
if site_packages:
|
||||||
|
sys.path.insert(0, site_packages)
|
||||||
|
|
||||||
# Set up Scheduled Jobs
|
if config.get("SECRET_KEY"):
|
||||||
|
os.environ["SECRET_KEY"] = config["SECRET_KEY"]
|
||||||
|
|
||||||
|
log_kwargs = {"level": getattr(logging, config.get("LOG_LEVEL", "DEBUG")), "stream": sys.stderr}
|
||||||
|
logging.basicConfig(**log_kwargs)
|
||||||
|
|
||||||
# Import and run the Flask app
|
|
||||||
from BreCal import create_app
|
from BreCal import create_app
|
||||||
application = create_app()
|
application = create_app(instance_path=config.get("INSTANCE_PATH"))
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user