| name | pdf-checklist-workflow |
| description | Generate structured PDF documents with tables, sections, and scoring using Python libraries in execute_code_sandbox |
PDF Checklist/Report Generation Workflow
This skill provides a reusable pattern for creating structured PDF documents such as checklists, reports, or assessments using Python in a sandboxed environment.
Overview
Use this workflow when you need to:
- Generate PDF checklists, reports, or assessments
- Create structured documents with tables, sections, and headers
- Include scoring criteria or evaluation frameworks
- Produce downloadable artifacts for users
Primary method: Use execute_code_sandbox for Python PDF generation
Fallback method: If execute_code_sandbox fails, create and run Python scripts via shell commands
Step-by-Step Instructions
Step 1: Choose a PDF Library
Select a Python library based on your needs:
| Library | Best For | Complexity |
|---|
reportlab | Professional reports, complex layouts | Medium |
fpdf / fpdf2 | Simple documents, quick generation | Low |
matplotlib | Charts, graphs, visual elements | Medium |
Step 2: Write PDF Generation Code in execute_code_sandbox
Use the execute_code_sandbox tool with Python code that:
- Imports the chosen PDF library
- Defines document structure (title, sections, tables)
- Adds content (text, tables, scores, criteria)
- Saves to a file path like
/workspace/output.pdf
- Outputs the path using
ARTIFACT_PATH: prefix for download
Determine workspace directory dynamically:
Before generating PDFs, identify the correct output path:
WORKDIR=$(pwd)
if [ -d "/workspace" ]; then WORKDIR="/workspace"
elif [ -d "$HOME/workspace" ]; then WORKDIR="$HOME/workspace"
else WORKDIR=$(pwd); fi
In Python code, use environment variables or dynamic path detection:
import os
workspace = os.environ.get('WORKSPACE', os.getcwd())
output_path = os.path.join(workspace, 'output.pdf')
Example using fpdf2:
from fpdf import FPDF
class PDFChecklist(FPDF):
def header(self):
self.set_font('Arial', 'B', 16)
self.cell(0, 10, 'Assessment Checklist', 0, 1, 'C')
self.ln(10)
def section_title(self, title):
self.set_font('Arial', 'B', 12)
self.cell(0, 10, title, 0, 1, 'L')
self.ln(5)
def add_checklist_item(self, item, criteria, score):
self.set_font('Arial', '', 10)
self.cell(100, 8, item, 1)
self.cell(60, 8, criteria, 1)
self.cell(, , (score), )
.ln()
pdf = PDFChecklist()
pdf.add_page()
pdf.set_auto_page_break(auto=, margin=)
pdf.section_title()
pdf.add_checklist_item(, , )
pdf.add_checklist_item(, , )
output_path =
pdf.output(output_path)
()
Example using reportlab (more professional):
from reportlab.lib import colors
from reportlab.lib.pagesizes import letter
from reportlab.platypus import SimpleDocTemplate, Paragraph, Spacer, Table, TableStyle
from reportlab.lib.styles import getSampleStyleSheet, ParagraphStyle
from reportlab.lib.units import inch
def create_pdf_report(output_path):
doc = SimpleDocTemplate(output_path, pagesize=letter)
styles = getSampleStyleSheet()
story = []
title_style = ParagraphStyle('CustomTitle', parent=styles['Heading1'],
fontSize=18, spaceAfter=30, alignment=1)
story.append(Paragraph("Assessment Report", title_style))
story.append(Spacer(1, 0.3*inch))
story.append(Paragraph("Evaluation Summary", styles['Heading2']))
story.append(Spacer(1, 0.2*inch))
data = [
['Criteria', 'Description', 'Score'],
['Completeness', 'All sections filled', '8/10'],
['Accuracy', 'Information verified', '9/10'],
['Clarity', 'Easy to understand', '7/10']
]
table = Table(data, colWidths=[2*inch, 2.5*inch, 1*inch])
table.setStyle(TableStyle([
(, (, ), (-, ), colors.grey),
(, (, ), (-, ), colors.whitesmoke),
(, (, ), (-, -), ),
(, (, ), (-, ), ),
(, (, ), (-, ), ),
(, (, ), (-, -), colors.beige),
(, (, ), (-, -), , colors.black)
]))
story.append(table)
doc.build(story)
()
create_pdf_report()
Step 3: Execute the Code
Call the tool:
execute_code_sandbox
code: <your PDF generation code from Step 2>
language: python
Step 3b: Fallback - Shell-Based Execution
If execute_code_sandbox fails repeatedly (e.g., "unknown error", timeouts), use this fallback:
1. Create the Python script via heredoc:
cat > /tmp/generate_pdf.py << 'EOF'
from fpdf import FPDF
import os
workspace = os.environ.get('WORKSPACE', os.getcwd())
output_path = os.path.join(workspace, 'checklist.pdf')
pdf = FPDF()
pdf.add_page()
pdf.set_font('Arial', 'B', 16)
pdf.cell(0, 10, 'Checklist', 0, 1, 'C')
pdf.output(output_path)
print(f'ARTIFACT_PATH:{output_path}')
EOF
2. Install required library if needed:
pip install fpdf2 --quiet 2>/dev/null || pip install fpdf2
3. Execute the script:
python /tmp/generate_pdf.py
4. Verify the output file was created:
ls -lh $(pwd)/*.pdf 2>/dev/null || ls -lh /workspace/*.pdf 2>/dev/null
Important for fallback: When using shell execution, ensure the script outputs the ARTIFACT_PATH so the file can be downloaded. Adjust the path based on where the file was actually created.
Step 4: Verify Output
After execution, verify the PDF was created:
Option A - Use read_file:
read_file
filetype: pdf
file_path: /workspace/output.pdf
Option B - Use shell inspection:
run_shell
command: ls -lh /workspace/*.pdf
Check that:
- File exists and has reasonable size (>1KB)
- No error messages in execution output
- ARTIFACT_PATH was correctly output for download
If using fallback execution, check multiple possible locations:
run_shell
command: find . -name "*.pdf" -type f -exec ls -lh {} \; 2>/dev/null
Step 5: Handle Common Issues
| Issue | Solution |
|---|
| Library not installed | Add !pip install fpdf2 or !pip install reportlab at code start |
| Font errors | Use standard fonts (Arial, Helvetica, Courier) |
| File not found | Ensure path is /workspace/filename.pdf |
| Empty PDF | Check that pdf.output() or doc.build() is called |
| Encoding issues | Use ASCII text or handle unicode properly |
execute_code_sandbox fails | Switch to shell-based fallback (Step 3b): create script with heredoc, run with python |
| Wrong workspace path | Use dynamic detection: os.getcwd() or $(pwd) instead of hardcoded /workspace/ |
| Permission errors | Write to current directory or /tmp/ then move file |
Best Practices
- Keep it simple first - Start with basic text, add tables/graphics later
- Use ARTIFACT_PATH prefix - Ensures the file is downloadable
- Test incrementally - Generate a minimal PDF before adding complexity
- Include error handling - Wrap file operations in try/except blocks
- Set appropriate margins - Prevent content from being cut off
- Have a fallback ready - If
execute_code_sandbox fails after 2-3 attempts, switch to shell-based execution immediately
- Detect workspace dynamically - Don't assume
/workspace/; use os.getcwd() or environment variables
Template for Quick Start
from fpdf import FPDF
import os
pdf = FPDF()
pdf.add_page()
pdf.set_font('Arial', 'B', 16)
pdf.cell(0, 10, 'Your Title Here', 0, 1, 'C')
pdf.ln(10)
pdf.set_font('Arial', '', 12)
pdf.multi_cell(0, 8, 'Your content here...')
workspace = os.environ.get('WORKSPACE', os.getcwd())
output_path = os.path.join(workspace, 'output.pdf')
pdf.output(output_path)
print(f'ARTIFACT_PATH:{output_path}')
Shell fallback template:
cat > /tmp/pdf_gen.py << 'PYEOF'
from fpdf import FPDF
import os
pdf = FPDF()
pdf.add_page()
pdf.set_font('Arial', 'B', 16)
pdf.cell(0, 10, 'Title', 0, 1, 'C')
workspace = os.environ.get('WORKSPACE', os.getcwd())
pdf.output(os.path.join(workspace, 'output.pdf'))
print(f'ARTIFACT_PATH:{workspace}/output.pdf')
PYEOF
pip install fpdf2 -q 2>/dev/null; python /tmp/pdf_gen.py
Related Tools
execute_code_sandbox - Run Python code for PDF generation
read_file - Verify PDF content (type: pdf)
run_shell - Check file existence and size
create_file - Alternative for simple text files if PDF not required