unmhtml
Convert MHTML files — or any HTML document with its resources — to a single standalone HTML string: CSS inlined, images and fonts embedded as data URIs, active content sanitized for safe display.
Installation
pip install unmhtml
Usage
Convert an MHTML archive:
from pathlib import Path
from unmhtml import load_mhtml, to_standalone_html
document = load_mhtml(Path("saved_page.mhtml").read_bytes())
html = to_standalone_html(document)
Or bring your own HTML and resources — a rendered page plus the bodies captured in a HAR archive, for example:
from unmhtml import Document, Resource, to_standalone_html
document = Document(
html=rendered_html,
resources={
"https://example.com/style.css": Resource(css_bytes, "text/css"),
"https://example.com/logo.png": Resource(png_bytes, "image/png"),
},
base_url="https://example.com/page.html",
)
html = to_standalone_html(document)
References resolve against base_url and match resource keys exactly; CSS
references inside a stylesheet resolve against the stylesheet's own URL.
Anything unresolvable is neutralized, so the result never makes network
requests.
Security
Conversion is secure by default: scripts, event handlers and dangerous URLs
are removed, forms are defused, head furniture that could fetch or redirect
(link, meta, base) is dropped, and CSS that could still fetch is
stripped. Each neutralization has its own flag on Security
(remove_javascript, disable_forms, sanitize_css), all defaulting to on:
from unmhtml import Security, to_standalone_html
html = to_standalone_html(
document,
security=Security(remove_javascript=False), # flags are independent
)
The contract is reduction, not isolation: the output makes no network
requests, but this is defense in depth, not a sandbox — display untrusted
output in a sandboxed context of your own, such as a sandboxed iframe
without allow-scripts, combined with a Content-Security-Policy.
API
load_mhtml(data) -> Document— parse MHTML content; raisesValueErrorwhen no HTML part existsDocument(html, resources, base_url)— a parsed document; resources map absolute URLs toResourcevaluesResource(data, mime_type)— one resource; the MIME type is guessed from the reference URL when omittedto_standalone_html(document, *, security=Security()) -> str— the document as one self-contained HTML string
The output is an HTML fragment: html/head/body wrappers and head
furniture (title, meta, link, base) are removed and the original
doctype is re-emitted. HTML comments are removed, relative anchor targets
are made absolute against base_url, and every anchor carries
rel="noopener noreferrer".
Requirements
Python 3.8+. The single dependency is nh3 (Python bindings to the Rust ammonia sanitizer) — zero transitive runtime dependencies, wheels for all major platforms.
License
MIT
Metadata
Release files for unmhtml 0.4.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| unmhtml-0.4.0.tar.gz | 78.8 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| unmhtml-0.4.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 92.2 kB
Release files / unmhtml-0.4.0.tar.gz
| Download URL | unmhtml-0.4.0.tar.gz |
|---|---|
| Size | 78.8 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
49a83d97768e4113e40cd8360638ad4e2e7a71dcbb42e6d304c2c73da1638e50
|
|
BLAKE2b-256 checksum How to use checksums |
d7a59b6c8c67259b43f0c94cf7b657be4bae13a199fd9bbd07ca6da8d4ffe820
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Oct 3, 2026.
Transparency logRelease files / unmhtml-0.4.0-py3-none-any.whl
| Download URL | unmhtml-0.4.0-py3-none-any.whl |
|---|---|
| Size | 13.5 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
4bd5e6ba90b171ac31ac6829cc5fa750c196a0c26bc6b2f8721f672a79958042
|
|
BLAKE2b-256 checksum How to use checksums |
ad6d4824cf42ecacb82c8e0336f1a7b3f8d3e7816ce534a693f7f860d68f9c2a
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Oct 3, 2026.
Transparency log