Generate beautiful PDF reports from data using LLMs, Mermaid diagrams, and Chart.js visualizations
Project description
text2report
Generate beautiful PDF reports from data using LLMs, Mermaid diagrams, and Chart.js visualizations.
📚 Documentation
- Complete Guide - Comprehensive documentation with all functions, use cases, and examples
- Quick Reference - One-page cheat sheet for common tasks
- Custom Prompts Guide - Create custom prompt templates for reports and insights
- Anti-Hallucination Guide - Ensure data fidelity in reports
- Packaging Guide - Build and distribute the package
Features
- 📊 Automatic Visualizations: Generates Chart.js charts and Mermaid diagrams from your data
- 🤖 Multi-LLM Support: Works with Ollama (local/free), OpenAI, and Azure OpenAI
- 🎯 Behavior Customization: Tailor reports for different audiences (executives, technical, analysts)
- 📄 PDF Generation: High-quality PDF output via Playwright
- ⚡ Quick Insights: Fast summary generation for immediate feedback
- 🎨 Professional Styling: Clean, modern report layouts
- 🔧 Flexible Configuration: Presets, custom templates, or full programmatic control
Installation
1. Install the package
pip install -e .
2. Install Playwright browsers
playwright install chromium
3. Set up an LLM Provider
Choose one of the following:
Option A: Ollama (Free, runs locally)
# Install from https://ollama.ai
ollama pull gpt-oss:20b # or your preferred model
ollama serve
Option B: OpenAI
# Get API key from https://platform.openai.com
export REPORT_LLM_PROVIDER=openai
export REPORT_LLM_API_KEY=sk-proj-your-key-here
export REPORT_LLM_MODEL=gpt-4-turbo-preview
Option C: Azure OpenAI
# Get credentials from Azure portal
export REPORT_LLM_PROVIDER=azure
export REPORT_LLM_BASE_URL=https://your-resource.openai.azure.com
export REPORT_LLM_MODEL=your-deployment-name
export REPORT_LLM_API_KEY=your-azure-key
Quick Start
from text2report import generate_report, generate_quick_insights
# Your data (can be dict, list, string, or any JSON-serializable object)
data = {
"sales": [
{"name": "Alice", "revenue": 50000},
{"name": "Bob", "revenue": 75000},
{"name": "Charlie", "revenue": 62000}
]
}
# Generate quick insights (fast, 3-5 bullet points)
insights = generate_quick_insights(
data=data,
question="Who are the top performers?"
)
print(insights)
# Generate full PDF report
pdf_path = generate_report(
data=data,
question="Analyze sales performance and provide recommendations",
output_path="sales_report.pdf" # Optional, auto-generates if not provided
)
print(f"Report generated: {pdf_path}")
Behavior Customization 🎯
NEW: Customize report output for different audiences, styles, and purposes without writing prompts!
Quick Start with Presets
Use pre-configured templates for common scenarios:
from text2report import generate_report
# Executive summary - concise, high-level, business-focused
pdf_path = generate_report(
data=sales_data,
question="Q4 performance analysis",
preset="executive_summary"
)
# Technical deep dive - detailed, implementation-focused
pdf_path = generate_report(
data=system_metrics,
question="System performance analysis",
preset="technical_deep_dive"
)
# Data analysis - statistical, methodology-focused
pdf_path = generate_report(
data=experiment_results,
question="A/B test results",
preset="data_analysis"
)
Available Presets:
executive_summary- High-level business summary for C-suitetechnical_deep_dive- Detailed technical analysis for engineersdata_analysis- Statistical analysis for data scientistssales_presentation- Persuasive report for sales/marketingquick_overview- Fast, scannable summary for general audience
Fine-Grained Control
Customize individual aspects:
# Customize audience, style, and tone
pdf_path = generate_report(
data=data,
question="Analyze user engagement",
audience="executives", # executives|technical|analysts|general
style="concise", # concise|detailed|visual_heavy
tone="formal", # formal|persuasive|casual
focus=["metrics", "recommendations"] # What to emphasize
)
Using ReportConfig (Advanced)
For maximum control and type safety:
from text2report import (
generate_report,
ReportConfig,
Audience,
Style,
Tone,
FocusArea
)
# Build custom configuration
config = ReportConfig(
audience=Audience.TECHNICAL,
style=Style.DETAILED,
tone=Tone.FORMAL,
focus=[FocusArea.INSIGHTS, FocusArea.TRENDS]
)
pdf_path = generate_report(
data=data,
question="System performance trends",
config=config
)
# Or use a preset and override specific values
config = ReportConfig.from_preset(
Preset.EXECUTIVE_SUMMARY,
tone=Tone.PERSUASIVE # Override the preset's tone
)
Behavior Options Reference
Audiences
executives- C-level focus: ROI, strategic implications, high-level recommendationstechnical- Engineering focus: implementation details, architecture, methodologiesanalysts- Data focus: statistical significance, methodology, data qualitygeneral- Accessible language, balanced depth, clear explanations
Styles
concise- 1-2 pages, bullet points, key highlights onlydetailed- 3-5 pages, comprehensive analysis with contextvisual_heavy- Chart-first approach, minimal text, infographic style
Tones
formal- Professional, objective, academic languagepersuasive- Action-oriented, compelling, results-focusedcasual- Friendly, conversational, accessible
Focus Areas
metrics- Prioritize quantitative data and KPIsrecommendations- Emphasize actionable next stepstrends- Focus on patterns and future projectionscomparisons- Highlight comparative analysisinsights- Uncover hidden patterns and surprises
Custom Templates (Expert)
Create your own prompt templates for complete control over report generation.
See the Custom Prompts Guide for complete documentation.
from pathlib import Path
# Option 1: Custom YAML template file (recommended)
config = ReportConfig(
template_file=Path("./my_templates.yaml"),
template_name="MY_CUSTOM_TEMPLATE"
)
pdf_path = generate_report(data, question="...", config=config)
# Option 2: Inline custom prompt (quick experiments)
custom_prompt = """
Create a report focusing on {question}.
Data: {answer}
Make it extremely concise with only bullet points.
"""
config = ReportConfig(custom_prompt=custom_prompt)
pdf_path = generate_report(data, question="...", config=config)
Examples:
- See
examples/07_custom_prompts.pyfor working examples - See
examples/custom_templates.yamlfor template file structure
Configuration
LLM Provider Setup
text2report supports multiple LLM providers: Ollama (local), OpenAI, and Azure OpenAI.
Option 1: Ollama (Default - Free & Local)
# Using Ollama (default configuration)
REPORT_LLM_PROVIDER=ollama
REPORT_LLM_BASE_URL=http://localhost:11434
REPORT_LLM_MODEL=gpt-oss:20b
REPORT_LLM_TEMPERATURE=0.3
REPORT_LLM_MAX_TOKENS=4096
# PDF Configuration
REPORT_PDF_OUTPUT_DIR=reports
Setup Ollama:
# Install Ollama from https://ollama.ai
ollama pull gpt-oss:20b # or any other model
ollama serve
Option 2: OpenAI
# Using OpenAI
REPORT_LLM_PROVIDER=openai
REPORT_LLM_BASE_URL=https://api.openai.com # Optional, this is the default
REPORT_LLM_MODEL=gpt-4-turbo-preview
REPORT_LLM_API_KEY=sk-proj-your-api-key-here
REPORT_LLM_TEMPERATURE=0.3
REPORT_LLM_MAX_TOKENS=4096
# PDF Configuration
REPORT_PDF_OUTPUT_DIR=reports
Option 3: Azure OpenAI
# Using Azure OpenAI
REPORT_LLM_PROVIDER=azure
REPORT_LLM_BASE_URL=https://your-resource.openai.azure.com
REPORT_LLM_MODEL=your-deployment-name
REPORT_LLM_API_KEY=your-azure-api-key
REPORT_LLM_TEMPERATURE=0.3
REPORT_LLM_MAX_TOKENS=4096
# PDF Configuration
REPORT_PDF_OUTPUT_DIR=reports
Programmatic Configuration
You can also configure settings in code:
from text2report.config import settings
# Configure for OpenAI
settings.llm_provider = "openai"
settings.llm_model = "gpt-4-turbo-preview"
settings.llm_api_key = "sk-proj-..."
# Or for Ollama
settings.llm_provider = "ollama"
settings.llm_model = "llama2:13b"
settings.llm_temperature = 0.5
Legacy Configuration (Deprecated)
Old REPORT_OLLAMA_* settings still work but will show deprecation warnings:
# DEPRECATED - still works but use REPORT_LLM_* instead
REPORT_OLLAMA_HOST=http://localhost:11434
REPORT_OLLAMA_MODEL=gpt-oss:20b
The system will automatically migrate these to the new settings.
API Reference
generate_report()
Generate a complete PDF report with visualizations and behavior customization.
def generate_report(
data: Any,
output_path: str | Path | None = None,
question: str | None = None,
charts: list | None = None,
# Behavior customization (NEW)
config: ReportConfig | None = None,
audience: str | None = None,
style: str | None = None,
tone: str | None = None,
focus: list[str] | None = None,
preset: str | None = None,
) -> str:
"""
Args:
data: Input data (text, dict, list, JSON, etc.)
output_path: Output PDF path (auto-generated if None)
question: User's question to guide report generation
charts: Deprecated (LLM generates visualizations automatically)
# Behavior Customization
config: ReportConfig object for complete control
audience: Target audience (executives|technical|analysts|general)
style: Report style (concise|detailed|visual_heavy)
tone: Report tone (formal|persuasive|casual)
focus: List of focus areas (metrics, recommendations, trends, etc.)
preset: Use preset config (executive_summary, technical_deep_dive, etc.)
Returns:
Path to generated PDF file
"""
Examples:
# Basic usage
pdf_path = generate_report(
data={"temperature": [20, 22, 25, 23, 21]},
question="Analyze temperature trends this week"
)
# With behavior customization
pdf_path = generate_report(
data=sales_data,
question="Q4 analysis",
audience="executives",
style="concise",
tone="formal"
)
# Using a preset
pdf_path = generate_report(
data=data,
question="System performance",
preset="technical_deep_dive"
)
generate_quick_insights()
Generate quick bullet-point insights (fast, 3-5 seconds).
def generate_quick_insights(
data: Any,
question: str | None = None,
) -> str:
"""
Args:
data: Input data (text, dict, list, JSON, etc.)
question: User's question
Returns:
String with 3-5 bullet point insights
"""
Example:
insights = generate_quick_insights(
data=user_feedback_data,
question="What are the main themes in user feedback?"
)
Report Features
The generated reports automatically include:
📊 Visualizations
The LLM intelligently chooses appropriate visualizations:
- Chart.js Charts: Bar charts, line charts, pie charts, radar charts
- Mermaid Diagrams: Flowcharts, process diagrams, relationships
📝 Report Structure
- Title & Summary: Clear overview with key findings
- Visualizations: Automatically generated charts and diagrams
- Detailed Analysis: In-depth breakdown of the data
- Tables: Raw data presented in clean tables
- Recommendations: Actionable insights
🎨 Styling
- Professional typography and spacing
- Color-coded sections and headers
- Responsive chart sizing
- Page break optimization
Advanced Usage
Custom Output Directory
from pathlib import Path
output_dir = Path("./monthly_reports")
output_dir.mkdir(exist_ok=True)
pdf_path = generate_report(
data=monthly_data,
output_path=output_dir / "january_2024.pdf",
question="Monthly performance summary"
)
Batch Report Generation
datasets = {
"Q1": q1_data,
"Q2": q2_data,
"Q3": q3_data,
"Q4": q4_data,
}
for quarter, data in datasets.items():
pdf_path = generate_report(
data=data,
question=f"Analyze {quarter} performance",
output_path=f"reports/{quarter}_report.pdf"
)
print(f"Generated {quarter}: {pdf_path}")
Real-World Use Cases
Board Meeting Executive Summary
# Generate high-level summary for board presentation
pdf_path = generate_report(
data=company_metrics,
question="Q4 2024 company performance and 2025 outlook",
preset="executive_summary"
)
Engineering Incident Report
# Detailed technical postmortem
pdf_path = generate_report(
data=incident_logs,
question="Database outage root cause analysis",
audience="technical",
style="detailed",
focus=["insights", "recommendations"]
)
A/B Test Results for Data Team
# Statistical analysis with methodology
pdf_path = generate_report(
data=ab_test_results,
question="Checkout flow A/B test analysis",
preset="data_analysis"
)
Sales Proposal
# Persuasive presentation with visuals
pdf_path = generate_report(
data=roi_analysis,
question="ROI projection for enterprise plan",
audience="general",
style="visual_heavy",
tone="persuasive",
focus=["metrics", "recommendations"]
)
Requirements
- Python >= 3.10
- LLM Provider (choose one):
- Dependencies (auto-installed):
- markdown
- requests
- pyyaml
- playwright
- pydantic >= 2.0
- pydantic-settings
Project Structure
text2report/
├── generator.py # Main orchestration
├── config/ # Configuration management
├── markdown_llm.py # LLM integration
├── html_renderer.py # Markdown → HTML conversion
├── pdf_renderer.py # HTML → PDF conversion
├── prompts.py # Prompt template management
├── styles.py # CSS styling
├── serializers.py # Data serialization
├── regex.py # Pattern matching
└── utils/ # Utility functions
Troubleshooting
LLM Provider Issues
Ollama Connection Errors
# Check if Ollama is running
curl http://localhost:11434/api/tags
# Start Ollama (if not running)
ollama serve
# Check environment
echo $REPORT_LLM_PROVIDER # should be "ollama" or empty
OpenAI API Errors
# Verify API key is set
echo $REPORT_LLM_API_KEY
# Test API connection
curl https://api.openai.com/v1/models \
-H "Authorization: Bearer $REPORT_LLM_API_KEY"
Azure OpenAI Errors
# Verify all Azure settings
echo $REPORT_LLM_PROVIDER # should be "azure"
echo $REPORT_LLM_BASE_URL
echo $REPORT_LLM_MODEL
echo $REPORT_LLM_API_KEY
Provider Configuration
# Check current provider in Python
from text2report.config import settings
print(f"Provider: {settings.llm_provider}")
print(f"Model: {settings.llm_model}")
print(f"Base URL: {settings.llm_base_url}")
Playwright Errors
# Reinstall Chromium
playwright install --force chromium
# Check Playwright installation
playwright --version
Import Errors
# Reinstall package in development mode
pip install -e .
License
MIT
Contributing
Contributions welcome! Please feel free to submit issues and pull requests.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file text2report-1.0.tar.gz.
File metadata
- Download URL: text2report-1.0.tar.gz
- Upload date:
- Size: 42.4 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.10.6
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
08a5c797a2dcd1f6b49816fb9d0ddf4179f181385911351328fef5d0ab705e4e
|
|
| MD5 |
0667010e7965079c8e37798471d103f7
|
|
| BLAKE2b-256 |
029220b94111a18e9c34bc0ed92309492436cf8287e9f3e14a8e0fd502891518
|
File details
Details for the file text2report-1.0-py3-none-any.whl.
File metadata
- Download URL: text2report-1.0-py3-none-any.whl
- Upload date:
- Size: 29.1 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.10.6
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
a52c2e94ddc671d297f6a08bf6fbd30fc60acf30969c41b3dadf1a5de23530fd
|
|
| MD5 |
d09883f998993014f1dd3a4716d1ba50
|
|
| BLAKE2b-256 |
eeb16387218e6d6a921ca5d1d98bc34232818b7044cbd505283df4755f6bb9e7
|