Fixing ImportError: cannot import name 'Markup' from 'jinja2'
This error occurs when trying to import the Markup
class from Jinja2, which has been deprecated and moved to a different package. The issue commonly affects Flask applications using older versions that haven't been updated to use the new import location.
Problem Overview
The error typically appears as:
ImportError: cannot import name 'Markup' from 'jinja2' (/path/to/jinja2/__init__.py)
This occurs because:
- Starting with Jinja2 version 3.0.1, the
Markup
class was moved to themarkupsafe
package - Older versions of Flask and related libraries still try to import
Markup
directly fromjinja2
- The error breaks dependency chains in Flask applications, preventing them from starting
Root Cause
Jinja2 version 3.0.1 introduced a breaking change where the Markup
class was deprecated and removed from the main package. According to the Jinja2 changelog:
Fixed calling deprecated jinja2.Markup without an argument. Use markupsafe.Markup instead.
Solutions
Solution 1: Update Package Imports (Recommended)
The most straightforward fix is to import Markup
from markupsafe
instead of jinja2
:
# Old import (causing the error)
from jinja2 import Markup
# New import (working solution)
from markupsafe import Markup
TIP
If you're modifying third-party code (like Flask extensions), be aware that this change might be overwritten by package updates. Check if there's an updated version of the package that already includes this fix.
Solution 2: Upgrade Flask and Jinja2
Update your Flask installation to a version that handles the Jinja2 3.x changes properly:
pip uninstall Flask Jinja2
pip install Flask>=2.0.0 Jinja2
This will install compatible versions:
click==8.0.4
Flask==2.0.3
itsdangerous==2.1.2
Jinja2==3.1.1
MarkupSafe==2.1.1
Werkzeug==2.0.3
Solution 3: Install Specific Version Combinations
If you cannot update Flask, try compatible version combinations:
Flask==1.1.2
Jinja2==2.11.2
MarkupSafe==1.1.1
Werkzeug==1.0.1
Install with:
pip install Flask==1.1.2 Jinja2==2.11.2 MarkupSafe==1.1.1 Werkzeug==1.0.1
Solution 4: Platform-Specific Installation
For deployment scenarios (like with Zappa), you might need platform-specific installation:
pip install --platform=manylinux2014_x86_64 --only-binary=:all: --target venv/lib/python3.10/site-packages flask markupsafe jinja2==3.0.3 --force-reinstall --upgrade
Common Scenarios
When Using Flask Extensions
Some Flask extensions (like Flask-JSGlue) may need manual patching. Check if the extension has a pending pull request for the Markup import fix.
Virtual Environment Issues
If you're using virtual environments, ensure you're not mixing system-wide and virtual environment packages:
# Remove the virtual environment and create a fresh one
rm -rf venv
python -m venv venv
source venv/bin/activate
pip install -r requirements.txt
Best Practices
- Pin Your Dependencies: Always specify exact versions in your
requirements.txt
to avoid unexpected breaking changes - Regular Updates: Periodically update your dependencies to receive security patches and bug fixes
- Test After Updates: Always test your application after updating packages to catch breaking changes early
Example requirements.txt
Here's an example of a stable configuration that avoids the Markup import issue:
Flask==2.0.3
Jinja2==3.1.2
MarkupSafe==2.1.1
Werkzeug==2.0.3
flasgger==0.9.5
Flask-RESTful==0.3.9
flask-cors==3.0.10
WARNING
Avoid using extremely old versions of Flask (like 1.0.2) with newer versions of Jinja2, as they are not compatible due to the Markup import change.
By following these solutions, you should be able to resolve the ImportError and get your Flask application running smoothly again.