How to Create Documents with the Generated Compatibility Module in Python
Aspose.PDF FOSS for Python ships a generated compatibility subpackage (aspose_pdf.generated) that mirrors a stable subset of the main API surface — a Document class with the core lifecycle operations, plus UnsignedContent/UnsignedContentAbsorber and PdfAValidateOptions/PdfAValidationResult. It exists for callers that want this narrower surface explicitly rather than the full-featured top-level classes, and its classes are not imported automatically by import aspose_pdf — you import them from aspose_pdf.generated.* directly. The package is pure Python and is installed from PyPI with pip.
Step-by-Step Guide
Step 1: Install the Package
Install the Aspose.PDF FOSS package from PyPI:
pip install aspose-pdf-foss-for-pythonVerify the installation by importing the generated Document and printing a confirmation message:
import aspose_pdf
from aspose_pdf.generated.document import Document
print("aspose-pdf-foss-for-python is ready.")Step 2: Import Required Classes
The generated compatibility classes live in aspose_pdf.generated.document, aspose_pdf.generated.forms, and aspose_pdf.generated.pdfa — import them explicitly by submodule:
import aspose_pdf
from aspose_pdf.generated.document import Document
from aspose_pdf.generated.forms import UnsignedContent, UnsignedContentAbsorber
from aspose_pdf.generated.pdfa import PdfAValidateOptions, PdfAValidationResultStep 3: Create and Load a Document
Document(source) loads immediately when a source is supplied; calling Document() with no argument creates an empty instance you can load later with load_from. Both accept a file path, bytes, or a binary stream:
from aspose_pdf.generated.document import Document
document = Document("report.pdf")
print(f"Loaded {len(document.pages)} page(s)")
empty_doc = Document()
empty_doc.load_from("report.pdf")Step 4: Save, Merge, and Dispose
save(destination, save_format=None, overwrite=False) writes the document; only PDF output is accepted. merge(*documents) appends the pages of one or more other Document instances onto the current one. close() is an alias for dispose(), which releases the underlying engine resources:
first = Document("report.pdf")
second = Document("appendix.pdf")
first.merge(second)
first.save("combined.pdf", overwrite=True)
first.close()Step 5: Optimize and Repair a Document
optimize(compress_images=True) runs generic size optimizations, optimize_resources(remove_unused=True) removes unused shared resources such as fonts and images, and repair() attempts to fix structural issues via the underlying engine. All three return the Document itself so calls can be chained:
document = Document("large-report.pdf")
document.optimize(compress_images=True).optimize_resources(remove_unused=True)
document.repair()
document.save("large-report-optimized.pdf", overwrite=True)Step 6: Encrypt, Decrypt, and Validate
encrypt(password) and decrypt(password) manage a document password; change_passwords(old_password, new_password) rotates it while the document is encrypted. validate() (aliased by check()) reports whether the document is structurally valid:
document = Document("report.pdf")
document.encrypt("secret")
print(document.is_encrypted)
document.decrypt("secret")
document.change_passwords("secret", "new-secret") if document.is_encrypted else None
print(document.validate())Step 7: Extract Unsigned Form Content
UnsignedContentAbsorber extracts the pages, form fields, and annotations that have not been part of a digital signature. Call extract() to run the extraction, has_extracted() to check whether it has run, and get_extracted() to retrieve the result again without re-extracting:
from aspose_pdf.generated.forms import UnsignedContentAbsorber
absorber = UnsignedContentAbsorber()
unsigned = absorber.extract()
print(f"Unsigned pages: {len(unsigned.pages)}")
print(f"Unsigned form fields: {len(unsigned.form_fields)}")
if absorber.has_extracted():
same_result = absorber.get_extracted()Step 8: Build an UnsignedContent Container Manually
UnsignedContent is also a plain container you can populate yourself with add_page, add_form_field, and add_annotation — each has a matching remove_* method, and reset() clears all three collections at once:
from aspose_pdf.generated.forms import UnsignedContent
content = UnsignedContent()
content.add_page("page-1")
content.add_annotation("signature-placeholder")
print(content) # UnsignedContent(pages=1, form_fields=0, annotations=1)
content.remove_annotation("signature-placeholder")
content.reset()Step 9: Configure and Run PDF/A Validation
PdfAValidateOptions collects the inputs and settings for a validation run. add_input(source) registers an input, set_option(key, value) stores a named option, and get_options() returns a copy of the stored options. PdfAValidationResult holds the outcome — add_error(message) marks the result invalid and appends to errors, and to_dict() renders is_valid and errors as a plain dictionary:
from aspose_pdf.generated.pdfa import PdfAValidateOptions, PdfAValidationResult
options = PdfAValidateOptions()
options.add_input("report.pdf")
options.set_option("pdfa_version", "1b")
print(options.get_options())
result = PdfAValidationResult()
result.add_error("Font 'Arial' is not embedded")
print(result.is_valid) # False
print(result.to_dict())Common Issues and Fixes
ImportError or AttributeError when accessing aspose_pdf.generated
The generated subpackage is not re-exported by import aspose_pdf — import each class from its specific submodule, for example from aspose_pdf.generated.document import Document, rather than expecting aspose_pdf.generated.Document to work after a plain import aspose_pdf.
Confusing the generated Document with the main aspose_pdf.Document
aspose_pdf.Document (the top-level class re-exported by import aspose_pdf) has a larger surface — it adds methods such as validate_pdfa, iter_pages, and redact_text that aspose_pdf.generated.document.Document does not implement. If a method is missing on the generated Document, check whether it belongs to the top-level Document class instead.
save() raises AsposePdfException: Cannot save a disposed document
close()/dispose() releases the document’s internal state permanently — a disposed Document cannot be saved, optimized, or repaired afterward. Perform all remaining operations before calling close(), or reload from the source with a fresh Document(...) call.
change_passwords raises PdfSecurityException: Document is not encrypted
change_passwords only rotates a password on a document that is already encrypted. Call encrypt(password) first, or check document.is_encrypted before attempting to change the password.
PdfAValidationResult.add_error raises TypeError
add_error requires a str argument. Convert exception objects or other error details to a string (str(error)) before passing them to add_error.
Frequently Asked Questions
Why does aspose_pdf.generated exist alongside the main aspose_pdf.Document?
It mirrors a narrower, stable subset of the Aspose.PDF API for code written against that reduced surface. New code that does not specifically need this compatibility subset should generally use the top-level aspose_pdf.Document, which supports more operations (PDF/A conversion, page iteration, text redaction, and others).
Does UnsignedContentAbsorber.extract() accept a Document to scan?
extract() accepts positional and keyword arguments that are used to populate the returned UnsignedContent’s pages, form_fields, and annotations collections — pass the collections you want represented as keyword arguments (pages=, form_fields=, annotations=).
What happens if I call reset() on UnsignedContentAbsorber before extracting anything?
It clears any previously extracted result. get_extracted() then returns None and has_extracted() returns False until extract() is called again.
Can PdfAValidateOptions.add_input be called more than once?
Yes — each call appends another entry to the inputs list, and it returns self, so calls can be chained: options.add_input("a.pdf").add_input("b.pdf").
Is close() different from dispose() on the generated Document?
No — close() is a direct alias that calls dispose() with the same arguments; either name releases the document’s resources.