Disclaimer: You can architect beautiful apps in apps, its just easy todo it wrong.
GLOBALS: Flask has a lot of globals (from flask import g, request, current_user, etc.) A better web handler function looks like this handle(request) -> response. Any other web framework that I know does it like this. Much better. Flask promotes touching the 'request' object everywhere. Example: https://github.com/lepture/flask-wtf/blob/master/flask_wtf/f.... Flask is not functional, its inherently statefull with globals.
MIDDLEWARE: Flask promotes writing middleware as decorators functions, while it looks nice, it not really useable anywhere else, and its not really a standard. At least you can still use WSGI middleware.
BLUEPRINT are nice, but have issues: When you create a blueprint, for a sub app, you cant set error handlers. They only work on app level. Also (small issue) You cant add blueprint specific middleware.
Better way to create 'sub apps': Use a new WSGI App. Or use a sitemap where you bind functions to paths.
SITEMAP @route has disadvantages For big apps, its nice to have a single routes.py file where you can see all urls the app supports, and which methods to handle those. The @route is nice to use initially, but imho for big apps it becomes messy. Also it promotes circular imports:
view.py:
from init import blueprint #circular import!
blueprint.route('/test/')
def f(): pass
init.py:
blueprint = new Blueprint
from . import view
assert view # ensure the handlers are initiallized