Open source · 2025

email-to-pdf

A Python-based email-to-PDF conversion tool that renders HTML emails into clean, production-ready PDFs while preserving structure, styling, and visual fidelity.

Free · Open source
  • Python

Questions

Is email-to-pdf free?

Yes. email-to-pdf is free to use and open source. The full source code is on GitHub at https://github.com/kshitizwagle/email-to-pdf.

How do I get email-to-pdf?

Get the source from https://github.com/kshitizwagle/email-to-pdf; the README there covers installation and usage.

Is there a warranty or support for email-to-pdf?

No. email-to-pdf was built with AI assistance and is provided as is, without warranty. Kshitiz Wagle is not liable for damage or loss. Use it at your own risk.

Who makes email-to-pdf?

email-to-pdf is built and maintained by Kshitiz Wagle, a software engineer in Lalitpur, Nepal. Portfolio: https://kshitizwagle.com.np.

README

Convert .eml and .msg email files to PDF — via CLI, HTTP API, or Python library.

Features

  • Supports .eml (RFC 822) and .msg (Outlook) formats
  • HTML sanitization before rendering
  • Attachment extraction
  • Configurable paper format (A4, Letter, Legal, A3)
  • Structured JSON logging

Installation

pip install git+https://github.com/kshitizwagle/email-to-pdf.git

After installing, download the Chromium browser that Playwright uses for rendering:

playwright install chromium --with-deps

To also install the web server components:

pip install "git+https://github.com/kshitizwagle/email-to-pdf.git#egg=email-to-pdf[server]"

Requirements

  • Python 3.14+
  • Chromium (installed via the playwright install step above)

Usage

CLI

# Basic conversion
email-to-pdf email.eml

# Custom output path and paper format
email-to-pdf email.eml -o output.pdf --format Letter

# Extract attachments
email-to-pdf email.msg --extract-attachments ./attachments/

Python library

import asyncio
from email_to_pdf import convert

result = asyncio.run(convert("email.eml", output_path="output.pdf"))
print(f"Pages: {result.page_count}, Size: {result.output_size_bytes} bytes")

For high-throughput use, reuse a ConversionContext to share a browser pool across calls:

from email_to_pdf import ConversionContext

ctx = ConversionContext()
await ctx.start()

result = await ctx.convert("email.eml", output_path="output.pdf")

await ctx.stop()

You can configure rendering, attachments, and more via Settings:

from email_to_pdf import ConversionContext, Settings
from email_to_pdf.infra.config import RenderSettings

settings = Settings(render=RenderSettings(paper_format="Letter", scale=0.9))
ctx = ConversionContext(settings)

Web UI / HTTP API

Requires the server extra (see installation above).

uvicorn main:app --reload

Open http://localhost:8000 for the drag-and-drop web interface, or use the API:

# Upload and convert
curl -F file=@email.eml http://localhost:8000/convert
# {"token": "...", "filename": "email.pdf", "size": 12345}

# Download the PDF
curl -o output.pdf http://localhost:8000/download/<token>

Docker

docker compose up

The service is available at http://localhost:8000.

Development

git clone https://github.com/kshitizwagle/email-to-pdf.git
cd email-to-pdf
uv sync --dev
uv run playwright install chromium --with-deps
uv run pytest
← All projectsSource on GitHub ↗