Python API

Everything the command line does is available from Python. The library never prints or exits: results are returned, and failures are raised.

Example

from dataclasses import replace

from word2html import Limits, UnsafeDocumentError, WordToHtmlError, convert_to_html

limits = replace(Limits(), timeout=30, max_memory=512 * 1024 * 1024)

try:
    result = convert_to_html("report.docx", strict=True, limits=limits)
except UnsafeDocumentError as exc:
    print("refused:", exc)
    for finding in exc.findings:
        print(" -", finding.kind, finding.message)
except (WordToHtmlError, FileNotFoundError) as exc:
    print("failed:", exc)
else:
    print("wrote", result.output_path)
    for finding in result.warnings:
        print(" -", finding.kind, finding.message)

convert_to_html

convert_to_html(
    filename: str | os.PathLike[str],
    *,
    strict: bool = False,
    limits: Limits | None = None,
) -> ConversionResult

Converts a document and writes the HTML next to it, replacing any existing file with that name.

ArgumentDescription
filenamePath to the .docx file.
strictRaise UnsafeDocumentError for unsafe links or hidden text, instead of returning them as warnings.
limitsResource limits, or None for the defaults.

ConversionResult

AttributeTypeDescription
output_pathpathlib.PathThe HTML file that was written.
warningstuple[Finding, ...]Things to know about the document. Empty if there are none.

Limits

A frozen dataclass. Use dataclasses.replace() to change individual values.

FieldDefaultDescription
max_file_size200 MiBLargest input file, in bytes.
max_total_uncompressed1 GiBLargest total uncompressed size, in bytes.
max_xml_part_size64 MiBLargest single XML part, in bytes.
max_zip_entries10,000Most files in the archive.
max_xml_depth256Deepest XML nesting.
max_memory2 GiBpandoc memory limit, in bytes.
timeout120.0pandoc time limit, in seconds.

Finding and FindingKind

A Finding has a kind and a message. Messages are already escaped, so they're safe to print to a terminal.

FindingKindValueMeaningHandling
UNSAFE_LINKunsafe-linkA link with a scheme that isn't allowedWarning; refused with strict=True
HIDDEN_TEXThidden-textText hidden in Word that'll be visibleWarning; refused with strict=True
ACTIVE_CONTENTactive-contentContent that could run in a browserAlways refused
LINKED_IMAGElinked-imageAn image that isn't stored in the documentWarning only
PANDOCpandocA message from pandoc itselfWarning only

Check for a specific kind like this:

from word2html import FindingKind, convert_to_html

result = convert_to_html("report.docx")
has_hidden_text = any(f.kind is FindingKind.HIDDEN_TEXT for f in result.warnings)

Exceptions

Everything word2html raises deliberately derives from WordToHtmlError, except FileNotFoundError for a missing input. If any of these is raised, no output was written.

ExceptionRaised when
WordToHtmlErrorThe base class. Catch this for any deliberate failure.
InvalidDocumentErrorThe input isn't a usable .docx. Also a ValueError.
ResourceLimitErrorThe input, or converting it, exceeded a limit.
UnsafeDocumentErrorThe document was refused. Its findings attribute says why.
PandocNotFoundErrorpandoc isn't installed or isn't on PATH.
PandocErrorpandoc is too old, or failed for a reason other than the document.
OutputErrorThe HTML couldn't be written.
FileNotFoundErrorThe input doesn't exist. This is Python's built-in exception.

Version

import word2html

print(word2html.__version__)

Threads and processes

Each call starts its own pandoc process and keeps no shared state, so separate documents can be converted at the same time. Two calls converting the same document will both write the same output path, and whichever finishes last wins.