from pathlib import Path from flask import Flask, flash, render_template from werkzeug.exceptions import RequestEntityTooLarge from app.config import Config from app.routes import main_blueprint def _format_size_limit(size_limit_bytes: int) -> str: """Render the upload limit in a friendly unit for error messages.""" if size_limit_bytes >= 1024 * 1024: return f"{size_limit_bytes / (1024 * 1024):.0f} MB" if size_limit_bytes >= 1024: return f"{size_limit_bytes / 1024:.0f} KB" return f"{size_limit_bytes} bytes" def create_app(config_class: type[Config] = Config) -> Flask: """Application factory used by Flask and Gunicorn.""" app = Flask(__name__, instance_relative_config=True) app.config.from_object(config_class) output_dir = Path(app.config["OUTPUT_DIRECTORY"]) if not output_dir.is_absolute(): output_dir = Path(app.instance_path) / output_dir app.config["OUTPUT_DIRECTORY"] = output_dir output_dir.mkdir(parents=True, exist_ok=True) app.register_blueprint(main_blueprint) @app.errorhandler(RequestEntityTooLarge) def handle_file_too_large(_error): size_limit_bytes = int(app.config["MAX_CONTENT_LENGTH"]) flash( f"The uploaded file is too large. Maximum allowed size is {_format_size_limit(size_limit_bytes)}.", "danger", ) return render_template("index.html"), 413 return app