OpenSpace pdf-checklist-workflow
Generate structured PDF documents with tables, sections, and scoring using Python libraries in execute_code_sandbox
git clone https://github.com/HKUDS/OpenSpace
T=$(mktemp -d) && git clone --depth=1 https://github.com/HKUDS/OpenSpace "$T" && mkdir -p ~/.claude/skills && cp -r "$T/gdpval_bench/skills/pdf-checklist-workflow" ~/.claude/skills/hkuds-openspace-pdf-checklist-workflow && rm -rf "$T"
gdpval_bench/skills/pdf-checklist-workflow/SKILL.mdPDF 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 |
|---|---|---|
| Professional reports, complex layouts | Medium |
/ | Simple documents, quick generation | Low |
| 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
prefix for downloadARTIFACT_PATH:
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
| Issue | Solution |
|---|---|
| Library not installed | Add or at code start |
| Font errors | Use standard fonts (Arial, Helvetica, Courier) |
| File not found | Ensure path is |
| Empty PDF | Check that or is called |
| Encoding issues | Use ASCII text or handle unicode properly |
fails | Switch to shell-based fallback (Step 3b): create script with heredoc, run with |
| Wrong workspace path | Use dynamic detection: or instead of hardcoded |
| Permission errors | Write to current directory or 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
fails after 2-3 attempts, switch to shell-based execution immediatelyexecute_code_sandbox - Detect workspace dynamically - Don't assume
; use/workspace/
or environment variablesos.getcwd()
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
- Run Python code for PDF generationexecute_code_sandbox
- Verify PDF content (type: pdf)read_file
- Check file existence and sizerun_shell
- Alternative for simple text files if PDF not requiredcreate_file