Generate structured PDF documents with tables, sections, and scoring using Python libraries in execute_code_sandbox
This skill provides a reusable pattern for creating structured PDF documents such as checklists, reports, or assessments using Python in a sandboxed environment.
Use this workflow when you need to:
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
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 |
Use the execute_code_sandbox tool with Python code that:
/workspace/output.pdfARTIFACT_PATH: prefix for downloadDetermine workspace directory dynamically: Before generating PDFs, identify the correct output path:
# Option 1: Use current directory
WORKDIR=$(pwd)
# Option 2: Check common workspace locations
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(30, 8, str(score), 1)
self.ln()
# Create PDF
pdf = PDFChecklist()
pdf.add_page()
pdf.set_auto_page_break(auto=True, margin=15)
# Add sections
pdf.section_title('Evaluation Criteria')
pdf.add_checklist_item('Requirement 1', 'Must meet standard', 5)
pdf.add_checklist_item('Requirement 2', 'Should be complete', 4)
# Save
output_path = '/workspace/checklist.pdf'
pdf.output(output_path)
print(f'ARTIFACT_PATH:{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
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))
# Section header
story.append(Paragraph("Evaluation Summary", styles['Heading2']))
story.append(Spacer(1, 0.2*inch))
# Data table
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([
('BACKGROUND', (0, 0), (-1, 0), colors.grey),
('TEXTCOLOR', (0, 0), (-1, 0), colors.whitesmoke),
('ALIGN', (0, 0), (-1, -1), 'CENTER'),
('FONTNAME', (0, 0), (-1, 0), 'Helvetica-Bold'),
('BOTTOMPADDING', (0, 0), (-1, 0), 12),
('BACKGROUND', (0, 1), (-1, -1), colors.beige),
('GRID', (0, 0), (-1, -1), 1, colors.black)
]))
story.append(table)
doc.build(story)
print(f'ARTIFACT_PATH:{output_path}')
create_pdf_report('/workspace/report.pdf')
Call the tool:
execute_code_sandbox
code: <your PDF generation code from Step 2>
language: python
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'
# Your PDF generation code here
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.
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:
If using fallback execution, check multiple possible locations:
run_shell
command: find . -name "*.pdf" -type f -exec ls -lh {} \; 2>/dev/null
| 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 |
execute_code_sandbox fails after 2-3 attempts, switch to shell-based execution immediately/workspace/; use os.getcwd() or environment variables# Install library if needed
# !pip install fpdf2
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:
# Create script
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
# Run it
pip install fpdf2 -q 2>/dev/null; python /tmp/pdf_gen.py
execute_code_sandbox - Run Python code for PDF generationread_file - Verify PDF content (type: pdf)run_shell - Check file existence and sizecreate_file - Alternative for simple text files if PDF not required