"""Flask web application main script""" import os import secrets from typing import Optional from typing import Type, List from pathlib import Path from dotenv import load_dotenv from flask import Flask from . import exts from .routes import Routes from . import pages from . import admin from . import errors from . import db routes: List[Type[Routes]] = [ pages.RoutePages, admin.RouteAdmin, 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, ) # Load sample configuation if app.debug: load_dotenv( Path(__file__).parent.parent / '.env' ) # Get the token from environment # or generate it using secrets app.config['SECRET_KEY'] = os.getenv( 'SECRET_KEY', secrets.token_hex(32), ) # Configurate MySQL database db_name = os.getenv('MYSQL_DATABASE', '${REPO_NAME_SNAKE}') app.config.update({ 'MYSQL_DATABASE_HOST': os.getenv('MYSQL_HOST', 'localhost'), 'MYSQL_DATABASE_PORT': parseint(os.getenv('MYSQL_PORT'), 3306), 'MYSQL_DATABASE_USER': os.getenv('MYSQL_USER', 'root'), 'MYSQL_DATABASE_PASSWORD': os.getenv('MYSQL_PASSWORD', ''), }) # Load extensions for ext in exts.exts: ext.init_app(app) db.create_db(db_name) with app.app_context(): db.init_db() # 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