Spaces:
Running
Running
| """ | |
| PDF Report Generator for Farmer.Chat | |
| Exports query results as downloadable PDF | |
| """ | |
| from reportlab.lib.pagesizes import letter, A4 | |
| from reportlab.lib.styles import getSampleStyleSheet, ParagraphStyle | |
| from reportlab.lib.units import inch | |
| from reportlab.platypus import SimpleDocTemplate, Paragraph, Spacer, Table, TableStyle, PageBreak | |
| from reportlab.lib import colors | |
| from reportlab.lib.enums import TA_CENTER, TA_LEFT | |
| from datetime import datetime | |
| import json | |
| import os | |
| from typing import Dict, Any | |
| def generate_pdf_report( | |
| query: str, | |
| advice: str, | |
| data: Dict[str, Any], | |
| location: Dict[str, Any] | |
| ) -> str: | |
| """ | |
| Generate PDF report from query results | |
| Args: | |
| query: Farmer's question | |
| advice: Generated advice | |
| data: Compiled data from MCP servers | |
| location: Location information | |
| Returns: | |
| str: Path to generated PDF file | |
| """ | |
| # Create output directory | |
| output_dir = "./pdf_reports" | |
| os.makedirs(output_dir, exist_ok=True) | |
| # Generate filename | |
| timestamp = datetime.now().strftime("%Y%m%d_%H%M%S") | |
| filename = f"farmer_chat_report_{timestamp}.pdf" | |
| filepath = os.path.join(output_dir, filename) | |
| # Create PDF | |
| doc = SimpleDocTemplate(filepath, pagesize=letter) | |
| story = [] | |
| styles = getSampleStyleSheet() | |
| # Custom styles | |
| title_style = ParagraphStyle( | |
| 'CustomTitle', | |
| parent=styles['Heading1'], | |
| fontSize=24, | |
| textColor=colors.HexColor('#2E7D32'), | |
| spaceAfter=30, | |
| alignment=TA_CENTER | |
| ) | |
| heading_style = ParagraphStyle( | |
| 'CustomHeading', | |
| parent=styles['Heading2'], | |
| fontSize=16, | |
| textColor=colors.HexColor('#1B5E20'), | |
| spaceAfter=12, | |
| spaceBefore=20 | |
| ) | |
| # Title | |
| story.append(Paragraph("🌾 Farmer.Chat Report", title_style)) | |
| story.append(Spacer(1, 0.2*inch)) | |
| # Metadata section | |
| metadata_data = [ | |
| ["Report Generated:", datetime.now().strftime("%B %d, %Y at %I:%M %p")], | |
| ["Location:", f"{location['name']}"], | |
| ["Coordinates:", f"{location['lat']}°N, {location['lon']}°E"], | |
| ["Data Sources:", f"{len(data.get('successful_servers', []))} MCP Servers"] | |
| ] | |
| metadata_table = Table(metadata_data, colWidths=[2*inch, 4*inch]) | |
| metadata_table.setStyle(TableStyle([ | |
| ('BACKGROUND', (0, 0), (0, -1), colors.HexColor('#E8F5E9')), | |
| ('TEXTCOLOR', (0, 0), (-1, -1), colors.black), | |
| ('ALIGN', (0, 0), (-1, -1), 'LEFT'), | |
| ('FONTNAME', (0, 0), (0, -1), 'Helvetica-Bold'), | |
| ('FONTNAME', (1, 0), (1, -1), 'Helvetica'), | |
| ('FONTSIZE', (0, 0), (-1, -1), 10), | |
| ('BOTTOMPADDING', (0, 0), (-1, -1), 8), | |
| ('GRID', (0, 0), (-1, -1), 1, colors.grey) | |
| ])) | |
| story.append(metadata_table) | |
| story.append(Spacer(1, 0.3*inch)) | |
| # Query section | |
| story.append(Paragraph("Your Query", heading_style)) | |
| story.append(Paragraph(query, styles['Normal'])) | |
| story.append(Spacer(1, 0.2*inch)) | |
| # Advice section | |
| story.append(Paragraph("Recommendations", heading_style)) | |
| # Split advice into paragraphs | |
| advice_paragraphs = advice.split('\n\n') | |
| for para in advice_paragraphs: | |
| if para.strip(): | |
| story.append(Paragraph(para.strip(), styles['Normal'])) | |
| story.append(Spacer(1, 0.1*inch)) | |
| story.append(Spacer(1, 0.2*inch)) | |
| # Data section | |
| story.append(Paragraph("Data Sources", heading_style)) | |
| compiled_data = data.get('data', {}) | |
| for server_name, server_data in compiled_data.items(): | |
| # Server heading | |
| server_title = server_name.replace('_', ' ').title() | |
| story.append(Paragraph(f"<b>{server_title}</b>", styles['Normal'])) | |
| story.append(Spacer(1, 0.05*inch)) | |
| # Server data table | |
| server_items = [] | |
| if isinstance(server_data, dict): | |
| for key, value in server_data.items(): | |
| if isinstance(value, (str, int, float)): | |
| display_key = key.replace('_', ' ').title() | |
| server_items.append([display_key, str(value)]) | |
| if server_items: | |
| data_table = Table(server_items, colWidths=[2.5*inch, 3.5*inch]) | |
| data_table.setStyle(TableStyle([ | |
| ('BACKGROUND', (0, 0), (0, -1), colors.HexColor('#F1F8E9')), | |
| ('TEXTCOLOR', (0, 0), (-1, -1), colors.black), | |
| ('ALIGN', (0, 0), (-1, -1), 'LEFT'), | |
| ('FONTNAME', (0, 0), (0, -1), 'Helvetica'), | |
| ('FONTNAME', (1, 0), (1, -1), 'Helvetica'), | |
| ('FONTSIZE', (0, 0), (-1, -1), 9), | |
| ('BOTTOMPADDING', (0, 0), (-1, -1), 6), | |
| ('GRID', (0, 0), (-1, -1), 0.5, colors.grey) | |
| ])) | |
| story.append(data_table) | |
| story.append(Spacer(1, 0.15*inch)) | |
| # Footer | |
| story.append(Spacer(1, 0.3*inch)) | |
| footer_style = ParagraphStyle( | |
| 'Footer', | |
| parent=styles['Normal'], | |
| fontSize=9, | |
| textColor=colors.grey, | |
| alignment=TA_CENTER | |
| ) | |
| story.append(Paragraph("Generated by Farmer.Chat - Agricultural Intelligence System", footer_style)) | |
| story.append(Paragraph("Powered by Multi-stage MCP Pipeline", footer_style)) | |
| # Build PDF | |
| doc.build(story) | |
| return filepath |