Implement PDF renderer with WeasyPrint

This commit is contained in:
2026-01-29 17:58:23 +00:00
parent 5405ceec7f
commit 3b136dca69
2 changed files with 85 additions and 1 deletions

View File

@@ -1,5 +1,6 @@
"""Report renderers for HTML and PDF output."""
from py_dvt_ate.reporting.renderers.html import HTMLRenderer
from py_dvt_ate.reporting.renderers.pdf import PDFRenderer
__all__ = ["HTMLRenderer"]
__all__ = ["HTMLRenderer", "PDFRenderer"]

View File

@@ -0,0 +1,83 @@
"""PDF renderer using WeasyPrint.
This module provides PDF rendering from HTML content using WeasyPrint.
"""
from pathlib import Path
from py_dvt_ate.reporting.exceptions import PDFConversionError
class PDFRenderer:
"""Renders PDF documents from HTML content using WeasyPrint.
WeasyPrint converts HTML/CSS to PDF with support for page layout,
headers/footers, and professional typography.
"""
def __init__(self) -> None:
"""Initialise the PDF renderer."""
self._weasyprint: type | None = None
def _get_weasyprint(self) -> type:
"""Lazy-load WeasyPrint to avoid import errors when not installed.
Returns:
The WeasyPrint HTML class.
Raises:
PDFConversionError: If WeasyPrint is not installed.
"""
if self._weasyprint is None:
try:
from weasyprint import HTML
self._weasyprint = HTML
except ImportError as e:
msg = (
"WeasyPrint is required for PDF generation. "
"Install it with: pip install py_dvt_ate[reports]"
)
raise PDFConversionError(msg) from e
return self._weasyprint
def render_to_file(self, html: str, path: Path) -> None:
"""Render HTML content to a PDF file.
Args:
html: HTML content to convert.
path: Output path for the PDF file.
Raises:
PDFConversionError: If PDF conversion fails.
"""
try:
HTML = self._get_weasyprint()
path.parent.mkdir(parents=True, exist_ok=True)
HTML(string=html).write_pdf(path)
except PDFConversionError:
raise
except Exception as e:
msg = f"Failed to convert HTML to PDF: {e}"
raise PDFConversionError(msg) from e
def render_to_bytes(self, html: str) -> bytes:
"""Render HTML content to PDF bytes.
Args:
html: HTML content to convert.
Returns:
PDF document as bytes.
Raises:
PDFConversionError: If PDF conversion fails.
"""
try:
HTML = self._get_weasyprint()
return HTML(string=html).write_pdf()
except PDFConversionError:
raise
except Exception as e:
msg = f"Failed to convert HTML to PDF: {e}"
raise PDFConversionError(msg) from e