import os from utils.debug_utils import DebugUtils # This should match exactly the name of the app you specified APP_NAME = "MY_APP_NAME_HERE" # default mode is "dev" if environment variable doesn't have an assigned value DEFAULT_MODE = "dev" ENV = os.environ.get('ENV', DEFAULT_MODE).lower() DEBUG_MODE = ENV != 'prod' URL_PREFIX = f"/{APP_NAME}" if not DEBUG_MODE else "" class AppDBConfig: def __init__(self, bind_key_name, debug_env_var_key, prod_env_var_key, force_prod_con_str=None, force_debug_con_str=None): self.bind_key_name = bind_key_name self.debug_env_var_key = debug_env_var_key self.prod_env_var_key = prod_env_var_key self.force_prod_con_str = force_prod_con_str self.force_debug_con_str = force_debug_con_str # Factory Methods @classmethod def construct_with_sqllite_debug_db(cls, bind_key_name, sqllite_path, prod_env_var_key, force_prod_con_str=None): return AppDBConfig(bind_key_name, None, prod_env_var_key, force_prod_con_str, force_debug_con_str="sqlite:///database{0}.db".format(sqllite_path)) # End Factory Methods. def get_debug_con_str(self): return self._get_con_str(self.debug_env_var_key, self.force_debug_con_str) # If you have created a database for this app, the connection string will be automatically # accessible through the DATABASE_URL environment variable. def get_prod_con_str(self): return self._get_con_str(self.prod_env_var_key, self.force_prod_con_str) # Private Methods def _print_warning(self, msg, env_key): DebugUtils.print_warning(msg, tag=f"{env_key} - {self.bind_key_name}", tag_wrapper_pair="[]") def _get_con_str(self, env_key, force_value): if force_value: url = force_value if url.startswith("sqlite"): self._print_warning(f"You are using an sqlite db, you will not be able to perform " f"migrations on this db!", env_key) else: # Print warning if not using a hardcoded sqlite connection string self._print_warning(f"Hardcoded connection string! Assign it to an environment variable!", env_key) else: url = os.environ.get(env_key) if url is None: self._print_warning("Could not connect to the given database URL!", env_key) elif url.startswith("postgres://"): # For PostgreSQL databases, the conn string needs to start with "postgresql" url = url.replace("postgres://", "postgresql://", 1) return url # ============= DB Configs ============= # ===== DB Bindings ===== # Bindings are referenced by "models" to assign the model to the correct db FIRST_DB_BIND_NAME = "first_db" # Add more bindings here # ... # ===== End DB Bindings ===== PROD_BINDINGS = dict() DEV_BINDINGS = dict() db_configs = [ # Add more DBs here! AppDBConfig(bind_key_name=FIRST_DB_BIND_NAME, debug_env_var_key="FIRST_DB_DEBUG_CON_STR", prod_env_var_key="FIRST_DB_CON_STR") ] for db_config in db_configs: PROD_BINDINGS[db_config.bind_key_name] = db_config.get_prod_con_str() DEV_BINDINGS[db_config.bind_key_name] = db_config.get_debug_con_str() # ============= End DB Configs ============= # Get the static URL of the app (to get around the production path issue) def get_static_url(): if DEBUG_MODE: return '/static' return f'/{APP_NAME}/static' # Get the app configuration based on the ENV environment variable (default is prod) def get_app_config(): if DEBUG_MODE: return DevelopmentConfig() return ProductionConfig() class Config(object): DEBUG = False TESTING = False SQLALCHEMY_TRACK_MODIFICATIONS = False SQLALCHEMY_BINDS = {} # Flask App settings for production environment class ProductionConfig(Config): PREFERRED_URL_SCHEME = 'https' DEBUG = False APPLICATION_ROOT = f"/{APP_NAME}" # Source: https://flask-sqlalchemy.palletsprojects.com/en/2.x/binds/ SQLALCHEMY_BINDS = PROD_BINDINGS # Flask App settings for local development environment class DevelopmentConfig(Config): DEBUG = True SQLALCHEMY_BINDS = DEV_BINDINGS