class HybridSessionDocTemplate
A custom ReportLab document template class that extends BaseDocTemplate to create PDF documents with session information footers, specifically designed for hybrid text and graphics responses.
/tf/active/vicechatdev/e-ink-llm/hybrid_pdf_generator.py
29 - 84
moderate
Purpose
This class provides a specialized PDF document template for generating hybrid response PDFs with automatic footer generation. It manages page layout with a main content frame and adds session metadata (conversation ID, exchange number) to each page footer. The footer includes page numbers, a hybrid response indicator, and session tracking information, making it ideal for conversational AI systems that need to track and document multi-turn interactions with mixed content types.
Source Code
class HybridSessionDocTemplate(BaseDocTemplate):
"""Custom document template for hybrid PDFs with session info"""
def __init__(self, filename, conversation_id=None, exchange_number=None, **kwargs):
super().__init__(filename, **kwargs)
self.conversation_id = conversation_id
self.exchange_number = exchange_number
# Create frame for main content (leaving space for footer)
main_frame = Frame(
self.leftMargin, self.bottomMargin + 0.5*inch,
self.width, self.height - 0.5*inch,
id='main'
)
# Create page template
main_template = PageTemplate(
id='main',
frames=[main_frame],
onPage=self.add_session_footer
)
self.addPageTemplates([main_template])
def add_session_footer(self, canvas, doc):
"""Add session information to page footer"""
canvas.saveState()
# Set footer style
canvas.setFont('Helvetica', 8)
canvas.setFillColor(colors.grey)
# Left side: page number
page_text = f"Page {doc.page}"
canvas.drawString(doc.leftMargin, doc.bottomMargin, page_text)
# Center: hybrid indicator
hybrid_text = "Hybrid Response (Text + Graphics)"
text_width = canvas.stringWidth(hybrid_text, 'Helvetica', 8)
x_center = (doc.width + 2*doc.leftMargin) / 2 - text_width / 2
canvas.drawString(x_center, doc.bottomMargin, hybrid_text)
# Right side: session info
if self.conversation_id and self.exchange_number:
session_text = f"Session: {self.conversation_id} | Exchange #{self.exchange_number}"
elif self.conversation_id:
session_text = f"Session: {self.conversation_id}"
else:
session_text = "E-Ink LLM Assistant"
# Calculate position for right-aligned text
text_width = canvas.stringWidth(session_text, 'Helvetica', 8)
x_position = doc.width + doc.leftMargin - text_width
canvas.drawString(x_position, doc.bottomMargin, session_text)
canvas.restoreState()
Parameters
| Name | Type | Default | Kind |
|---|---|---|---|
bases |
BaseDocTemplate | - |
Parameter Details
filename: The output filename or file path where the PDF document will be saved. Can be a string path or file-like object.
conversation_id: Optional identifier for the conversation session. Used in the footer to track which conversation this document belongs to. Can be None if session tracking is not needed.
exchange_number: Optional integer representing the exchange number within a conversation. Used in the footer to indicate the specific turn or exchange. Can be None if exchange tracking is not needed.
**kwargs: Additional keyword arguments passed to the parent BaseDocTemplate class, such as pagesize (default letter), leftMargin, rightMargin, topMargin, bottomMargin, title, author, etc.
Return Value
Instantiation returns a HybridSessionDocTemplate object that can be used to build PDF documents. The object inherits all methods from BaseDocTemplate, primarily the build() method which takes a list of flowables (Paragraph, Image, Spacer, etc.) and generates the final PDF with session footers on each page.
Class Interface
Methods
__init__(self, filename, conversation_id=None, exchange_number=None, **kwargs)
Purpose: Initializes the hybrid session document template with session tracking information and sets up the page layout with a main content frame and footer space
Parameters:
filename: Output PDF filename or file pathconversation_id: Optional conversation session identifierexchange_number: Optional exchange number within the conversation**kwargs: Additional arguments passed to BaseDocTemplate (pagesize, margins, etc.)
Returns: None (constructor)
add_session_footer(self, canvas, doc)
Purpose: Callback method that adds session information footer to each page, including page number, hybrid indicator, and session details
Parameters:
canvas: ReportLab Canvas object for drawing on the pagedoc: Document object containing page information and dimensions
Returns: None (modifies canvas in place)
Attributes
| Name | Type | Description | Scope |
|---|---|---|---|
conversation_id |
Optional[str] | Stores the conversation identifier for display in the footer | instance |
exchange_number |
Optional[int] | Stores the exchange number within the conversation for display in the footer | instance |
leftMargin |
float | Left margin of the document (inherited from BaseDocTemplate) | instance |
bottomMargin |
float | Bottom margin of the document (inherited from BaseDocTemplate) | instance |
width |
float | Width of the content area (inherited from BaseDocTemplate) | instance |
height |
float | Height of the content area (inherited from BaseDocTemplate) | instance |
Dependencies
reportlab
Required Imports
from reportlab.platypus.doctemplate import BaseDocTemplate
from reportlab.platypus.doctemplate import PageTemplate
from reportlab.platypus.frames import Frame
from reportlab.lib import colors
from reportlab.lib.units import inch
Usage Example
from reportlab.platypus.doctemplate import BaseDocTemplate
from reportlab.platypus.doctemplate import PageTemplate
from reportlab.platypus.frames import Frame
from reportlab.lib import colors
from reportlab.lib.units import inch
from reportlab.platypus import Paragraph, Spacer
from reportlab.lib.styles import getSampleStyleSheet
# Instantiate the template
doc = HybridSessionDocTemplate(
'output.pdf',
conversation_id='conv_12345',
exchange_number=3
)
# Create content
styles = getSampleStyleSheet()
story = [
Paragraph('Hybrid Response Example', styles['Heading1']),
Spacer(1, 0.2*inch),
Paragraph('This is a text response with graphics.', styles['Normal'])
]
# Build the PDF
doc.build(story)
# Example without session info
doc_simple = HybridSessionDocTemplate('simple.pdf')
doc_simple.build(story)
Best Practices
- Always call the build() method with a list of flowables to generate the PDF after instantiation
- Provide conversation_id and exchange_number for proper session tracking in multi-turn conversations
- The template reserves 0.5 inches at the bottom for the footer, so content will automatically flow within the remaining space
- Use with other ReportLab flowables (Paragraph, Image, Spacer, etc.) to create rich content
- The footer is automatically added to every page via the onPage callback mechanism
- Session information in the footer is conditionally displayed based on what parameters were provided during instantiation
- The template uses letter size by default but can be customized via kwargs (e.g., pagesize=A4)
- Canvas state is properly managed (saveState/restoreState) in the footer callback to avoid affecting main content rendering
Tags
Similar Components
AI-powered semantic similarity - components with related functionality:
-
class SessionDocTemplate 87.1% similar
-
class HybridResponseHandler 66.8% similar
-
class HybridResponse 66.0% similar
-
function demo_hybrid_response 64.8% similar
-
class HybridPDFGenerator 64.7% similar