CtrlK
BlogDocsLog inGet started
Tessl Logo

pdf-checklist-workflow

Generate structured PDF documents with tables, sections, and scoring using Python libraries in execute_code_sandbox

60

Quality

68%

Does it follow best practices?

Run evals on this skill

Adds up to 20 points to the overall score

View guide

SecuritybySnyk

Passed

No findings from the security scan

Fix and improve this skill with Tessl

tessl review fix ./benchmarks/gdpval/skills/pdf-checklist-workflow/SKILL.md
SKILL.md
Quality
Evals
Security

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:

LibraryBest ForComplexity
reportlabProfessional reports, complex layoutsMedium
fpdf / fpdf2Simple documents, quick generationLow
matplotlibCharts, graphs, visual elementsMedium

Step 2: Write PDF Generation Code in execute_code_sandbox

Use the execute_code_sandbox tool with Python code that:

  1. Imports the chosen PDF library
  2. Defines document structure (title, sections, tables)
  3. Adds content (text, tables, scores, criteria)
  4. Saves to a file path like /workspace/output.pdf
  5. Outputs the path using ARTIFACT_PATH: prefix for download

Determine 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')

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'
# 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.

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

IssueSolution
Library not installedAdd !pip install fpdf2 or !pip install reportlab at code start
Font errorsUse standard fonts (Arial, Helvetica, Courier)
File not foundEnsure path is /workspace/filename.pdf
Empty PDFCheck that pdf.output() or doc.build() is called
Encoding issuesUse ASCII text or handle unicode properly
execute_code_sandbox failsSwitch to shell-based fallback (Step 3b): create script with heredoc, run with python
Wrong workspace pathUse dynamic detection: os.getcwd() or $(pwd) instead of hardcoded /workspace/
Permission errorsWrite to current directory or /tmp/ then move file

Best Practices

  1. Keep it simple first - Start with basic text, add tables/graphics later
  2. Use ARTIFACT_PATH prefix - Ensures the file is downloadable
  3. Test incrementally - Generate a minimal PDF before adding complexity
  4. Include error handling - Wrap file operations in try/except blocks
  5. Set appropriate margins - Prevent content from being cut off
  6. Have a fallback ready - If execute_code_sandbox fails after 2-3 attempts, switch to shell-based execution immediately
  7. Detect workspace dynamically - Don't assume /workspace/; use os.getcwd() or environment variables

Template for Quick Start

# 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

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
Repository
HKUDS/OpenSpace
Last updated
First committed

Is this your skill?

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.