Introduction

Aspose.PDF FOSS for Python centers on the Document class, which exposes pages, form, outlines, tagged_content, and attachments as the entry points for structural, document-level editing. Beyond adding page content, the library covers the operations that make a PDF a complete, distributable artifact: interactive form fields that collect and expose structured data, document-level file attachments, font discovery and embedding for text authoring, and a bookmark tree for navigation. Every one of these areas raises errors through a single exception hierarchy rooted in AsposePdfException, so callers can catch package-specific failures without guessing at exception types module by module.

This guide shows how to work with that document-management surface: catching and distinguishing AsposePdfException subclasses, creating and reading AcroForm fields with Form and Field, embedding and recovering attachments through FileSpecification, resolving fonts with FontRepository and FontRegistry, and building a bookmark tree with OutlineCollection and OutlineItem. Each section uses only the classes and methods present in the current package.

Aspose.PDF FOSS for Python is a Python package, aspose-pdf-foss-for-python, released under the MIT license, requiring Python 3.11 or later. Its top-level module name is aspose_pdf, installed with pip install aspose-pdf-foss-for-python. The core package depends only on cryptography and asn1crypto; optional extras add Pillow-based image decoding, Brotli-based WOFF2 font support, and HarfBuzz-based complex text layout.


Key Features

Exception Handling with AsposePdfException

Every package-specific error in Aspose.PDF FOSS for Python derives from AsposePdfException. Most document-processing failures fall under its PdfException subclass, which in turn is the base for PdfParseException (malformed input), PdfSecurityException (encryption and password failures, including InvalidPasswordException), and PdfValidationException (structural or compliance failures). Catching AsposePdfException last, after more specific subclasses, lets a caller react differently to a bad password than to a corrupted file while still having a single fallback for everything else the package can raise.

from aspose_pdf import Document
from aspose_pdf.exceptions import (
    AsposePdfException,
    InvalidPasswordException,
    PdfParseException,
)


def open_document(path, password=None):
    try:
        document = Document()
        document.load_from(path, password=password)
        return document
    except InvalidPasswordException:
        print(f"{path}: a correct password is required")
    except PdfParseException as error:
        print(f"{path}: not a valid PDF ({error})")
    except AsposePdfException as error:
        # Catches every other aspose_pdf-specific error not handled above.
        print(f"{path}: PDF operation failed ({error})")
    return None

Interactive Form Fields

Document.form returns a Form facade over the document’s AcroForm fields. Form.add_text_field(), add_checkbox(), and add_radio_group() create new terminal fields tied to a page and a widget rectangle, each returning a Field. Field exposes name, value, and field_type so existing fields can be inspected and updated by name, and Field.remove() deletes a field entirely.

from aspose_pdf import Document

with Document() as document:
    page = document.pages.add()

    document.form.add_text_field("customer_name", page, (72, 700, 300, 720))
    document.form.add_checkbox("subscribe", page, (72, 670, 90, 688), on_value="Yes")
    document.form.add_radio_group(
        "plan",
        page,
        {"Basic": (72, 630, 90, 648), "Pro": (72, 600, 90, 618)},
        value="Basic",
    )

    for field in document.form.fields:
        print(field.name, field.field_type, field.value)

    for field in document.form.fields:
        if field.name == "customer_name":
            field.value = "Jane Doe"

    document.form.generate_appearances()
    document.save("form.pdf")

Embedded Files and Attachments

Document.add_attachment() embeds bytes as a document-level file attachment, written to the PDF’s /Names /EmbeddedFiles name tree on save, along with an optional MIME type, description, and creation/modification dates. Document.embedded_files reads every attachment back as a typed FileSpecification (name, contents, mime_type, description, size), and Document.get_embedded_file() looks one up by name. FileSpecification.save() writes the recovered bytes to disk.

from aspose_pdf import Document

with Document() as document:
    document.pages.add()
    document.add_attachment(
        "notes.txt",
        b"Reviewed and approved.",
        mime="text/plain",
        description="Reviewer notes",
    )
    document.save("with-attachment.pdf")

with Document() as document:
    document.load_from("with-attachment.pdf")

    for spec in document.embedded_files:
        print(spec.name, spec.mime_type, spec.size)

    notes = document.get_embedded_file("notes.txt")
    if notes is not None:
        notes.save("notes-recovered.txt")

Font Discovery and Embedding

FontRepository aggregates font sources and resolves fonts by name across the document. FontRepository.add_source() registers a FontSource such as FolderFontSource (scans a directory, optionally recursively); FontRepository.find_font() and search() then resolve a font by family, full, or PostScript name, falling back to the standard-font registry. Each match is a FontDescriptor, which can be passed directly to Page.add_text() to embed and subset the font. FontRegistry maps common non-standard names (Arial, Times New Roman, and similar) to their closest Standard-14 equivalent through search_font_by_name().

from aspose_pdf import Document, FolderFontSource, FontRepository
from aspose_pdf.font_registry import FontRegistry

FontRepository.add_source(FolderFontSource("./fonts", scan_subdirectories=True))

descriptor = FontRepository.find_font("Open Sans")
if descriptor is None:
    # Fall back to the closest Standard-14 match for a common font name.
    descriptor = FontRegistry().search_font_by_name("Arial")

with Document() as document:
    page = document.pages.add()
    page.add_text(
        "Rendered with a resolved font",
        x=72,
        y=700,
        font_size=14,
        font=descriptor,
    )
    document.save("font-sample.pdf")

Document Outlines and Bookmarks

Document.outlines returns an OutlineCollection, the top-level container for a PDF’s bookmark tree. OutlineCollection.add() appends a top-level OutlineItem; OutlineItem.add() nests a child bookmark under an existing one. Each OutlineItem carries a title, a target page_index, and is_bold / is_italic display flags, and exposes its own children list.

from aspose_pdf import Document
from aspose_pdf.outlines import OutlineItem

with Document() as document:
    document.pages.add()
    document.pages.add()

    chapter = OutlineItem("Chapter 1: Overview", page_index=0)
    document.outlines.add(chapter)
    chapter.add(OutlineItem("Section 1.1", page_index=0, is_italic=True))
    document.outlines.add(OutlineItem("Chapter 2: Details", page_index=1, is_bold=True))

    document.save("bookmarked.pdf")

Quick Start

Install the package, then build a document that combines a bookmark, document metadata, and an attachment in a single script.

pip install aspose-pdf-foss-for-python
from aspose_pdf import Document
from aspose_pdf.outlines import OutlineItem

with Document() as document:
    page = document.pages.add()
    page.add_text("Quarterly Report", x=72, y=740, font_size=20)

    document.outlines.add(OutlineItem("Quarterly Report", page_index=0))
    document.info = {"Title": "Quarterly Report"}
    document.add_attachment(
        "source-data.csv", b"quarter,total\nQ1,1000\n", mime="text/csv"
    )
    document.save("report.pdf")

with Document() as reopened:
    reopened.load_from("report.pdf")
    print(reopened.page_count, "page(s),", reopened.info.get("Title"))
    print([spec.name for spec in reopened.embedded_files])

Supported Formats

FormatExtensionReadWrite
PDFpdfYesYes
TIFFtiff-Yes

Page.render(), Page.save_as_image(), and Document.save_page_as_image() also produce PNG raster output alongside TIFF.

These are page-rasterization outputs rather than document-loading formats.


Open Source & Licensing

Aspose.PDF FOSS for Python is released under the MIT license: no usage restrictions, no runtime fees, and no registration requirements for commercial or personal use. Source code is hosted at github.com/aspose-pdf-foss/Aspose-PDF-FOSS-for-Python, and the package is published on PyPI as aspose-pdf-foss-for-python.


Getting Started