Skip to content

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 the markupsafe package
  • Older versions of Flask and related libraries still try to import Markup directly from jinja2
  • 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

The most straightforward fix is to import Markup from markupsafe instead of jinja2:

python
# 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:

bash
pip uninstall Flask Jinja2
pip install Flask>=2.0.0 Jinja2

This will install compatible versions:

txt
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:

txt
Flask==1.1.2
Jinja2==2.11.2
MarkupSafe==1.1.1
Werkzeug==1.0.1

Install with:

bash
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:

bash
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:

bash
# 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

  1. Pin Your Dependencies: Always specify exact versions in your requirements.txt to avoid unexpected breaking changes
  2. Regular Updates: Periodically update your dependencies to receive security patches and bug fixes
  3. 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:

txt
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.