"""Application factory; package imports do not initialize storage or networking.""" def create_app(config=None): from collections import defaultdict import logging from pathlib import Path from threading import Lock from flask import Flask from .config import ROOT_DIR, default_config from . import customer_service, db, file_service, hooks, visitor_service from .routes import register_routes from .routes.speech import MemoryAudioRequest app = Flask(__name__, template_folder=str(ROOT_DIR/'templates'), static_folder=str(ROOT_DIR/'static')) app.request_class = MemoryAudioRequest app.config.update(default_config()) if config: app.config.update(config) app.extensions['human_typing'] = {} app.extensions['rate_hits'] = defaultdict(list) app.extensions['customer_login_attempts'] = {} app.extensions['customer_login_lock'] = Lock() app.before_request(hooks.rate_limit) app.before_request(visitor_service.attach_visitor) app.before_request(customer_service.attach_customer) app.after_request(hooks.no_cache_html) app.teardown_appcontext(db.close_connections) register_routes(app) if app.config['INITIALIZE_RUNTIME']: if not app.testing: from flask.logging import default_handler log_directory = Path(app.config['LOG_DIR']) log_directory.mkdir(parents=True, exist_ok=True) log_path = str((log_directory/'app.log').resolve()) app.logger = logging.getLogger('logistics_chat.' + log_path) app.logger.setLevel(logging.INFO) if default_handler not in app.logger.handlers: app.logger.addHandler(default_handler) if not any(getattr(handler, 'baseFilename', None) == log_path for handler in app.logger.handlers): handler = logging.FileHandler(log_path, encoding='utf-8') handler.setFormatter(logging.Formatter('%(asctime)s [%(levelname)s] %(message)s')) app.logger.addHandler(handler) with app.app_context(): db.init_db() db.backup_db() file_service.cleanup_uploads() return app