Generate structured PDF documents with tables, sections, and scoring using Python libraries in execute_code_sandbox
60
68%
Does it follow best practices?
Run evals on this skill
Adds up to 20 points to the overall score
View guide
Passed
No findings from the security scan
Fix and improve this skill with Tessl
tessl review fix ./benchmarks/gdpval/skills/pdf-checklist-workflow/SKILL.mdThis 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); fiIn 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: pythonIf 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}')
EOF2. Install required library if needed:
pip install fpdf2 --quiet 2>/dev/null || pip install fpdf23. Execute the script:
python /tmp/generate_pdf.py4. Verify the output file was created:
ls -lh $(pwd)/*.pdf 2>/dev/null || ls -lh /workspace/*.pdf 2>/dev/nullImportant 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.pdfOption B - Use shell inspection:
run_shell
command: ls -lh /workspace/*.pdfCheck 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.pyexecute_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 requiredc5a9c4b
If you maintain this skill, you can claim it as your own. Once claimed, you can manage eval scenarios, bundle related skills, attach documentation or rules, and ensure cross-agent compatibility.