"""Flask web application main script""" import os import secrets from typing import Optional from typing import Type, List from flask import Flask from flaskext.mysql import MySQL # type: ignore from .routes import Routes from . import pages from . import errors from . import db routes: List[Type[Routes]] = [ pages.RoutePages, errors.RouteErrors, ] def create_app() -> Flask: """Flask app factory function""" # Create an app object app = Flask( __name__, static_folder='../static', template_folder='../templates', instance_relative_config=True, ) # Get the token from environment # or generate it using secrets app.config['SECRET_KEY'] = os.getenv( 'SECRET_KEY', secrets.token_hex(32), ) # Setup MySQL database app.config.update({ 'MYSQL_DATABASE_HOST': os.getenv('DB_HOST', 'localhost'), 'MYSQL_DATABASE_PORT': parseint(os.getenv('DB_PORT'), 3306), 'MYSQL_DATABASE_USER': os.getenv('DB_USER', 'root'), 'MYSQL_DATABASE_PASSWORD': os.getenv('DB_PASSWORD', ''), 'MYSQL_DATABASE_DB': os.getenv('DB_DATABASE', '${REPO_NAME_SNAKE}'), }) sql = MySQL(app) db.set_db(sql) # Create instance/ directory try: os.makedirs(app.instance_path) except OSError: pass # Add all routes for r in routes: r(app).add_routes() return app def parseint( value: Optional[str], default: int) -> Optional[int]: """Parses integer from the string, returns default value on error Args: value (Optional[str]): String or None default (int): Default value Returns: Integer or None """ try: return int(value or default) except ValueError: return default