factory + init_appconstruct at module scope, bind inside create_app() with init_app(app) — the pattern the whole ecosystem expects
SECRET_KEY is load-bearingsessions, Flask-Login, CSRF, Flask-WTF, Flask-Session id, and OAuth state all depend on it
pip name ≠ import namepip install Flask-Login → import flask_login; Flask-Cors keeps the -Cors spelling
JWT_SECRET_KEY ≠ SECRET_KEYFlask-JWT-Extended uses its own key (falls back to SECRET_KEY if unset)
Flask-SQLAlchemy 3.1 = SA 2.0use select()+db.session.execute(); Model.query is legacy
Limiter needs shared storageset storage_uri=redis:// or limits are per-worker and reset on restart
SocketIO worker must match gunicornasync_mode (threading/gevent) has to line up with the gunicorn worker class; eventlet is EOL
Flask-Admin is open by defaultoverride is_accessible() before you deploy an admin
Flask-Security-Too → Flask-Securitymerged back into pallets-eco; both PyPI names ship the same 5.8.x release
Flask-Session filesystem is deprecateduse cachelib (or redis/sqlalchemy) since 0.7.0
Connexion 3 is ASGIFlaskApp/AsyncApp + add_api(); serve with uvicorn, not flask run
don't block the requestemail/long jobs → Flask-Executor / APScheduler / Celery, not inline in the view