{"id":203,"library":"Flask","title":"Flask","description":"Lightweight WSGI web framework. Current version is 3.1.3 (Feb 2026). Flask 3.0 (Sep 2023) removed a large set of APIs that had been deprecated since 2.x — before_first_request, FLASK_ENV, JSON config keys, and custom json_encoder/decoder. LLMs still generate these removed patterns.","status":"active","version":"3.1.3","language":"python","source_language":"en","source_url":"https://flask.palletsprojects.com/en/stable/changes/","tags":["web","wsgi","framework","http","jinja2","werkzeug"],"install":[{"cmd":"pip install Flask","lang":"bash","label":"Core"},{"cmd":"pip install \"Flask[async]\"","lang":"bash","label":"With async view support (adds asgiref)"},{"cmd":"pip install \"Flask[dotenv]\"","lang":"bash","label":"With .env file support (adds python-dotenv)"}],"dependencies":[{"reason":"WSGI utilities. Required. Version pinned by Flask.","package":"Werkzeug>=3.1","optional":false},{"reason":"Template engine. Required.","package":"Jinja2>=3.1.2","optional":false},{"reason":"Required for async views. Only installed with Flask[async].","package":"asgiref>=3.2","optional":true},{"reason":"Loads .env files for flask run. Only installed with Flask[dotenv].","package":"python-dotenv","optional":true}],"imports":[{"note":"FLASK_ENV environment variable and app.env property were removed in Flask 3.0. Use FLASK_DEBUG=1 for debug mode instead.","wrong":"from flask import Flask\napp = Flask(__name__)\napp.config['FLASK_ENV'] = 'development'  # FLASK_ENV removed in 3.0","symbol":"Flask","correct":"from flask import Flask\napp = Flask(__name__)"},{"note":"@app.before_first_request and @bp.before_app_first_request removed in 3.0. Use app context at startup or initialize in app factory.","wrong":"@app.before_first_request\ndef initialize():\n    init_db()  # decorator removed in Flask 3.0","symbol":"before_first_request","correct":"# Use app context or lifespan pattern\nwith app.app_context():\n    init_db()\n\n# Or with app factory + teardown:\n@app.before_request\ndef check_initialized():\n    ..."}],"quickstart":{"code":"from flask import Flask, jsonify, request\n\napp = Flask(__name__)\n\n@app.get('/')\ndef index():\n    return jsonify({'status': 'ok'})\n\n@app.post('/items')\ndef create_item():\n    data = request.get_json()\n    return jsonify(data), 201\n\n@app.errorhandler(404)\ndef not_found(e):\n    return jsonify({'error': 'not found'}), 404\n\n# Run: flask --app app run --debug","lang":"python","description":"Minimal Flask 3.x app with JSON responses and error handler."},"warnings":[{"fix":"Run initialization code in the app factory, in a CLI command, or using with app.app_context(): at startup. For teardown-based patterns use @app.teardown_appcontext.","message":"@app.before_first_request and @bp.before_app_first_request decorators removed in Flask 3.0. Extremely common in older tutorials and LLM-generated code.","severity":"breaking","affected_versions":">= 3.0"},{"fix":"Use FLASK_DEBUG=1 or flask run --debug for debug mode. Set app.config['TESTING'] = True for test mode.","message":"FLASK_ENV environment variable, ENV config key, and app.env property removed in Flask 3.0. Using FLASK_ENV=development no longer enables debug mode.","severity":"breaking","affected_versions":">= 3.0"},{"fix":"Use app.json.sort_keys = False, app.json.mimetype = 'application/json', app.json.ensure_ascii = False on the app.json provider instead.","message":"JSON config keys removed in Flask 3.0: JSON_AS_ASCII, JSON_SORT_KEYS, JSONIFY_MIMETYPE, JSONIFY_PRETTYPRINT_REGULAR. LLMs still generate these in config blocks.","severity":"breaking","affected_versions":">= 3.0"},{"fix":"Subclass flask.json.provider.DefaultJSONProvider and assign: app.json_provider_class = MyProvider, then app = Flask(__name__).","message":"app.json_encoder and app.json_decoder class attributes removed in Flask 3.0. Custom JSON serialization using these was a common pattern.","severity":"breaking","affected_versions":">= 3.0"},{"fix":"Update send_file calls: send_file(path, download_name='file.csv', max_age=3600, etag=True).","message":"send_file() parameter names changed in Flask 2.0 and finalised in 3.0: attachment_filename → download_name, cache_timeout → max_age, add_etags → etag. Old names raise TypeError.","severity":"breaking","affected_versions":">= 2.0"},{"fix":"from markupsafe import Markup","message":"flask.Markup imported from flask is deprecated. Markup was moved to MarkupSafe.","severity":"deprecated","affected_versions":">= 2.0"},{"fix":"flask --app mymodule:app run  or  export FLASK_APP=mymodule:app","message":"flask run requires the app to be discoverable. By default looks for app.py or wsgi.py with an app variable. Use FLASK_APP env var or --app flag for other module names.","severity":"gotcha","affected_versions":"all"},{"fix":"pip install 'Flask[async]' to enable async view support.","message":"Async views require Flask[async] (installs asgiref). Defining async def routes without this raises RuntimeError or silently runs synchronously depending on version.","severity":"gotcha","affected_versions":">= 2.0"}],"env_vars":null,"last_verified":"2026-05-12T10:08:50.730Z","next_check":"2026-09-25T00:00:00.000Z","problems":[{"fix":"Use 'from flask_wtf import FlaskForm' instead of 'from flask import FlaskForm'.","cause":"The 'FlaskForm' class is part of the 'flask_wtf' extension, not the core 'flask' module.","error":"ImportError: cannot import name 'FlaskForm' from 'flask'"},{"fix":"Downgrade Werkzeug to a version before 3.0.0 by adding 'Werkzeug==2.3.7' to your 'requirements.txt' file and reinstalling dependencies.","cause":"The 'url_quote' function was removed in Werkzeug 3.0.0.","error":"ImportError: cannot import name 'url_quote' from 'werkzeug.urls'"},{"fix":"Import 'escape' from 'markupsafe' instead: 'from markupsafe import escape'.","cause":"The 'escape' function was removed from Jinja2 in version 3.1.0.","error":"ImportError: cannot import name 'escape' from 'jinja2'"},{"fix":"Ensure that your project structure does not have circular imports and that 'flask' is installed correctly.","cause":"This error often occurs due to a circular import or incorrect project structure.","error":"ImportError: cannot import name 'Flask' from 'flask'"},{"fix":"Use Python's built-in 'json' module instead: 'import json'.","cause":"The 'json' module was removed from Flask in version 3.0.0.","error":"ImportError: cannot import name 'json' from 'flask'"}],"ecosystem":"pypi","meta_description":null,"install_score":100,"install_tag":"verified","quickstart_score":80,"quickstart_tag":"verified","pypi_latest":null,"install_checks":{"last_tested":"2026-05-12","tag":"verified","tag_description":"installs cleanly on critical runtimes, fast import, recently tested","results":[{"runtime":"python:3.10-alpine","python_version":"3.10","os_libc":"alpine (musl)","variant":"async","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":0.43,"mem_mb":11.7,"disk_size":"22.9M"},{"runtime":"python:3.10-alpine","python_version":"3.10","os_libc":"alpine (musl)","variant":"dotenv","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":0.43,"mem_mb":11.7,"disk_size":"22.5M"},{"runtime":"python:3.10-alpine","python_version":"3.10","os_libc":"alpine (musl)","variant":"default","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":0.45,"mem_mb":11.7,"disk_size":"22.3M"},{"runtime":"python:3.10-slim","python_version":"3.10","os_libc":"slim (glibc)","variant":"async","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":0.33,"mem_mb":11.7,"disk_size":"23M"},{"runtime":"python:3.10-slim","python_version":"3.10","os_libc":"slim (glibc)","variant":"dotenv","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":0.33,"mem_mb":11.7,"disk_size":"23M"},{"runtime":"python:3.10-slim","python_version":"3.10","os_libc":"slim (glibc)","variant":"default","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":0.34,"mem_mb":11.7,"disk_size":"23M"},{"runtime":"python:3.11-alpine","python_version":"3.11","os_libc":"alpine (musl)","variant":"async","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":0.6,"mem_mb":13.2,"disk_size":"25.3M"},{"runtime":"python:3.11-alpine","python_version":"3.11","os_libc":"alpine (musl)","variant":"dotenv","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":0.59,"mem_mb":13.2,"disk_size":"25.2M"},{"runtime":"python:3.11-alpine","python_version":"3.11","os_libc":"alpine (musl)","variant":"default","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":0.6,"mem_mb":13.2,"disk_size":"25.0M"},{"runtime":"python:3.11-slim","python_version":"3.11","os_libc":"slim (glibc)","variant":"async","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":0.49,"mem_mb":13.2,"disk_size":"26M"},{"runtime":"python:3.11-slim","python_version":"3.11","os_libc":"slim (glibc)","variant":"dotenv","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":0.52,"mem_mb":13.2,"disk_size":"26M"},{"runtime":"python:3.11-slim","python_version":"3.11","os_libc":"slim (glibc)","variant":"default","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":0.49,"mem_mb":13.2,"disk_size":"26M"},{"runtime":"python:3.12-alpine","python_version":"3.12","os_libc":"alpine (musl)","variant":"async","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":0.5,"mem_mb":12.9,"disk_size":"16.9M"},{"runtime":"python:3.12-alpine","python_version":"3.12","os_libc":"alpine (musl)","variant":"dotenv","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":0.52,"mem_mb":12.9,"disk_size":"16.9M"},{"runtime":"python:3.12-alpine","python_version":"3.12","os_libc":"alpine (musl)","variant":"default","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":0.51,"mem_mb":12.9,"disk_size":"16.7M"},{"runtime":"python:3.12-slim","python_version":"3.12","os_libc":"slim (glibc)","variant":"async","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":0.53,"mem_mb":12.9,"disk_size":"17M"},{"runtime":"python:3.12-slim","python_version":"3.12","os_libc":"slim (glibc)","variant":"dotenv","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":0.51,"mem_mb":12.9,"disk_size":"17M"},{"runtime":"python:3.12-slim","python_version":"3.12","os_libc":"slim (glibc)","variant":"default","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":0.51,"mem_mb":12.9,"disk_size":"17M"},{"runtime":"python:3.13-alpine","python_version":"3.13","os_libc":"alpine (musl)","variant":"async","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":0.48,"mem_mb":13.9,"disk_size":"16.6M"},{"runtime":"python:3.13-alpine","python_version":"3.13","os_libc":"alpine (musl)","variant":"dotenv","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":0.48,"mem_mb":13.9,"disk_size":"16.5M"},{"runtime":"python:3.13-alpine","python_version":"3.13","os_libc":"alpine (musl)","variant":"default","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":0.49,"mem_mb":13.9,"disk_size":"16.3M"},{"runtime":"python:3.13-slim","python_version":"3.13","os_libc":"slim (glibc)","variant":"async","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":0.52,"mem_mb":13.8,"disk_size":"17M"},{"runtime":"python:3.13-slim","python_version":"3.13","os_libc":"slim (glibc)","variant":"dotenv","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":0.48,"mem_mb":13.8,"disk_size":"17M"},{"runtime":"python:3.13-slim","python_version":"3.13","os_libc":"slim (glibc)","variant":"default","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":0.48,"mem_mb":13.8,"disk_size":"17M"},{"runtime":"python:3.9-alpine","python_version":"3.9","os_libc":"alpine (musl)","variant":"async","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":0.39,"mem_mb":12.1,"disk_size":"22.6M"},{"runtime":"python:3.9-alpine","python_version":"3.9","os_libc":"alpine (musl)","variant":"dotenv","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":0.38,"mem_mb":12.1,"disk_size":"22.3M"},{"runtime":"python:3.9-alpine","python_version":"3.9","os_libc":"alpine (musl)","variant":"default","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":0.39,"mem_mb":12.1,"disk_size":"22.1M"},{"runtime":"python:3.9-slim","python_version":"3.9","os_libc":"slim (glibc)","variant":"async","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":0.35,"mem_mb":12.1,"disk_size":"23M"},{"runtime":"python:3.9-slim","python_version":"3.9","os_libc":"slim (glibc)","variant":"dotenv","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":0.34,"mem_mb":12.1,"disk_size":"23M"},{"runtime":"python:3.9-slim","python_version":"3.9","os_libc":"slim (glibc)","variant":"default","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":0.38,"mem_mb":12.1,"disk_size":"23M"}]},"quickstart_checks":{"last_tested":"2026-04-23","tag":"verified","tag_description":"quickstart runs on critical runtimes, recently tested","results":[{"runtime":"python:3.10-alpine","exit_code":0},{"runtime":"python:3.10-slim","exit_code":0},{"runtime":"python:3.11-alpine","exit_code":0},{"runtime":"python:3.11-slim","exit_code":0},{"runtime":"python:3.12-alpine","exit_code":0},{"runtime":"python:3.12-slim","exit_code":0},{"runtime":"python:3.13-alpine","exit_code":0},{"runtime":"python:3.13-slim","exit_code":0},{"runtime":"python:3.9-alpine","exit_code":0},{"runtime":"python:3.9-slim","exit_code":0}]}}