pypdf-batch-pdf-processing-pipeline

Sub-skill of pypdf: Batch PDF Processing Pipeline.

5 stars

Best use case

pypdf-batch-pdf-processing-pipeline is best used when you need a repeatable AI agent workflow instead of a one-off prompt.

Sub-skill of pypdf: Batch PDF Processing Pipeline.

Teams using pypdf-batch-pdf-processing-pipeline should expect a more consistent output, faster repeated execution, less prompt rewriting.

When to use this skill

  • You want a reusable workflow that can be run more than once with consistent structure.

When not to use this skill

  • You only need a quick one-off answer and do not need a reusable workflow.
  • You cannot install or maintain the underlying files, dependencies, or repository context.

Installation

Claude Code / Cursor / Codex

$curl -o ~/.claude/skills/batch-pdf-processing-pipeline/SKILL.md --create-dirs "https://raw.githubusercontent.com/vamseeachanta/workspace-hub/main/.agents/skills/_archive/data/office/pypdf/batch-pdf-processing-pipeline/SKILL.md"

Manual Installation

  1. Download SKILL.md from GitHub
  2. Place it in .claude/skills/batch-pdf-processing-pipeline/SKILL.md inside your project
  3. Restart your AI agent — it will auto-discover the skill

How pypdf-batch-pdf-processing-pipeline Compares

Feature / Agentpypdf-batch-pdf-processing-pipelineStandard Approach
Platform SupportNot specifiedLimited / Varies
Context Awareness High Baseline
Installation ComplexityUnknownN/A

Frequently Asked Questions

What does this skill do?

Sub-skill of pypdf: Batch PDF Processing Pipeline.

Where can I find the source code?

You can find the source code on GitHub using the link provided at the top of the page.

SKILL.md Source

# Batch PDF Processing Pipeline

## Batch PDF Processing Pipeline


```python
"""
Batch process PDFs with configurable operations.
"""
from pypdf import PdfReader, PdfWriter, PdfMerger
from pathlib import Path
from typing import List, Dict, Any, Callable
from concurrent.futures import ThreadPoolExecutor, as_completed
import logging

logger = logging.getLogger(__name__)

class PDFProcessor:
    """Batch PDF processing with configurable operations."""

    def __init__(self, output_dir: str):
        self.output_dir = Path(output_dir)
        self.output_dir.mkdir(parents=True, exist_ok=True)

    def process_batch(
        self,
        pdf_files: List[str],
        operations: List[Dict[str, Any]],
        parallel: bool = False
    ) -> List[Dict]:
        """Process multiple PDFs with specified operations.

        Args:
            pdf_files: List of PDF file paths
            operations: List of operation configs
            parallel: Run in parallel if True
        """
        results = []

        if parallel:
            with ThreadPoolExecutor(max_workers=4) as executor:
                futures = {
                    executor.submit(self._process_single, f, operations): f
                    for f in pdf_files
                }
                for future in as_completed(futures):
                    results.append(future.result())
        else:
            for pdf_file in pdf_files:
                results.append(self._process_single(pdf_file, operations))

        return results

    def _process_single(
        self,
        pdf_path: str,
        operations: List[Dict[str, Any]]
    ) -> Dict:
        """Process single PDF with operations."""
        result = {'file': pdf_path, 'success': True, 'operations': []}

        try:
            current_path = pdf_path

            for op in operations:
                op_name = op['name']
                op_params = op.get('params', {})

                output_path = str(
                    self.output_dir / f"{Path(current_path).stem}_{op_name}.pdf"
                )

                if op_name == 'rotate':
                    self._rotate(current_path, output_path, **op_params)
                elif op_name == 'watermark':
                    self._watermark(current_path, output_path, **op_params)
                elif op_name == 'extract_pages':
                    self._extract_pages(current_path, output_path, **op_params)
                elif op_name == 'encrypt':
                    self._encrypt(current_path, output_path, **op_params)

                result['operations'].append({
                    'name': op_name,
                    'output': output_path
                })
                current_path = output_path

            result['final_output'] = current_path

        except Exception as e:
            result['success'] = False
            result['error'] = str(e)
            logger.exception(f"Failed to process {pdf_path}")

        return result

    def _rotate(self, input_path, output_path, rotation=90, pages=None):
        reader = PdfReader(input_path)
        writer = PdfWriter()
        for i, page in enumerate(reader.pages):
            if pages is None or i in pages:
                page.rotate(rotation)
            writer.add_page(page)
        writer.write(output_path)

    def _watermark(self, input_path, output_path, watermark_path):
        reader = PdfReader(input_path)
        watermark = PdfReader(watermark_path).pages[0]
        writer = PdfWriter()
        for page in reader.pages:
            page.merge_page(watermark)
            writer.add_page(page)
        writer.write(output_path)

    def _extract_pages(self, input_path, output_path, pages):
        reader = PdfReader(input_path)
        writer = PdfWriter()
        for p in pages:
            if 0 <= p < len(reader.pages):
                writer.add_page(reader.pages[p])
        writer.write(output_path)

    def _encrypt(self, input_path, output_path, password):
        reader = PdfReader(input_path)
        writer = PdfWriter()
        for page in reader.pages:
            writer.add_page(page)
        writer.encrypt(password)
        writer.write(output_path)


# Example usage
# processor = PDFProcessor('processed_output/')
# results = processor.process_batch(
#     ['doc1.pdf', 'doc2.pdf', 'doc3.pdf'],
#     [
#         {'name': 'rotate', 'params': {'rotation': 90}},
#         {'name': 'watermark', 'params': {'watermark_path': 'watermark.pdf'}},
#         {'name': 'encrypt', 'params': {'password': 'secure123'}}
#     ],
#     parallel=True
# )
```

Related Skills

teams-meeting-pipeline

5
from vamseeachanta/workspace-hub

Operate the Teams meeting summary pipeline via Hermes CLI — summarize meetings, inspect pipeline status, replay jobs, manage Microsoft Graph subscriptions.

solidworks-to-blender-pipeline

5
from vamseeachanta/workspace-hub

Use when converting SolidWorks .sldprt/.sldasm geometry to Blender for rendering, animation, or visualization, including questions about STEP export settings, FreeCAD as a bridge, or which mesh format (STL/OBJ/GLTF) to choose.

multi-role-agent-contract-review-pipeline

5
from vamseeachanta/workspace-hub

Execute a 4-role agent team (Planner/Architect/Reviewer/Integrator) pipeline for self-reviewing knowledge artifacts before delivery

batch-syntax-repair-from-injection-errors

5
from vamseeachanta/workspace-hub

Detect and fix systematic syntax errors caused by line-injection scripts that split multiline constructs

batch-syntax-fix-with-regex-line-based-fallback

5
from vamseeachanta/workspace-hub

Fix repeated syntax errors across many files using regex, then fall back to line-based parsing when regex fails

batch-syntax-fix-regex-iteration

5
from vamseeachanta/workspace-hub

Iteratively fix widespread syntax errors across many files using regex refinement when initial patterns fail

batch-syntax-fix-pattern

5
from vamseeachanta/workspace-hub

Identify and repair cascading import/syntax errors across multiple files using regex-based line-scanning and verification

batch-regex-fix-import-syntax

5
from vamseeachanta/workspace-hub

Detect and fix mid-import blank-line syntax breaks across multiple files using line-based regex

gtm-prospect-pipeline-phased-execution

5
from vamseeachanta/workspace-hub

Phased execution pattern for

closure-first-overnight-batch

5
from vamseeachanta/workspace-hub

Run a high-leverage overnight batch by clearing stale-open approved issues first, converting shared blockers into tracked issues, and reserving only one lane for true implementation.

workspace-hub-batch-issue-execution

5
from vamseeachanta/workspace-hub

Deprecated alias for gh-work-execution.

overnight-verify-close-batch

5
from vamseeachanta/workspace-hub

Build overnight parallel batches that close stale-open GitHub issues by proving landed work already satisfies the issue, instead of wasting implementation lanes on redoing completed work.