API Reference

eml2pdf.generate_pdf(*, html_content: str, outfile_path: Path, debug_html: bool = False, page: str = 'a4', unsafe: bool = False, logging_id: str | None = None) → None[source]
eml2pdf.generate_pdf(*, html_content: str, page: str = 'a4', unsafe: bool = False, logging_id: str | None = None) → bytes

Convert HTML content to PDF with optional sanitization.

Generates a PDF from HTML content using WeasyPrint. By default, sanitizes HTML to remove security and privacy risks before rendering.

Processing Steps:
  1. Sanitize HTML (unless unsafe=True)

  2. Optionally save HTML to disk for debugging

  3. Parse HTML with WeasyPrint

  4. Apply page size and margins via CSS

  5. Get exclusive output file handle (prevents conflicts)

  6. Write PDF to file

Parameters:
  • html_content (str) – The HTML content to convert to PDF.

  • outfile_path (Path) – Desired output file path.

  • debug_html (bool, optional) – If True, saves HTML to {outfile}.html for debugging. Defaults to False.

  • page (str, optional) – Page size for PDF (e.g., ‘a4’, ‘letter’). Defaults to ‘a4’.

  • unsafe (bool, optional) – If True, bypasses HTML sanitization. Only use when you completely trust the source. Defaults to False.

  • logging_id (str | None, optional) – Identifier for logging context.

Note

HTML sanitization is performed by security.sanitize_html() unless unsafe=True. See security.md for details on what is filtered.

Raises:

Exception – Logs error if PDF generation fails, but does not re-raise.

eml2pdf.process_eml(eml_path: Path, output_path: Path, page: str = 'a4', debug_html: bool = False, unsafe: bool = False, logging_id: str | None = None)[source]

Process a single EML file and generate a PDF.

  1. Parse EML file with email.message_from_binary_file() (fallback to

    message_from_file())

  2. Extract header (from/to/subject/date)

  3. Walk message parts to extract content and attachments

  4. Generate attachment list table

  5. Assemble complete HTML with UTF-8 meta tags, header, attachments, and body

  6. Generate output filename from date and subject

  7. Convert to PDF (with sanitization unless unsafe=True)

HTML Structure:
  • UTF-8 meta tags

  • Email header table (from/to/date/subject)

  • Attachment list table

  • Horizontal rule separator

  • Email body content with embedded images

Parameters:
  • eml_path (Path) – Path to the EML file to process.

  • output_path (Path) – Path where PDF will be saved. If this is a dir then an output filename will be derived from the email content. If this is a file then output_path is taken as filename.

  • page (str, optional) – PDF page size. Defaults to ‘a4’.

  • debug_html (bool, optional) – Save HTML to disk for debugging. Defaults to False.

  • unsafe (bool, optional) – Skip HTML sanitization. Defaults to False.

  • logging_id (str | None, optional) – Identifier for logging context. Defaults to the eml_path name.

Note

If no text content is found, the file is skipped and a warning is logged. Output filename format: {date}-{subject}.pdf

eml2pdf.process_eml_bytes(contents: bytes, page: str = 'a4', debug_html: bool = False, unsafe: bool = False, logging_id: str | None = None) → bytes[source]

Generates a PDF from an EML file in memory.

Same as process_eml() but accepts and returns bytes instead of files.

Parameters:
  • contents (bytes) – The bytes of the eml file

  • page (str, optional) – PDF page size. Defaults to ‘a4’.

  • debug_html (bool, optional) – Save HTML to disk for debugging. Defaults to False.

  • unsafe (bool, optional) – Skip HTML sanitization. Defaults to False.

  • logging_id (str | None, optional) – Identifier for logging context.

Returns (bytes): The bytes of a valid PDF file.

eml2pdf.process_all_emls_in_dir(input_dir: Path, output_dir: Path, number_of_procs: int = 1, debug_html: bool = False, page: str = 'a4', unsafe: bool = False)[source]

Process all EML files in a directory to PDFs.

Main entry point for batch processing of email files. Handles directory creation, file discovery, and parallel or sequential processing.

Multiprocessing Conditions:

Parallel processing is used when ALL of these are true: - number_of_procs > 1 - logger level is not DEBUG

Reason for Limitations:

Debug logging outputs long messages that are not multiprocess-safe and would become garbled when multiple processes write simultaneously.

Parameters:
  • input_dir (Path) – Directory containing EML files to process.

  • output_dir (Path) – Directory where PDFs will be saved (created if needed).

  • number_of_procs (int) – Number of parallel processes. Use 1 for sequential. Defaults to 1.

  • debug_html (bool) – Save intermediate HTML files for debugging. Defaults to False.

  • page (str) – PDF page size (e.g., ‘a4’, ‘letter’). Defaults to ‘a4’

  • unsafe (bool) – Skip HTML sanitization (use only with trusted sources). Defaults to False.

Note

Creates output_dir with parents if it doesn’t exist. Exits with code 1 if output directory cannot be created. Uses Python’s multiprocessing.Pool for parallel processing.

eml2pdf.header_to_html(header_str: str) → str[source]

Decode and HTML-escape an email header field.

Processes encoded email headers by decoding multi-part headers and concatenating them into a single HTML-safe string.

Decoding Strategy:
  1. Uses email.header.decode_header() to parse encoded headers

  2. Handles multi-part headers by concatenating them

  3. For string parts, uses them directly

  4. For byte parts, decodes with specified encoding (defaults to

    ‘ascii’ if None)

  5. HTML-escapes the final result to prevent XSS

Parameters:

header_str (str) – The raw email header string (may be RFC 2047 encoded).

Returns:

Decoded and HTML-escaped header string safe for inclusion in HTML.

Return type:

str

Example

>>> header_to_html('=?utf-8?B?SGVsbG8gV29ybGQ=?=')
'Hello World'
>>> header_to_html('Test <tag>')
'Test &lt;tag&gt;'
eml2pdf.sanitize_html(html_content)[source]

Remove potential privacy and security issues from HTML content.

Sanitizes HTML by removing or neutralizing dangerous elements and attributes before PDF generation. This provides defense-in-depth protection against various attack vectors.

Protected Against:
  • Script execution (script, iframe, object, embed tags)

  • Data exfiltration via forms

  • Privacy leaks via remote resources (tracking pixels, web beacons)

  • Cross-Site Scripting via event handlers (onclick, onload, onerror, etc.)

  • Remote resource loading (meta redirects, external stylesheets)

  • CSS-based tracking via url() references

  • External link navigation

Processing Steps:
  1. Removes risky HTML tags (script, iframe, object, embed, video, audio, form, meta, link)

  2. Removes remote images (http:// or https:// sources)

  3. Clears style attributes containing url() references

  4. Neutralizes external links by replacing href with ‘#’

  5. Removes event handler attributes (on*) and data attributes (data-*)

Parameters:

html_content (str) – The HTML content to sanitize.

Returns:

Sanitized HTML content safe for PDF rendering.

Return type:

str

Note

Only embedded images (data URIs or CID references) are preserved. Remote images are completely removed to prevent tracking.

Example

>>> html = (
    '<img src="http://tracker.com/pixel.gif">'
    '<script>alert(1)</script>'
)
>>> sanitize_html(html)
''