Python
The page-validation package provides Python bindings for page.
Installation¶
Check compliance of a PDF¶
is_pdf_compliant() is the fastest way to get a simple true/false compliance result for a profile. It returns both the selected profile and the boolean result:
If the profile isn't specified, it reads the PDF/A or PDF/UA profile declared in the document's XMP metadata. A missing, malformed, or unsupported profile declaration, or an input that cannot be read or parsed, raises page.ValidationError.
Info
If you want to run it on bytes instead of a file, use is_pdf_compliant_bytes(), which provides the same API but expects a bytes value instead of a path.
Validate a PDF with details¶
If you need details about which rules failed, use validate_pdf():
import page
report = page.validate_pdf("document.pdf")
if report.is_compliant:
print("The document passed all implemented checks.")
else:
for failure in report.failures:
print(f"[{failure.rule_id}] {failure.message}")
Info
If you want to run it on bytes instead of a file, use validate_pdf_bytes(), which provides the same API but expects a bytes value instead of a path.
Select a profile explicitly¶
Pass a profile to validate_pdf() when the caller, rather than the document, selects it:
The explicit-profile call does not require the document to contain a usable profile declaration. The declaration can still fail the selected profile's metadata rules. Use is_pdf_compliant() or the corresponding bytes function when you only need a boolean result.
Failures¶
Each report contains a list of failures:
import page
report = page.validate_pdf("file.pdf")
for failure in report.failures:
print(f"Rule: {failure.rule_id}")
print(f"Category: {failure.category}")
print(f"Message: {failure.message}")
Failure categories distinguish conformance problems from parser or operational errors:
import page
for failure in report.failures:
if failure.category in (
page.FailureCategory.METADATA,
page.FailureCategory.CONFORMANCE,
):
# The PDF was parsed, but failed a validation rule.
pass
elif failure.category == page.FailureCategory.PARSER:
# The PDF could not be parsed correctly.
pass
elif failure.category == page.FailureCategory.OPERATIONAL:
# Validation failed because of I/O or another runtime issue.
pass
Safety limits¶
Safety limits protect the validator from excessively large or complex inputs. Defaults are sufficient for most cases:
import page
limits = page.SafetyLimits(
max_input_size=256 * 1024 * 1024, # 256 MiB
max_decoded_stream_size=32 * 1024 * 1024, # 32 MiB
max_total_decoded_content_size=256 * 1024 * 1024, # 256 MiB
max_object_count=1_000_000, # 1,000,000 objects
max_reference_depth=256, # 256 levels
max_xref_revisions=1_024, # 1,024 revisions
max_table_span=1_024, # rows or columns per cell
max_table_grid_rows=1_024, # rows
max_table_grid_columns=1_024, # columns
max_table_grid_cells=1_000_000, # cells
max_unicode_cmap_mappings=1_000_000, # mappings per ToUnicode CMap
)
report = page.validate_pdf("document.pdf", limits=limits)
max_decoded_stream_size bounds one decoded stream and max_total_decoded_content_size bounds the total decoded page, Form, appearance, Pattern, and Type3 content inspected for one document. max_xref_revisions bounds the number of incremental-update revisions read from the cross-reference chain. max_table_span bounds the row or column span of an individual tagged-table cell. max_table_grid_rows, max_table_grid_columns, and max_table_grid_cells bound the derived table-grid dimensions and total cells. max_unicode_cmap_mappings bounds the total mappings expanded from one ToUnicode CMap.
Use the exit code¶
For command-line integrations or automated checks, a report can provide an appropriate process exit code:
The exit code is 0 for a compliant report, 2 for a noncompliant report, and 1 when the report contains an operational failure.
Export the report¶
Validation reports can be exported as JSON: