{"id":13496556,"url":"https://github.com/pikepdf/pikepdf","last_synced_at":"2026-10-19T07:21:42.794Z","repository":{"id":37484299,"uuid":"103577933","full_name":"pikepdf/pikepdf","owner":"pikepdf","description":"A Python library for reading and writing PDF, powered by QPDF","archived":false,"fork":false,"pushed_at":"2026-10-11T23:08:03.000Z","size":17706,"stargazers_count":2815,"open_issues_count":17,"forks_count":236,"subscribers_count":37,"default_branch":"main","last_synced_at":"2026-10-13T06:51:25.265Z","etag":null,"topics":["existing-pdfs","pdf","pdf-generation","pdf-manipulation","pikepdf","pypdf2","python","qpdf"],"latest_commit_sha":null,"homepage":"https://pikepdf.readthedocs.io/","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mpl-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/pikepdf.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":"CONTRIBUTING.md","funding":".github/FUNDING.yml","license":"LICENSE.txt","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"claude":null,"gemini":null,"cursor":null,"copilot":null,"dco":null,"cla":null,"disclosure":null},"funding":{"github":null,"patreon":null,"open_collective":"james-barlow","ko_fi":null,"tidelift":null,"community_bridge":null,"liberapay":null,"issuehunt":null,"otechie":null,"custom":null}},"created_at":"2017-09-14T20:22:29.000Z","updated_at":"2026-10-13T01:56:50.000Z","dependencies_parsed_at":"2026-09-28T00:34:53.536Z","dependency_job_id":null,"html_url":"https://github.com/pikepdf/pikepdf","commit_stats":{"total_commits":2647,"total_committers":51,"mean_commits":51.90196078431372,"dds":"0.43860974688326404","last_synced_commit":"db089aed57565d826a043388b76cad9332929005"},"previous_names":[],"tags_count":288,"template":false,"template_full_name":null,"purl":"pkg:github/pikepdf/pikepdf","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pikepdf%2Fpikepdf","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pikepdf%2Fpikepdf/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pikepdf%2Fpikepdf/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pikepdf%2Fpikepdf/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/pikepdf","download_url":"https://codeload.github.com/pikepdf/pikepdf/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pikepdf%2Fpikepdf/sbom","scorecard":{"id":733815,"data":{"date":"2025-08-11","repo":{"name":"github.com/pikepdf/pikepdf","commit":"b9dae088c08e0050e5157e5a595ddd243dd223a6"},"scorecard":{"version":"v5.2.1-40-gf6ed084d","commit":"f6ed084d17c9236477efd66e5b258b9d4cc7b389"},"score":6.5,"checks":[{"name":"Maintained","score":10,"reason":"30 commit(s) and 6 issue activity found in the last 90 days -- score normalized to 10","details":null,"documentation":{"short":"Determines if the project is \"actively maintained\".","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#maintained"}},{"name":"Code-Review","score":0,"reason":"Found 2/26 approved changesets -- score normalized to 0","details":null,"documentation":{"short":"Determines if the project requires human code review before pull requests (aka merge requests) are merged.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#code-review"}},{"name":"CII-Best-Practices","score":0,"reason":"no effort to earn an OpenSSF best practices badge detected","details":null,"documentation":{"short":"Determines if the project has an OpenSSF (formerly CII) Best Practices Badge.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#cii-best-practices"}},{"name":"Dangerous-Workflow","score":10,"reason":"no dangerous workflow patterns detected","details":null,"documentation":{"short":"Determines if the project's GitHub Action workflows avoid dangerous patterns.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#dangerous-workflow"}},{"name":"Security-Policy","score":0,"reason":"security policy file not detected","details":["Warn: no security policy file detected","Warn: no security file to analyze","Warn: no security file to analyze","Warn: no security file to analyze"],"documentation":{"short":"Determines if the project has published a security policy.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#security-policy"}},{"name":"Token-Permissions","score":0,"reason":"detected GitHub workflow tokens with excessive permissions","details":["Warn: jobLevel 'contents' permission set to 'write': .github/workflows/build.yml:296","Info: jobLevel 'actions' permission set to 'read': .github/workflows/codeql-analysis.yml:19","Info: jobLevel 'contents' permission set to 'read': .github/workflows/codeql-analysis.yml:20","Warn: no topLevel permission defined: .github/workflows/build.yml:1","Info: found token with 'none' permissions: .github/workflows/cifuzz.yml:1","Warn: no topLevel permission defined: .github/workflows/codeql-analysis.yml:1","Warn: no topLevel permission defined: .github/workflows/pre-commit.yml:1"],"documentation":{"short":"Determines if the project's workflows follow the principle of least privilege.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#token-permissions"}},{"name":"Binary-Artifacts","score":10,"reason":"no binaries found in the repo","details":null,"documentation":{"short":"Determines if the project has generated executable (binary) artifacts in the source repository.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#binary-artifacts"}},{"name":"Vulnerabilities","score":10,"reason":"0 existing vulnerabilities detected","details":null,"documentation":{"short":"Determines if the project has open, known unfixed vulnerabilities.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#vulnerabilities"}},{"name":"License","score":10,"reason":"license file detected","details":["Info: project has a license file: LICENSE.txt:0","Info: FSF or OSI recognized license: Mozilla Public License 2.0: LICENSE.txt:0"],"documentation":{"short":"Determines if the project has defined a license.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#license"}},{"name":"Fuzzing","score":10,"reason":"project is fuzzed","details":["Info: OSSFuzz integration found","Info: PythonAtherisFuzzer integration found: fuzzing/fuzz_helpers.py:12","Info: PythonAtherisFuzzer integration found: fuzzing/pikepdf_fuzzer.py:8"],"documentation":{"short":"Determines if the project uses fuzzing.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#fuzzing"}},{"name":"Pinned-Dependencies","score":0,"reason":"dependency not pinned by hash detected -- score normalized to 0","details":["Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/build.yml:125: update your workflow using https://app.stepsecurity.io/secureworkflow/pikepdf/pikepdf/build.yml/main?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/build.yml:127: update your workflow using https://app.stepsecurity.io/secureworkflow/pikepdf/pikepdf/build.yml/main?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/build.yml:133: update your workflow using https://app.stepsecurity.io/secureworkflow/pikepdf/pikepdf/build.yml/main?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/build.yml:192: update your workflow using https://app.stepsecurity.io/secureworkflow/pikepdf/pikepdf/build.yml/main?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/build.yml:194: update your workflow using https://app.stepsecurity.io/secureworkflow/pikepdf/pikepdf/build.yml/main?enable=pin","Warn: third-party GitHubAction not pinned by hash: .github/workflows/build.yml:253: update your workflow using https://app.stepsecurity.io/secureworkflow/pikepdf/pikepdf/build.yml/main?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/build.yml:259: update your workflow using https://app.stepsecurity.io/secureworkflow/pikepdf/pikepdf/build.yml/main?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/build.yml:275: update your workflow using https://app.stepsecurity.io/secureworkflow/pikepdf/pikepdf/build.yml/main?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/build.yml:281: update your workflow using https://app.stepsecurity.io/secureworkflow/pikepdf/pikepdf/build.yml/main?enable=pin","Warn: third-party GitHubAction not pinned by hash: .github/workflows/build.yml:287: update your workflow using https://app.stepsecurity.io/secureworkflow/pikepdf/pikepdf/build.yml/main?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/build.yml:22: update your workflow using https://app.stepsecurity.io/secureworkflow/pikepdf/pikepdf/build.yml/main?enable=pin","Warn: third-party GitHubAction not pinned by hash: .github/workflows/build.yml:25: update your workflow using https://app.stepsecurity.io/secureworkflow/pikepdf/pikepdf/build.yml/main?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/build.yml:28: update your workflow using https://app.stepsecurity.io/secureworkflow/pikepdf/pikepdf/build.yml/main?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/build.yml:45: update your workflow using https://app.stepsecurity.io/secureworkflow/pikepdf/pikepdf/build.yml/main?enable=pin","Warn: third-party GitHubAction not pinned by hash: .github/workflows/build.yml:48: update your workflow using https://app.stepsecurity.io/secureworkflow/pikepdf/pikepdf/build.yml/main?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/build.yml:163: update your workflow using https://app.stepsecurity.io/secureworkflow/pikepdf/pikepdf/build.yml/main?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/build.yml:165: update your workflow using https://app.stepsecurity.io/secureworkflow/pikepdf/pikepdf/build.yml/main?enable=pin","Warn: third-party GitHubAction not pinned by hash: .github/workflows/build.yml:181: update your workflow using https://app.stepsecurity.io/secureworkflow/pikepdf/pikepdf/build.yml/main?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/build.yml:183: update your workflow using https://app.stepsecurity.io/secureworkflow/pikepdf/pikepdf/build.yml/main?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/build.yml:299: update your workflow using https://app.stepsecurity.io/secureworkflow/pikepdf/pikepdf/build.yml/main?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/build.yml:305: update your workflow using https://app.stepsecurity.io/secureworkflow/pikepdf/pikepdf/build.yml/main?enable=pin","Warn: third-party GitHubAction not pinned by hash: .github/workflows/build.yml:311: update your workflow using https://app.stepsecurity.io/secureworkflow/pikepdf/pikepdf/build.yml/main?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/build.yml:61: update your workflow using https://app.stepsecurity.io/secureworkflow/pikepdf/pikepdf/build.yml/main?enable=pin","Warn: third-party GitHubAction not pinned by hash: .github/workflows/build.yml:64: update your workflow using https://app.stepsecurity.io/secureworkflow/pikepdf/pikepdf/build.yml/main?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/build.yml:75: update your workflow using https://app.stepsecurity.io/secureworkflow/pikepdf/pikepdf/build.yml/main?enable=pin","Warn: third-party GitHubAction not pinned by hash: .github/workflows/build.yml:78: update your workflow using https://app.stepsecurity.io/secureworkflow/pikepdf/pikepdf/build.yml/main?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/build.yml:81: update your workflow using https://app.stepsecurity.io/secureworkflow/pikepdf/pikepdf/build.yml/main?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/build.yml:106: update your workflow using https://app.stepsecurity.io/secureworkflow/pikepdf/pikepdf/build.yml/main?enable=pin","Warn: third-party GitHubAction not pinned by hash: .github/workflows/build.yml:109: update your workflow using https://app.stepsecurity.io/secureworkflow/pikepdf/pikepdf/build.yml/main?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/build.yml:111: update your workflow using https://app.stepsecurity.io/secureworkflow/pikepdf/pikepdf/build.yml/main?enable=pin","Warn: third-party GitHubAction not pinned by hash: .github/workflows/cifuzz.yml:19: update your workflow using https://app.stepsecurity.io/secureworkflow/pikepdf/pikepdf/cifuzz.yml/main?enable=pin","Warn: third-party GitHubAction not pinned by hash: .github/workflows/cifuzz.yml:24: update your workflow using https://app.stepsecurity.io/secureworkflow/pikepdf/pikepdf/cifuzz.yml/main?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/cifuzz.yml:31: update your workflow using https://app.stepsecurity.io/secureworkflow/pikepdf/pikepdf/cifuzz.yml/main?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/cifuzz.yml:38: update your workflow using https://app.stepsecurity.io/secureworkflow/pikepdf/pikepdf/cifuzz.yml/main?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/codeql-analysis.yml:29: update your workflow using https://app.stepsecurity.io/secureworkflow/pikepdf/pikepdf/codeql-analysis.yml/main?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/codeql-analysis.yml:33: update your workflow using https://app.stepsecurity.io/secureworkflow/pikepdf/pikepdf/codeql-analysis.yml/main?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/codeql-analysis.yml:55: update your workflow using https://app.stepsecurity.io/secureworkflow/pikepdf/pikepdf/codeql-analysis.yml/main?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/codeql-analysis.yml:66: update your workflow using https://app.stepsecurity.io/secureworkflow/pikepdf/pikepdf/codeql-analysis.yml/main?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/pre-commit.yml:15: update your workflow using https://app.stepsecurity.io/secureworkflow/pikepdf/pikepdf/pre-commit.yml/main?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/pre-commit.yml:16: update your workflow using https://app.stepsecurity.io/secureworkflow/pikepdf/pikepdf/pre-commit.yml/main?enable=pin","Warn: third-party GitHubAction not pinned by hash: .github/workflows/pre-commit.yml:19: update your workflow using https://app.stepsecurity.io/secureworkflow/pikepdf/pikepdf/pre-commit.yml/main?enable=pin","Warn: pipCommand not pinned by hash: .github/workflows/build.yml:206","Warn: pipCommand not pinned by hash: .github/workflows/build.yml:220","Warn: pipCommand not pinned by hash: .github/workflows/build.yml:221","Warn: pipCommand not pinned by hash: .github/workflows/build.yml:230","Warn: pipCommand not pinned by hash: .github/workflows/build.yml:239","Warn: pipCommand not pinned by hash: .github/workflows/build.yml:145","Warn: pipCommand not pinned by hash: .github/workflows/codeql-analysis.yml:40","Warn: pipCommand not pinned by hash: .github/workflows/codeql-analysis.yml:61","Warn: pipCommand not pinned by hash: .github/workflows/codeql-analysis.yml:62","Info:   0 out of  29 GitHub-owned GitHubAction dependencies pinned","Info:   0 out of  12 third-party GitHubAction dependencies pinned","Info:   0 out of   9 pipCommand dependencies pinned"],"documentation":{"short":"Determines if the project has declared and pinned the dependencies of its build process.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#pinned-dependencies"}},{"name":"Branch-Protection","score":-1,"reason":"internal error: error during branchesHandler.setup: internal error: githubv4.Query: Resource not accessible by integration","details":null,"documentation":{"short":"Determines if the default and release branches are protected with GitHub's branch protection settings.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#branch-protection"}},{"name":"Packaging","score":10,"reason":"packaging workflow detected","details":["Info: Project packages its releases by way of GitHub Actions.: .github/workflows/build.yml:264"],"documentation":{"short":"Determines if the project is published as a package that others can easily download, install, easily update, and uninstall.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#packaging"}},{"name":"SAST","score":8,"reason":"SAST tool detected but not run on all commits","details":["Info: SAST configuration detected: CodeQL","Warn: 4 commits out of 6 are checked with a SAST tool"],"documentation":{"short":"Determines if the project uses static code analysis.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#sast"}},{"name":"Signed-Releases","score":8,"reason":"5 out of the last 5 releases have a total of 5 signed artifacts.","details":["Info: signed release artifact: pikepdf-9.10.2-cp310-cp310-macosx_13_0_x86_64.whl.sigstore.json: https://github.com/pikepdf/pikepdf/releases/tag/v9.10.2","Info: signed release artifact: pikepdf-9.10.1-cp310-cp310-macosx_13_0_x86_64.whl.sigstore.json: https://github.com/pikepdf/pikepdf/releases/tag/v9.10.1","Info: signed release artifact: pikepdf-9.10.0-cp310-cp310-macosx_13_0_x86_64.whl.sigstore.json: https://github.com/pikepdf/pikepdf/releases/tag/v9.10.0","Info: signed release artifact: pikepdf-9.9.0-cp310-cp310-macosx_13_0_x86_64.whl.sigstore.json: https://github.com/pikepdf/pikepdf/releases/tag/v9.9.0","Info: signed release artifact: pikepdf-9.8.1-cp310-cp310-macosx_13_0_x86_64.whl.sigstore.json: https://github.com/pikepdf/pikepdf/releases/tag/v9.8.1","Warn: release artifact v9.10.2 does not have provenance: https://api.github.com/repos/pikepdf/pikepdf/releases/233086228","Warn: release artifact v9.10.1 does not have provenance: https://api.github.com/repos/pikepdf/pikepdf/releases/232753744","Warn: release artifact v9.10.0 does not have provenance: https://api.github.com/repos/pikepdf/pikepdf/releases/232141460","Warn: release artifact v9.9.0 does not have provenance: https://api.github.com/repos/pikepdf/pikepdf/releases/226063252","Warn: release artifact v9.8.1 does not have provenance: https://api.github.com/repos/pikepdf/pikepdf/releases/221376194"],"documentation":{"short":"Determines if the project cryptographically signs release artifacts.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#signed-releases"}}]},"last_synced_at":"2025-08-22T15:09:54.022Z","repository_id":37484299,"created_at":"2025-08-22T15:09:54.023Z","updated_at":"2025-08-22T15:09:54.023Z"},"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":343843146,"owners_count":38263778,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-10-03T21:59:58.778Z","status":"online","status_checked_at":"2026-10-13T02:00:04.984Z","response_time":52,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["existing-pdfs","pdf","pdf-generation","pdf-manipulation","pikepdf","pypdf2","python","qpdf"],"created_at":"2024-07-31T19:01:51.542Z","updated_at":"2026-10-19T07:21:42.789Z","avatar_url":"https://github.com/pikepdf.png","language":"Python","funding_links":["https://opencollective.com/james-barlow"],"categories":["Python","Specific Formats Processing","Multi-Purpose Libraries"],"sub_categories":[],"readme":"\u003c!-- SPDX-FileCopyrightText: 2022 James R. Barlow --\u003e\n\u003c!-- SPDX-License-Identifier: MPL-2.0 --\u003e\n\n# pikepdf\n\n**Read, write, repair, and transform PDFs in Python -- powered by qpdf.**\n\n[![Build Status](https://github.com/pikepdf/pikepdf/actions/workflows/build.yml/badge.svg)](https://github.com/pikepdf/pikepdf/actions/workflows/build.yml) [![PyPI](https://img.shields.io/pypi/v/pikepdf.svg)](https://pypi.org/project/pikepdf/) ![PyPI - Python Version](https://img.shields.io/pypi/pyversions/pikepdf)  ![PyPI - License](https://img.shields.io/pypi/l/pikepdf) ![PyPI - Downloads](https://img.shields.io/pypi/dm/pikepdf)  [![codecov](https://codecov.io/gh/pikepdf/pikepdf/branch/main/graph/badge.svg?token=8FJ755317J)](https://codecov.io/gh/pikepdf/pikepdf)\n\npikepdf is based on [qpdf](https://github.com/qpdf/qpdf), a mature, actively maintained C++ library for PDF manipulation and repair.\n\nPython + qpdf = \"py\" + \"qpdf\" = \"pyqpdf\", which looks like a dyslexia test. Say it out loud, and it sounds like \"pikepdf\".\n\n```python\nimport pikepdf\n\n# Open a PDF -- pikepdf (via qpdf) automatically repairs structural damage\nwith pikepdf.Pdf.open('input.pdf') as pdf:\n    num_pages = len(pdf.pages)\n    del pdf.pages[-1]\n    pdf.save('output.pdf')\n```\n\n## Installation\n\n```bash\npip install pikepdf\n```\n\nBinary wheels are available for all common platforms -- Linux, macOS, and Windows on both x86-64 and ARM64/Apple Silicon -- including free-threaded (no-GIL) CPython 3.14. No compiler required.\n\nFor building from source, see [installation](https://pikepdf.readthedocs.io/en/latest/source_build.html). Commercial support is available.\n\n## What Can pikepdf Do?\n\n### Manipulate pages\n\nMerge, split, rotate, and rearrange pages across PDFs.\n\n```python\nfrom pikepdf import Pdf\n\n# Merge multiple PDFs\nwith Pdf.new() as merged:\n    for filename in ['first.pdf', 'second.pdf', 'third.pdf']:\n        src = Pdf.open(filename)\n        merged.pages.extend(src.pages)\n    merged.save('merged.pdf')\n```\n\n```python\n# Rotate all pages in a document\nwith Pdf.open('input.pdf') as pdf:\n    for page in pdf.pages:\n        page.rotate(180, relative=True)\n    pdf.save('rotated.pdf')\n```\n\n### Edit metadata\n\nRead and write XMP metadata and DocumentInfo, with automatic synchronization between the two.\n\n```python\nimport pikepdf\n\nwith pikepdf.open('report.pdf') as pdf:\n    with pdf.open_metadata() as meta:\n        meta['dc:title'] = 'Quarterly Report'\n        meta['dc:creator'] = ['Author Name']\n    pdf.save('updated.pdf')\n```\n\n### Extract images\n\nExtract images losslessly from PDFs -- without re-encoding JPEGs or other compressed formats.\n\n```python\nfrom pikepdf import Pdf, PdfImage\n\nwith Pdf.open('document.pdf') as pdf:\n    for page in pdf.pages:\n        for name, raw_image in page.images.items():\n            image = PdfImage(raw_image)\n            image.extract_to(fileprefix='output')\n```\n\n### Encrypt and decrypt\n\nOpen password-protected PDFs and save with encryption (AES-256, AES-128, or RC4).\n\n```python\nimport pikepdf\n\n# Open an encrypted PDF\nwith pikepdf.open('protected.pdf', password='secret') as pdf:\n    pdf.save('decrypted.pdf')\n\n# Save with encryption\nwith pikepdf.open('input.pdf') as pdf:\n    pdf.save('encrypted.pdf', encryption=pikepdf.Encryption(\n        user='readpassword', owner='adminpassword'\n    ))\n\n# Remove encryption if user password is not set\nwith pikepdf.open('protected.pdf') as pdf:\n    pdf.save('decrypted.pdf', encryption=False)\n```\n\n(Digital signature-based encryption is not currently supported.)\n\n### Linearize to improve browser performance\n\nCreate \"fast web view\" PDFs optimized for streaming delivery.\n\n```python\nwith pikepdf.open('input.pdf') as pdf:\n    pdf.save('web_optimized.pdf', linearize=True)\n```\n\n### Access PDF objects directly\n\nUse a Pythonic API that mirrors the PDF specification -- dictionaries, arrays, streams, and names map directly to Python types.\n\n```python\nfrom pikepdf import Pdf, Name\n\nwith Pdf.open('input.pdf') as pdf:\n    page = pdf.pages[0]\n    page.MediaBox               # e.g. [0, 0, 612, 792]\n    page.Resources.XObject      # image and form XObjects on this page\n    page.Rotate = 90            # set page rotation directly\n```\n\n### Use qpdf's Job API\n\nAccess qpdf's full command-line capabilities programmatically from Python.\n\n```python\nfrom pikepdf import Job\n\n# Check a PDF for errors\nJob(['pikepdf', '--check', 'document.pdf']).run()\n\n# Or use qpdf's JSON job interface\nJob({'inputFile': 'input.pdf', 'outputFile': 'output.pdf', 'linearize': ''}).run()\n```\n\n## Key Features\n\n- **Built on qpdf** -- backed by a mature, battle-tested C++ PDF library\n- **Automatic PDF repair** -- silently fixes many types of PDF damage on open\n- **PDF/A compliance** -- modify PDFs without breaking PDF/A conformance\n- **XMP metadata editing** -- full read/write support for XMP and DocumentInfo\n- **Encryption support** -- open and save password-protected PDFs (AES-256, AES-128, RC4)\n- **Linearization** -- create \"fast web view\" PDFs for efficient streaming\n- **Pythonic API** -- dictionary-style access to PDF objects, list-style page access\n- **Lossless image extraction** -- extract and replace images without re-encoding\n- **Content stream inspection** -- parse and manipulate page content at the operator level\n- **Object-level manipulation** -- work directly with PDF objects per the specification\n- **Jupyter integration** -- render PDF and page previews inline in notebooks\n- **Binary wheels everywhere** -- pre-built for Linux, macOS, Windows (x86-64 and ARM64), including free-threaded CPython 3.14\n- **Liberal license** -- MPL-2.0, compatible with most open and closed source projects\n\n## When to Use pikepdf\n\npikepdf is a great fit when you need to:\n\n- Repair, sanitize, or normalize damaged or malformed PDFs\n- Merge, split, rotate, crop, or rearrange pages\n- Edit PDF metadata (XMP, DocumentInfo) programmatically\n- Build tools or libraries that operate on existing PDFs\n- Preserve PDF/A or other standard compliance while modifying documents\n- Work with encrypted PDFs\n- Perform low-level PDF surgery (object and stream manipulation)\n- Optimize PDFs for web delivery (linearization)\n\npikepdf is probably not what you want if you need to:\n\n- Generate PDFs from HTML or templates -- consider [weasyprint](https://weasyprint.org/) or [reportlab](https://www.reportlab.com/)\n- Render PDFs to images -- consider [PyMuPDF](https://pymupdf.readthedocs.io/) or [pypdfium2](https://github.com/pypdfium2-team/pypdfium2)\n- Extract text or tables from PDFs -- consider [pdfminer.six](https://github.com/pdfminer/pdfminer.six) or [pdfplumber](https://github.com/jsvine/pdfplumber)\n\n## PDF Libraries in Python\n\nPython has several PDF libraries, each with different strengths. [pypdf](https://pypdf.readthedocs.io/) is pure Python and well-suited for straightforward PDF tasks without compiled dependencies. [pypdfium](https://pypdfium2.readthedocs.io/) for permissively licensed PDF rendering.\n [PyMuPDF](https://pymupdf.readthedocs.io/) offers comprehensive rendering and text extraction. pikepdf focuses on correctness, repair, and low-level manipulation through qpdf, under the permissive MPL-2.0 license.\n\n## Testimonials\n\n\u003e I decided to try writing a quick Python program with pikepdf to automate [something] and it \"just worked\". --Jay Berkenbilt, creator of qpdf\n\n\u003e \"Thanks for creating a great pdf library, I tested out several and this is the one that was best able to work with whatever I threw at it.\" --@cfcurtis\n\n## Used By\n\n* [OCRmyPDF](https://github.com/ocrmypdf/OCRmyPDF) uses pikepdf to graft OCR text layers onto existing PDFs, to examine the contents of input PDFs, and to optimize PDFs.\n\n* [PDF Arranger](https://github.com/jeromerobert/pdfarranger) is a small Python application that provides a graphical user interface to rotate, crop and rearrange PDFs.\n\n* [PDFStitcher](https://github.com/cfcurtis/sewingutils) is a utility for stitching PDF pages into a single document (i.e. N-up or page imposition).\n\n## Documentation\n\nFull documentation is available at [pikepdf.readthedocs.io](https://pikepdf.readthedocs.io/en/latest/). For the latest changes, see the [release notes](https://pikepdf.readthedocs.io/en/latest/releasenotes/index.html).\n\n## Contributing\n\nContributions are welcome! If you'd like to make a contribution, see the [Contributing Guidelines](https://pikepdf.readthedocs.io/en/latest/references/contributing.html)\n\n## License\n\npikepdf is licensed under the [Mozilla Public License 2.0](https://www.mozilla.org/en-US/MPL/2.0/) license (MPL-2.0) that can be found in the LICENSE file. By using, distributing, or contributing to this project, you agree to the terms and conditions of this license. MPL 2.0 permits you to combine the software with other work, including commercial and closed source software, but asks you to publish source-level modifications you make to pikepdf itself.\n\nSome components of the project may be under other license agreements, as indicated in their SPDX license header or the [`REUSE.toml`](REUSE.toml) file.\n\npikepdf source distributions contain only pikepdf's own MPL-2.0 code. Binary wheels additionally bundle compiled third-party libraries — qpdf and libjpeg-turbo everywhere, plus OpenSSL and zlib on Windows and the GnuTLS stack on macOS. [`third-party-licenses/`](third-party-licenses/README.md) maps each of those components to its license, and every wheel redistributes that mapping and the license texts under `pikepdf-\u003cversion\u003e.dist-info/licenses/`.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpikepdf%2Fpikepdf","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fpikepdf%2Fpikepdf","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpikepdf%2Fpikepdf/lists"}