Spaces:
Sleeping
Sleeping
File size: 2,817 Bytes
690bcb6 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 |
import io
from typing import List, Dict
import streamlit as st
def _import_reportlab():
try:
from reportlab.lib.pagesizes import A4
from reportlab.lib.styles import getSampleStyleSheet
from reportlab.lib.units import mm
from reportlab.pdfgen import canvas
from reportlab.platypus import Paragraph, SimpleDocTemplate, Spacer, Table, TableStyle
from reportlab.lib import colors
return {
"A4": A4,
"getSampleStyleSheet": getSampleStyleSheet,
"mm": mm,
"canvas": canvas,
"Paragraph": Paragraph,
"SimpleDocTemplate": SimpleDocTemplate,
"Spacer": Spacer,
"Table": Table,
"TableStyle": TableStyle,
"colors": colors,
}
except Exception:
return None
def build_chat_pdf(messages: List[Dict[str, str]], title: str = "MediLingua Chat Transcript") -> io.BytesIO:
"""
Create a PDF from chat messages and return as an in-memory BytesIO buffer.
Each message is a dict with keys: role ('user'|'assistant'), content (str).
"""
libs = _import_reportlab()
if libs is None:
st.error(
"PDF generation library not found. Install with: `pip install reportlab` and rerun."
)
return None
buffer = io.BytesIO()
doc = libs["SimpleDocTemplate"](buffer, pagesize=libs["A4"], rightMargin=28, leftMargin=28, topMargin=36, bottomMargin=28)
styles = libs["getSampleStyleSheet"]()
elements = []
# Title
title_style = styles["Title"]
elements.append(libs["Paragraph"](title, title_style))
elements.append(libs["Spacer"](1, 12))
# Build a table-like layout for messages
data = []
table_style_cmds = [
("VALIGN", (0, 0), (-1, -1), "TOP"),
("INNERGRID", (0, 0), (-1, -1), 0.25, libs["colors"].lightgrey),
("BOX", (0, 0), (-1, -1), 0.25, libs["colors"].lightgrey),
("LEFTPADDING", (0, 0), (-1, -1), 6),
("RIGHTPADDING", (0, 0), (-1, -1), 6),
("TOPPADDING", (0, 0), (-1, -1), 6),
("BOTTOMPADDING", (0, 0), (-1, -1), 6),
]
role_style = styles["Heading5"]
body_style = styles["BodyText"]
for msg in messages:
role = msg.get("role", "").capitalize()
content = msg.get("content", "")
# Left column: role, Right column: content paragraph
role_par = libs["Paragraph"](f"<b>{role}</b>", role_style)
content_par = libs["Paragraph"](content.replace("\n", "<br/>"), body_style)
data.append([role_par, content_par])
table = libs["Table"](data, colWidths=[30 * libs["mm"], None])
table.setStyle(libs["TableStyle"](table_style_cmds))
elements.append(table)
doc.build(elements)
buffer.seek(0)
return buffer
|