Safely add untrusted strings to HTML/XML markup.



MarkupSafe implements a text object that escapes characters so it is safe to use in HTML and XML. Characters that have special meanings are replaced so that they display as the actual characters. This mitigates injection attacks, meaning untrusted user input can safely be displayed on a page.


Install and update using pip:

pip install -U MarkupSafe


>>> from markupsafe import Markup, escape

>>> # escape replaces special characters and wraps in Markup
>>> escape("<script>alert(document.cookie);</script>")

>>> # wrap in Markup to mark text "safe" and prevent escaping
>>> Markup("<strong>Hello</strong>")

>>> escape(Markup("<strong>Hello</strong>"))

>>> # Markup is a str subclass
>>> # methods and operators escape their arguments
>>> template = Markup("Hello <em>{name}</em>")
>>> template.format(name='"World"')
Markup('Hello <em>&#34;World&#34;</em>')


The Pallets organization develops and supports MarkupSafe and other libraries that use it. In order to grow the community of contributors and users, and allow the maintainers to devote more time to the projects, please donate today.


  • wheels for markupsafe

    wheels for markupsafe

    Do you consider providing Python wheels for markupsafe? cf.

    opened by srkunze 38
  • Unicode incorrectly escaped on PyPy 7.3.1

    Unicode incorrectly escaped on PyPy 7.3.1

    On PyPy (specifically, the wheel with, when using markupsafe.escape(), this unicode below is incorrectly escaped;

    Input: 'https://x?<ab c>&q"+%3D%2B"="fö%26=o"'

    _native: 'https://x?&lt;ab c&gt;&amp;q&#34;+%3D%2B&#34;=&#34;fö%26=o&#34;' _speedups (on pypy): 'https://x?&lt;ab c&gt;&amp;q&#34;+%3D%2B&#34;=&#34;fö%26=o'

    This was caught while testing PyPy support for synapse, in, in which one of the tests hooked behind here.

    I am no expert in C, but I have a feeling one of the Unicode APIs used in _speedups.c is either being used incorrectly, or has an implementation mismatch compared to cPython

    opened by ShadowJonathan 26
  • Consider using the stable API when building wheels for CPython

    Consider using the stable API when building wheels for CPython

    I noticed your tweet about having lots of wheels (thanks for the PyPy one BTW). Perhaps you could consider creating stable ABI wheels? I think if you add

    py-limited-api = cp34

    to the setup.cfg then python bdist_wheel will build something like MarkupSafe-1.1.1-cp34-abi3-macosx_10_6_intel.whl which any cpython>-3.4 will support on macosx. This would save having to create a cpython-3.4, cpython3.5, ... wheels and would also mean you would future proof yourself for any new versions of cpython.

    You might need to adjust the CI wheel build to only build the wheel once, since the various versions of CPython will build a wheel with the same name, I think bdist_wheel is unhappy if a wheel already exists.

    opened by mattip 26
  • build py_limited_api abi3 wheel and MacOS universal2 wheel

    build py_limited_api abi3 wheel and MacOS universal2 wheel

    Use py_limited_api to build one wheel for 3.6+. Currently testing this.

    Use cibuildwheel as a GitHub action. Don't need setup-python or pip install.

    Build a MacOS universal2 wheel. From what I could tell from the cibuildwheel docs, this seems to be preferred over building the arm64 wheel.

    closes #175

    opened by davidism 17
  • Won't install on Windows

    Won't install on Windows

    Python 3.6 (x86-64) pip == 9.0.1 setuptools == 34.3.2

    (no36) D:\Git\project>pip install --force --upgrade markupsafe
    Collecting markupsafe
      Using cached MarkupSafe-1.0.tar.gz
    Building wheels for collected packages: markupsafe
      Running bdist_wheel for markupsafe ... error
      Failed building wheel for markupsafe
      Running clean for markupsafe
    Failed to build markupsafe
    Installing collected packages: markupsafe
      Found existing installation: markupsafe 1.0
        Uninstalling markupsafe-1.0:
          Successfully uninstalled markupsafe-1.0
      Running install for markupsafe ... error
      Rolling back uninstall of markupsafe
    Traceback (most recent call last):
      File "d:\python\no36\lib\site-packages\pip\compat\", line 73, in console_to_str
        return s.decode(sys.__stdout__.encoding)
    UnicodeDecodeError: 'utf-8' codec can't decode byte 0xe9 in position 66: invalid continuation byte
    During handling of the above exception, another exception occurred:
    Traceback (most recent call last):
      File "d:\python\no36\lib\site-packages\pip\", line 215, in main
        status =, args)
      File "d:\python\no36\lib\site-packages\pip\commands\", line 342, in run
      File "d:\python\no36\lib\site-packages\pip\req\", line 784, in install
      File "d:\python\no36\lib\site-packages\pip\req\", line 878, in install
      File "d:\python\no36\lib\site-packages\pip\utils\", line 676, in call_subprocess
        line = console_to_str(proc.stdout.readline())
      File "d:\python\no36\lib\site-packages\pip\compat\", line 75, in console_to_str
        return s.decode('utf_8')
    UnicodeDecodeError: 'utf-8' codec can't decode byte 0xe9 in position 66: invalid continuation byte
    opened by debnet 17
  • Use PEP 393 new APIs

    Use PEP 393 new APIs

    markupsafe doesn't support Python 3.2 anymore. So just use new API at Python 3.

    opened by methane 12
  • Build without speedups

    Build without speedups

    I've been building MarkupSafe using the --without-speedups option, because I have a requirement to distribute this module across various OSes in my network. All, of a sudden, I now see that this option is no longer available for How can I build a pure-python setup without building the C extension, for distribution, as I previously did?

    opened by aabdnn 11
  • Fixed format for keyword arguments

    Fixed format for keyword arguments

    In [1]: from markupsafe import Markup                                                                                                            
    In [2]: Markup(u'{a}').format(a=u'<>')
    Out[2]: Markup(u'<>')
    In [3]: Markup(u'{}').format(u'<>')                                                                                                             
    Out[3]: Markup(u'&lt;&gt;')
    opened by anti-social 11
  • Tests fail under pypy/pypy3 due to reliance on garbage collection policies.

    Tests fail under pypy/pypy3 due to reliance on garbage collection policies.


    MarkupLeakTestCase is the test in question. Under pypy, which does not run the garbage collection routines when expected, more objects will be returned via gc.get_objects() than one would expect.

    The test should be skipped on non-CPython platforms.

    opened by amcgregor 8
  • update cibuildwheel

    update cibuildwheel

    Target the 2.0.1 tag to build new wheels.

    opened by davidism 0
  • 2.0.1(May 18, 2021)

  • 2.0.0(May 12, 2021)

    New major versions of all the core Pallets libraries, including MarkupSafe 2.0, have been released! :tada:

    • Read the announcement on our blog:
    • Read the full list of changes:
    • Retweet the announcement on Twitter:
    • Follow our blog, Twitter, or GitHub to see future announcements.

    This represents a significant amount of work, and there are quite a few changes. Be sure to carefully read the changelog, and use tools such as pip-compile and Dependabot to pin your dependencies and control your updates.

    Source code(tar.gz)
    Source code(zip)
  • 2.0.0rc2(Apr 16, 2021)

Converts XML to Python objects

untangle Documentation Converts XML to a Python object. Siblings with similar names are grouped into a list. Children can be accessed with parent.chil

Christian Stefanescu 527 Oct 19, 2021
Bleach is an allowed-list-based HTML sanitizing library that escapes or strips markup and attributes

Bleach Bleach is an allowed-list-based HTML sanitizing library that escapes or strips markup and attributes. Bleach can also linkify text safely, appl

Mozilla 2.2k Oct 20, 2021
Pythonic HTML Parsing for Humans™

Requests-HTML: HTML Parsing for Humans™ This library intends to make parsing HTML (e.g. scraping the web) as simple and intuitive as possible. When us

Python Software Foundation 12.2k Oct 23, 2021
A jquery-like library for python

pyquery: a jquery-like library for python pyquery allows you to make jquery queries on xml documents. The API is as much as possible the similar to jq

Gael Pasgrimaud 2k Oct 22, 2021
Standards-compliant library for parsing and serializing HTML documents and fragments in Python

html5lib html5lib is a pure-python library for parsing HTML. It is designed to conform to the WHATWG HTML specification, as is implemented by all majo

null 935 Oct 15, 2021
The lxml XML toolkit for Python

What is lxml? lxml is the most feature-rich and easy-to-use library for processing XML and HTML in the Python language. It's also very fast and memory

null 2k Oct 26, 2021
Python binding to Modest engine (fast HTML5 parser with CSS selectors).

A fast HTML5 parser with CSS selectors using Modest engine. Installation From PyPI using pip: pip install selectolax Development version from github:

Artem Golubin 463 Oct 16, 2021
A library for converting HTML into PDFs using ReportLab

XHTML2PDF The current release of xhtml2pdf is xhtml2pdf 0.2.5. Release Notes can be found here: Release Notes As with all open-source software, its us

null 1.8k Oct 22, 2021
The awesome document factory

The Awesome Document Factory WeasyPrint is a smart solution helping web developers to create PDF documents. It turns simple HTML pages into gorgeous s

Kozea 4.6k Oct 22, 2021