Skip to main content

Create, read, and update PowerPoint 2007+ (.pptx) files.

Project description

paper-pptx

paper-pptx is an agent-first Python library for safely inspecting, editing, and composing existing PowerPoint (.pptx) files. It is a strict-superset hard fork of python-pptx v1.0.2 and a drop-in replacement. The distribution is renamed; the import name stays pptx, so existing code keeps working unchanged.

from pptx import Presentation          # unchanged — every existing snippet still runs

Why it exists

python-pptx is excellent at building a presentation from scratch. Its lossless package layer, disciplined XML mapping, and decade of absorbed edge cases are why this fork builds on it.

The harder problem is changing a live, branded, template-driven deck without breaking the relationships and inheritance that control how it renders. Hand-edited XML can produce silent corruption: a file that opens fine and is quietly wrong. An agent cannot eyeball the result, so it needs the deck's structure and every edit outcome as typed, machine-readable data. It also needs the library to refuse rather than guess.

What it adds

Everything below is additive API alongside the existing python-pptx API.

  • Perceive. Resolve the size, font, color, and emphasis a shape actually renders at through the placeholder → layout → master → theme chain, where stock python-pptx returns None. Each value includes its provenance (run.effective_font()). Emit the deck's text or structure as deterministic, versioned JSON for diffing and automation (inspect_text, inspect_deck).
  • Edit. Replace text without losing run formatting, addressed by a content-hash anchor so stale edits are detected rather than misapplied (pptx.edit). Copy, delete, move, and reorder slides and shapes; insert and delete table rows and columns. Author real bullets and numbering, normalize autofit, swap an image while keeping its position and crop byte-exact, and replace chart data by shape name after full validation. pptx.package.patch_save keeps every semantically unchanged part byte-identical.
  • Compose. Import slides under an explicit reconciliation mode: adopt the destination theme, keep the source appearance, or bake effective values in place (import_slide, append_deck). Rebind layouts (rebind_layout), apply real slide-number and date fields (apply_footers), and strip notes, comments, metadata, and unused parts before sending (scrub).
  • Verify. Diff two decks part-by-part, including slides added, removed, or moved and the text, chart, image, and notes changes within them (pptx.diff.diff_decks). The result identifies every changed part.

Safety contract

Every added operation either does exactly what it claims or refuses atomically. Mutating operations validate fully before they change anything. If an operation cannot proceed safely, it raises a typed PaperRefusal from pptx.errors and leaves the document byte-for-byte unchanged in memory and on disk. Callers can catch PaperRefusal separately from programmer errors, which remain plain ValueError or TypeError.

Example

Import a slide from one deck into another, then confirm the change with an independent diff:

from pptx import Presentation
from pptx.diff import diff_decks

deck = Presentation("house_deck.pptx")
source = Presentation("sector_team_deck.pptx")

# Import one slide, rebinding it to the destination theme. The report names every
# text run whose resolved appearance changed.
report = deck.import_slide(source, 0, mode="adopt_theme")
for shift in report.run_shifts:
    print(shift.text, shift.before["name"]["value"], "->", shift.after["name"]["value"])

deck.apply_footers(footer="Confidential", slide_number=True)  # real fields, not static text
deck.scrub(metadata=True, comments=True)                      # remove metadata and comments
deck.save("house_deck.v2.pptx")

# Compare the saved deck with the input using an independent diff.
delta = diff_decks("house_deck.pptx", "house_deck.v2.pptx")
print("slides added:", [s.slide_id for s in delta.slides_added])

Drop-in and name map

Only the distribution and repository are renamed. The importable package is pptx forever. This is the same distribution/import split as Pillow (pip install pillow, import PIL), and it preserves the millions of existing snippets and model priors that use from pptx import Presentation.

  • GitHub repository / PyPI distribution: paper-pptx
  • Python import: pptx
  • Fork sentinel: pptx.__paper_version__ = "0.1.0"
  • Upstream base: python-pptx v1.0.2 (git tag paper-base)

New upstream releases are merged, never rebased, so the fork retains its history and compatibility.

Installation

Install from PyPI:

pip install paper-pptx

Verify the install:

python -c "import pptx; print(pptx.__paper_version__)"

Documentation

Full documentation is under docs/. Start with the paper-pptx additions guide for an overview. Each added module has an API reference page under docs/api/. The remaining documentation is inherited from python-pptx and covers the shared foundation.

How it's tested

  • Upstream's pytest and behave suites run on every change to check compatibility with existing behavior.
  • A frozen, hash-pinned fixture corpus under tests/paper/fixtures/ includes files from real third-party producers, with provenance labels, rather than only self-generated fixtures.
  • The contract harness saves and reopens before asserting, enforces an exact changed-part budget and refusal atomicity, runs a headless LibreOffice load smoke, and validates every emitted XML fragment against its schema.

License

MIT, inherited from python-pptx. Original work © Steve Canny and the python-pptx contributors; fork additions © Paper Instruments, Inc. See LICENSE.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

paper_pptx-0.1.0.tar.gz (9.9 MB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

paper_pptx-0.1.0-py3-none-any.whl (558.3 kB view details)

Uploaded Python 3

File details

Details for the file paper_pptx-0.1.0.tar.gz.

File metadata

  • Download URL: paper_pptx-0.1.0.tar.gz
  • Upload date:
  • Size: 9.9 MB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: uv/0.11.28 {"installer":{"name":"uv","version":"0.11.28","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

File hashes

Hashes for paper_pptx-0.1.0.tar.gz
Algorithm Hash digest
SHA256 1ea68da9f3f3d56e4240333473291840f3c3aeabd70c1133cdd67d6dffb64c6d
MD5 fa5f8c6954faee94ce5bb3bf803dfb53
BLAKE2b-256 db5488cc56e6ea33c0141a174df966f00cb84995b65fb232e4e6a50ed8823b3b

See more details on using hashes here.

File details

Details for the file paper_pptx-0.1.0-py3-none-any.whl.

File metadata

  • Download URL: paper_pptx-0.1.0-py3-none-any.whl
  • Upload date:
  • Size: 558.3 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: uv/0.11.28 {"installer":{"name":"uv","version":"0.11.28","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

File hashes

Hashes for paper_pptx-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 7d129936bb1341f9daa6e75b0af1be11ae0993cf4b295e5960e61c50822b88b2
MD5 59adbfa29c69f52c42db3696650c33e0
BLAKE2b-256 89388abbd77d531e484e44ed5f198c7a2341819525b6e008b4a40dbdba96e7a5

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page