Skip to content

Referencia de la API de Python

PDF Oxide ofrece bindings nativos de Python construidos con PyO3. Hay wheels precompilados para Python 3.8–3.14 en Linux, macOS y Windows (x86_64 y ARM64).

pip install pdf_oxide

Para la API de Rust, consulta la Referencia de la API de Rust. Para la API de JavaScript, consulta la Referencia de la API de Node.js o la Referencia de la API WASM. Para los detalles de tipos, consulta Tipos y enums.


PdfDocument

La clase principal para abrir, extraer, editar y guardar archivos PDF.

from pdf_oxide import PdfDocument

Constructor

PdfDocument(path: str, password: str | None = None)
Parámetro Tipo Descripción
path str Ruta al archivo PDF
password str | None Contraseña opcional para PDFs cifrados (por defecto: None)

Pasa password= para abrir PDFs cifrados en un solo paso. Como alternativa, también puedes usar doc.authenticate(password) tras abrirlo.

Lanza FileNotFoundError si el archivo no existe. Lanza PdfError si el archivo no es un PDF válido.

Métodos de clase

PdfDocument.from_bytes(data: bytes, password: str | None = None) -> PdfDocument

Abre un PDF a partir de bytes en memoria (p. ej. descargado de S3, recibido por HTTP). Acepta una contraseña opcional para PDFs cifrados.

Parámetro Tipo Descripción
data bytes Bytes crudos del archivo PDF
password str | None Contraseña opcional para PDFs cifrados (por defecto: None)
from pdf_oxide import PdfDocument

# Open PDF from bytes (e.g., downloaded from S3)
doc = PdfDocument.from_bytes(pdf_bytes)

# Also supports password:
doc = PdfDocument.from_bytes(pdf_bytes, password="secret")

Métodos

Generales

Método Tipo de retorno Descripción
version() tuple[int, int] Versión del PDF como (major, minor) (p. ej. (1, 7))
authenticate(password) bool Autentica un PDF cifrado con la contraseña de usuario o de propietario

Información del documento

doc.page_count() -> int

Devuelve el número de páginas del documento.

doc.has_structure_tree() -> bool

Comprueba si el documento es un Tagged PDF con árbol de estructura.

Autenticación

doc.authenticate(password: str) -> bool

Autentica con una contraseña después de abrir. Devuelve True si la autenticación tuvo éxito.

Extracción de texto

doc.extract_text(
    page: int,
    region: tuple[float, float, float, float] | None = None,
    exclude_layers: list[str] | None = None,
    exclude_inks: list[str] | None = None,
    extract_tables: bool = True
) -> str

Extrae texto plano de una sola página. Las páginas se indexan desde cero. Opcionalmente, recorta a una region, excluye capas de contenido opcional con nombre o nombres de tintas/separaciones, y activa o desactiva la reconstrucción de tablas.

doc.extract_chars(
    page: int,
    region: tuple[float, float, float, float] | None = None,
    exclude_layers: list[str] | None = None,
    exclude_inks: list[str] | None = None
) -> list[TextChar]

Extrae el posicionamiento por carácter y los metadatos de fuente. Devuelve una lista de objetos TextChar.

doc.extract_spans(page: int, region: tuple | None = None, reading_order: str | None = None) -> list[TextSpan]

Extrae spans de texto con metadatos de fuente. Cada span es una secuencia de texto con un estilo idéntico. Pasa reading_order="column_aware" para PDFs multicolumna.

doc.extract_words(
    page: int,
    *,
    include_artifacts: bool = True,
    region: tuple | None = None,
    word_gap_threshold: float | None = None,
    profile: ExtractionProfile | None = None
) -> list[TextWord]

Extrae texto agrupado por palabras con cajas delimitadoras. Devuelve una lista de objetos TextWord.

doc.extract_text_lines(
    page: int,
    *,
    include_artifacts: bool = True,
    region: tuple | None = None,
    word_gap_threshold: float | None = None,
    line_gap_threshold: float | None = None,
    profile: ExtractionProfile | None = None
) -> list[TextLine]

Extrae texto agrupado por líneas. Devuelve una lista de objetos TextLine.

doc.extract_page_text(page: int, reading_order: str | None = None) -> dict

Extrae spans, caracteres y dimensiones de página en una sola pasada. Devuelve un dict con las claves: spans, chars, page_width, page_height, text. Es más eficiente que llamar a extract_spans() + extract_chars() por separado.

doc.page_layout_params(page: int) -> LayoutParams

Calcula parámetros de maquetación adaptativos (umbrales de separación entre palabras/líneas, métricas medianas, número de columnas) para una página. Consulta LayoutParams.

doc.within(page: int, bbox: tuple[float, float, float, float]) -> PdfPageRegion

Crea un handle de región recortada para extraer texto, palabras, líneas, tablas, imágenes y trazados dentro de bbox. Consulta PdfPageRegion.

Extracción y clasificación automáticas

doc.extract_text_auto(page: int) -> str

Selecciona automáticamente la mejor estrategia de extracción (texto nativo frente a OCR) para una página y devuelve texto plano.

doc.extract_page_auto(page: int, options_json: str | None = None) -> str

Extrae una página de forma automática y devuelve un documento JSON; pasa una cadena JSON options_json para ajustar el pipeline.

doc.classify_page(page: int) -> str

Clasifica una sola página (p. ej. "text", "scanned", "mixed").

doc.classify_document() -> str

Clasifica todo el documento muestreando sus páginas.

doc.has_text_layer(page: int) -> bool

Comprueba si una página ya tiene una capa de texto nativo extraíble (frente a requerir OCR).

Conversión

doc.to_plain_text(
    page: int,
    preserve_layout: bool = False,
    detect_headings: bool = True,
    include_images: bool = True,
    image_output_dir: str | None = None
) -> str

Convierte una página a texto plano con opciones de maquetación.

doc.to_plain_text_all(
    preserve_layout: bool = False,
    detect_headings: bool = True,
    include_images: bool = True,
    image_output_dir: str | None = None
) -> str

Convierte todas las páginas a texto plano.

doc.to_markdown(
    page: int,
    preserve_layout: bool = False,
    detect_headings: bool = True,
    include_images: bool = True,
    image_output_dir: str | None = None,
    embed_images: bool = True,
    include_form_fields: bool = True
) -> str

Convierte una página a Markdown.

doc.to_markdown_all(
    preserve_layout: bool = False,
    detect_headings: bool = True,
    include_images: bool = True,
    image_output_dir: str | None = None,
    embed_images: bool = True,
    include_form_fields: bool = True
) -> str

Convierte todas las páginas a Markdown.

doc.to_html(
    page: int,
    preserve_layout: bool = False,
    detect_headings: bool = True,
    include_images: bool = True,
    image_output_dir: str | None = None,
    embed_images: bool = True,
    include_form_fields: bool = True
) -> str

Convierte una página a HTML.

doc.to_html_all(
    preserve_layout: bool = False,
    detect_headings: bool = True,
    include_images: bool = True,
    image_output_dir: str | None = None,
    embed_images: bool = True,
    include_form_fields: bool = True
) -> str

Convierte todas las páginas a HTML.

Conversión a Office

Método Tipo de retorno Descripción
to_docx(path) Convierte el PDF a un archivo de documento de Word
to_docx_bytes() bytes Convierte el PDF a bytes DOCX
to_pptx(path) Convierte el PDF a un archivo de PowerPoint
to_pptx_bytes() bytes Convierte el PDF a bytes PPTX
to_xlsx(path) Convierte el PDF a un archivo de libro de Excel
to_xlsx_bytes() bytes Convierte el PDF a bytes XLSX

Extracción de imágenes

doc.extract_images(page: int) -> list[ImageInfo]

Extrae todas las imágenes de una página, incluidas las imágenes en content streams y Form XObjects anidados.

doc.extract_image_bytes(page: int) -> list[dict]

Extrae los bytes crudos de las imágenes de una página. Cada dict contiene width, height, data (bytes) y format.

Búsqueda

doc.search(
    pattern: str,
    case_insensitive: bool = False,
    literal: bool = False,
    whole_word: bool = False,
    max_results: int = 0
) -> list[SearchResult]

Busca texto en todas las páginas. Usa max_results=0 para resultados ilimitados. Devuelve una lista de coincidencias con número de página, texto y coordenadas.

doc.search_page(
    page: int,
    pattern: str,
    case_insensitive: bool = False,
    literal: bool = False,
    whole_word: bool = False,
    max_results: int = 0
) -> list[SearchResult]

Busca texto en una sola página.

Edición de metadatos

Método Parámetros Descripción
set_title(title) str Establece el título del documento
set_author(author) str Establece el autor del documento
set_subject(subject) str Establece el asunto del documento
set_keywords(keywords) str Establece las palabras clave del documento

Rotación de páginas

Método Parámetros Devuelve Descripción
page_rotation(page) int int Obtiene la rotación actual (0, 90, 180, 270)
set_page_rotation(page, degrees) int, int Establece la rotación absoluta
rotate_page(page, degrees) int, int Suma a la rotación actual
rotate_all_pages(degrees) int Rota todas las páginas

Dimensiones de página

Método Parámetros Devuelve Descripción
page_media_box(page) int tuple[float, float, float, float] Obtiene el MediaBox (llx, lly, urx, ury)
set_page_media_box(page, llx, lly, urx, ury) int, float, float, float, float Establece el MediaBox
page_crop_box(page) int `tuple None`
set_page_crop_box(page, llx, lly, urx, ury) int, float, float, float, float Establece el CropBox
crop_margins(left, right, top, bottom) float, float, float, float Recorta los márgenes de todas las páginas

Borrar / Whiteout

Método Parámetros Descripción
erase_region(page, llx, lly, urx, ury) int, float, float, float, float Borra una región rectangular
erase_regions(page, rects) int, list[tuple] Borra varias regiones
clear_erase_regions(page) int Cancela las operaciones de borrado pendientes

Anotaciones

doc.get_annotations(page: int) -> list[dict]

Obtiene los metadatos de las anotaciones (tipo, rect, contenido, etc.) de una página.

Método Parámetros Devuelve Descripción
flatten_page_annotations(page) int Aplana las anotaciones de una página
flatten_all_annotations() Aplana todas las anotaciones
is_page_marked_for_flatten(page) int bool Comprueba si la página está marcada para aplanar
unmark_page_for_flatten(page) int Desmarca una página para aplanar

Redacción (Redaction)

doc.add_redaction(
    page: int,
    rect: tuple[float, float, float, float],
    fill: tuple[float, float, float] | None = None
) -> None

Marca una región rectangular para redacción con un color de relleno RGB opcional.

doc.redaction_count(page: int) -> int

Devuelve el número de redacciones pendientes en una página.

doc.apply_redactions_destructive(
    scrub_metadata: bool = True,
    remove_javascript: bool = True,
    remove_embedded_files: bool = True,
    fill: tuple[float, float, float] = (0.0, 0.0, 0.0)
) -> None

Aplica todas las redacciones de forma destructiva, eliminando el contenido subyacente y, opcionalmente, depurando metadatos, JavaScript y archivos embebidos.

doc.sanitize_document(
    scrub_metadata: bool = True,
    remove_javascript: bool = True,
    remove_embedded_files: bool = True
) -> None

Sanea el documento sin redactar regiones: elimina metadatos, JavaScript y/o archivos embebidos.

Método Parámetros Devuelve Descripción
apply_page_redactions(page) int Aplica las redacciones de una página
apply_all_redactions() Aplica todas las redacciones pendientes
is_page_marked_for_redaction(page) int bool Comprueba si la página está marcada para redacción
unmark_page_for_redaction(page) int Desmarca una página para redacción

Capas y tintas

Método Parámetros Devuelve Descripción
get_layers() list[str] Lista los nombres de las capas de contenido opcional (OCG)
get_page_inks(page) int list[str] Lista los nombres de colorantes de tinta / separación de una página
get_page_inks_deep(page) int list[str] Lista las tintas, incluidas las anidadas en Form XObjects

Limpieza de cabeceras / pies de página

doc.remove_headers(threshold: float = 0.8) -> int
doc.remove_footers(threshold: float = 0.8) -> int
doc.remove_artifacts(threshold: float = 0.8) -> int

Detecta y elimina cabeceras, pies de página o artefactos de página que se repiten a lo largo del documento. threshold es la proporción de repetición entre páginas. Devuelve el número de elementos eliminados.

Método Parámetros Descripción
erase_header(page) int Borra la región de cabecera detectada en una página
edit_header(page) int Marca la región de cabecera para edición
erase_footer(page) int Borra la región de pie de página detectada en una página
edit_footer(page) int Marca la región de pie de página para edición
erase_artifacts(page) int Borra los artefactos detectados en una página
sync_editor_erasures() Vuelca al editor los borrados pendientes de cabeceras/pies/artefactos

Campos de formulario

doc.get_form_fields() -> list[FormField]

Obtiene todos los campos de formulario. Consulta FormField para ver sus propiedades.

doc.get_form_field_value(name: str) -> str | bool | list | None

Obtiene el valor de un campo de formulario por su nombre. Devuelve el tipo de Python adecuado según el tipo de campo.

doc.set_form_field_value(name: str, value: str | bool) -> None

Establece el valor de un campo de formulario por su nombre.

doc.has_xfa() -> bool

Comprueba si el documento contiene formularios XFA.

doc.export_form_data(path: str, format: str = "fdf") -> None

Exporta los datos del formulario a un archivo. Formatos admitidos: "fdf" y "xfdf".

Método Parámetros Descripción
flatten_forms() Aplana todos los campos de formulario en el contenido de la página
flatten_forms_on_page(page) int Aplana los formularios de una página concreta

Manipulación de imágenes

doc.page_images(page: int) -> list[dict]

Obtiene los nombres y los límites de las imágenes para operaciones de posicionamiento. Cada dict contiene name, bounds [x, y, width, height] y matrix.

Método Parámetros Descripción
reposition_image(page, name, x, y) int, str, float, float Mueve una imagen
resize_image(page, name, width, height) int, str, float, float Cambia el tamaño de una imagen
set_image_bounds(page, name, x, y, width, height) int, str, float, float, float, float Establece la posición y el tamaño de una imagen
clear_image_modifications(page) int Cancela las modificaciones de imagen pendientes
has_image_modifications(page) intbool Comprueba si hay modificaciones de imagen pendientes

Operaciones sobre el documento

doc.merge_from(source: str | PdfDocument) -> int

Fusiona las páginas de otro PDF. Acepta una ruta de archivo o una instancia de PdfDocument. Devuelve el número de páginas fusionadas.

doc.embed_file(name: str, data: bytes) -> None

Adjunta un archivo al PDF.

doc.get_outline() -> list[dict] | None

Obtiene los marcadores / índice de contenido del documento. Devuelve None si no existe un esquema.

doc.extract_paths(page: int, region: tuple | None = None) -> list[dict]

Obtiene los trazados vectoriales (líneas, curvas, formas) de una página.

doc.extract_rects(page: int, region: tuple | None = None) -> list[dict]

Obtiene los rectángulos alineados con los ejes (de trazados rellenos/contorneados) de una página.

doc.extract_lines(page: int, region: tuple | None = None) -> list[dict]

Obtiene los segmentos de línea recta de una página.

doc.extract_tables(page: int, region: tuple | None = None, table_settings: dict | None = None) -> list[dict]

Detecta y extrae tablas. Cada tabla es un dict con filas y celdas (texto + cajas delimitadoras). Pasa table_settings para ajustar la estrategia de detección.

doc.extract_structured(page: int) -> str

Extrae la página como un documento JSON estructurado (orden de lectura lógico, bloques y roles).

doc.page_labels() -> list[dict]

Obtiene los rangos de etiquetas de página. Cada dict contiene start_page, style, prefix y start_value.

doc.xmp_metadata() -> dict | None

Obtiene los metadatos XMP como un diccionario con campos como dc_title, dc_creator, xmp_create_date, etc. Devuelve None si no existen metadatos XMP.

OCR

doc.extract_text_ocr(page: int, engine: OcrEngine | None = None) -> str

Extrae texto mediante OCR. Requiere la feature ocr en la compilación de Rust. Pasa un OcrEngine personalizado o None para el motor por defecto.

Extracción y reordenación de páginas

doc.extract_pages(pages: list[int], output: str) -> None

Extrae los índices de página indicados en un nuevo archivo PDF en output.

doc.extract_pages_to_bytes(pages: list[int]) -> bytes

Extrae los índices de página indicados en un nuevo PDF devuelto como bytes.

doc.extract_page_ranges_to_bytes(ranges: list[tuple[int, int]]) -> bytes

Extrae uno o varios rangos de páginas (start, end) en un nuevo PDF devuelto como bytes.

Método Parámetros Descripción
select_pages(pages) list[int] Conserva solo las páginas indicadas, en el orden dado
delete_page(index) int Elimina una sola página
move_page(from_index, to_index) int, int Mueve una página a una nueva posición

Conformidad y validación

doc.validate_pdf_a(level: str = "1b") -> dict

Valida frente a un nivel de conformidad PDF/A (p. ej. "1b", "2b", "3b"). Devuelve un dict de informe.

doc.convert_to_pdf_a(level: str = "2b") -> dict

Convierte el documento a PDF/A y devuelve un dict de informe de conversión.

doc.validate_pdf_ua() -> dict

Valida frente a los requisitos de PDF/UA (accesibilidad).

doc.validate_pdf_x(level: str = "1a_2001") -> dict

Valida frente a un nivel de conformidad PDF/X (producción de impresión).

Permisos y advertencias

doc.permissions() -> dict

Devuelve los flags de permisos de cifrado del documento (imprimir, copiar, modificar, anotar, etc.).

doc.structured_warnings() -> list

Devuelve las advertencias recopiladas durante la extracción de contenido estructurado / etiquetado.

doc.flatten_warnings() -> list[str]

Devuelve las advertencias recopiladas durante el aplanado de formularios/anotaciones.

Firmas y Document Security Store

doc.signatures() -> list[Signature]

Devuelve todas las firmas digitales del documento. Consulta Signature.

doc.signature_count() -> int

Devuelve el número de firmas digitales.

doc.dss() -> Dss | None

Devuelve el Document Security Store (material LTV) analizado del documento, o None. Consulta Dss.

API de páginas (v0.3.34)

PdfDocument es iterable e indexable, y devuelve objetos Page perezosos. Consulta Page.

len(doc)                  # number of pages
doc[i]                    # page at index i (negative indexing supported)
doc[-1]                   # last page
for page in doc: ...      # iterate pages

Acceso al DOM

doc.page(index: int) -> PdfPage

Obtiene un handle de página tipo DOM para edición a nivel de elemento. Consulta PdfPage.

doc.save_page(page: PdfPage) -> None

Guarda en el documento una PdfPage modificada.

Renderizado

doc.render_page(
    page: int,
    dpi: int | None = None,
    format: str | None = None,
    background: tuple[float, float, float, float] | None = None,
    transparent: bool = False,
    render_annotations: bool | None = None,
    jpeg_quality: int | None = None,
    excluded_layers: list[str] | None = None
) -> bytes

Renderiza una página a bytes PNG o JPEG con control sobre el DPI, el fondo, la transparencia, el renderizado de anotaciones, la calidad JPEG y las capas excluidas.

doc.render_pixmap(page: int, dpi: int | None = None) -> RenderedPixmap

Renderiza una página a un RenderedPixmap RGBA crudo (named tuple con width, height, data).

doc.render_separations(page: int, dpi: int | None = None) -> list[SeparationPlate]

Renderiza las planchas de separación por tinta de una página. Devuelve una lista de named tuples SeparationPlate (name, width, height, data).

doc.render_separation(page: int, ink_name: str, dpi: int | None = None) -> SeparationPlate

Renderiza la plancha de separación de una sola tinta con nombre.

Método Tipo de retorno Descripción
render_page_fit(page, fit_width, fit_height, format=0) bytes Renderiza una página escalada para ajustarse a una caja de píxeles
flatten_to_images(dpi=150) bytes Aplana todas las páginas a un PDF basado en imágenes

Guardado

doc.save(path: str, compress: bool = True, garbage_collect: bool = True, linearize: bool = False) -> None

Guarda el PDF en un archivo. Activa o desactiva la compresión de streams, la recolección de objetos muertos y la linealización (visualización web rápida).

doc.to_bytes(compress: bool = True, garbage_collect: bool = True, linearize: bool = False) -> bytes

Serializa el PDF a bytes con las mismas opciones que save().

doc.save_encrypted(
    path: str,
    user_password: str,
    owner_password: str | None = None,
    allow_print: bool = True,
    allow_copy: bool = True,
    allow_modify: bool = True,
    allow_annotate: bool = True
) -> None

Guarda con protección por contraseña AES-256 y controles de permisos. Si owner_password es None, se utiliza la contraseña de usuario.

doc.to_bytes_encrypted(
    user_password: str,
    owner_password: str | None = None,
    allow_print: bool = True,
    allow_copy: bool = True,
    allow_modify: bool = True,
    allow_annotate: bool = True
) -> bytes

Serializa un PDF cifrado con AES-256 a bytes.


Page

Un handle de página perezoso devuelto por doc[i] o al iterar sobre PdfDocument. Todas las propiedades se calculan al acceder a ellas y se delegan al documento padre.

from pdf_oxide import PdfDocument

with PdfDocument("paper.pdf") as doc:
    page = doc[0]
    text = page.text
    md = page.markdown(detect_headings=True)

Propiedades (perezosas)

Propiedad Tipo Descripción
index int Índice de página basado en cero
width, height float Dimensiones de la página en puntos PDF
bbox tuple[float, 4] (llx, lly, urx, ury)
text str Texto plano extraído
chars, words, lines, spans list[...] Texto estructurado
tables list[dict] Tablas con filas + celdas (texto + bboxes)
images, paths, annotations list[...] Contenido de la página

Métodos

page.markdown(preserve_layout=False, detect_headings=True,
              include_images=False, image_output_dir=None,
              embed_images=True, include_form_fields=True) -> str
page.plain_text(...) -> str
page.html(...) -> str
page.render(dpi=None, format=None, background=None, transparent=False,
            render_annotations=None, jpeg_quality=None, excluded_layers=None) -> bytes
page.render_pixmap(dpi=None) -> RenderedPixmap
page.search(pattern, case_insensitive=False, literal=False,
            whole_word=False, max_results=100) -> list
page.region(x, y, width, height) -> PdfPageRegion

El objeto de página perezoso también se expone como doc.pages() (un iterador equivalente a iterar el documento directamente).


PdfPage

Handle de página tipo DOM para acceso y edición a nivel de elemento. Se obtiene mediante PdfDocument.page().

from pdf_oxide import PdfDocument

doc = PdfDocument("file.pdf")
page = doc.page(0)

Propiedades

Propiedad Tipo Descripción
index int Índice de página basado en cero
width float Ancho de la página en puntos PDF
height float Alto de la página en puntos PDF

Métodos

page.children() -> list[PdfElement]

Obtiene todos los elementos de la página.

page.find_text_containing(needle: str) -> list[PdfText]

Encuentra todos los elementos de texto que contienen la subcadena dada.

page.find_images() -> list[PdfImage]

Encuentra todos los elementos de imagen de la página.

page.get_element(element_id: str) -> PdfElement | None

Obtiene un elemento concreto por su ID.

page.set_text(text_id: PdfTextId, new_text: str) -> None

Reemplaza el contenido de texto de un elemento identificado por su PdfTextId.

page.annotations() -> list[PdfAnnotation]

Obtiene todas las anotaciones de la página.

page.add_link(x: float, y: float, width: float, height: float, url: str) -> str

Añade una anotación de enlace URL. Devuelve el ID de la anotación.

page.add_highlight(x: float, y: float, width: float, height: float, color: tuple[float, float, float]) -> str

Añade una anotación de resaltado con un color RGB. Devuelve el ID de la anotación.

page.add_note(x: float, y: float, text: str) -> str

Añade una anotación de nota adhesiva. Devuelve el ID de la anotación.

page.remove_annotation(index: int) -> bool

Elimina una anotación por su índice. Devuelve True si se eliminó.

page.add_text(text: str, x: float, y: float, font_size: float = 12.0) -> PdfTextId

Añade texto nuevo a la página. Devuelve un PdfTextId para referencia posterior.

page.remove_element(element_id: PdfTextId) -> bool

Elimina un elemento por su ID. Devuelve True si se eliminó.

Ejemplo

from pdf_oxide import PdfDocument

doc = PdfDocument("invoice.pdf")
page = doc.page(0)

# Find and replace text
for text in page.find_text_containing("DRAFT"):
    page.set_text(text.id, "FINAL")

# Add a link
page.add_link(100, 700, 200, 20, "https://example.com")

doc.save_page(page)
doc.save("invoice_updated.pdf")

Pdf

La clase unificada para crear PDFs a partir de distintos formatos de origen.

from pdf_oxide import Pdf

Métodos de fábrica

Pdf.from_markdown(content: str, title: str | None = None, author: str | None = None) -> Pdf

Crea un PDF a partir de contenido Markdown.

Pdf.from_html(content: str, title: str | None = None, author: str | None = None) -> Pdf

Crea un PDF a partir de contenido HTML.

Pdf.from_text(content: str, title: str | None = None, author: str | None = None) -> Pdf

Crea un PDF a partir de texto plano.

Pdf.from_markdown_with_template(content: str, template: str, title: str | None = None, author: str | None = None) -> Pdf

Crea un PDF a partir de Markdown renderizado mediante una plantilla CSS/de maquetación con nombre.

Pdf.from_image(path: str) -> Pdf

Crea un PDF de una sola página a partir de un archivo de imagen (JPEG, PNG).

Pdf.from_bytes(data: bytes) -> Pdf

Abre un PDF existente a partir de bytes en memoria para modificarlo. Útil para cargar PDFs descargados de S3, HTTP o bases de datos.

from pdf_oxide import Pdf

pdf = Pdf.from_bytes(existing_pdf_bytes)
pdf.save("modified.pdf")
Pdf.from_images(paths: list[str]) -> Pdf

Crea un PDF de varias páginas a partir de varios archivos de imagen, una página por imagen.

Pdf.from_image_bytes(data: bytes) -> Pdf

Crea un PDF de una sola página a partir de bytes de imagen.

Pdf.merge(paths: list[str]) -> Pdf

Fusiona varios archivos PDF (por ruta) en un único Pdf.

Métodos

pdf.save(path: str) -> None

Guarda el PDF en un archivo.

pdf.to_bytes() -> bytes

Obtiene el contenido del PDF como bytes.

len(pdf) -> int

Obtiene el tamaño del PDF en bytes (mediante __len__).


PdfText

Representa un elemento de texto en una página. Devuelto por PdfPage.find_text_containing().

Propiedad Tipo Descripción
id PdfTextId Identificador único del elemento
value str Contenido de texto
text str Contenido de texto (alias de value)
bbox tuple[float, float, float, float] Caja delimitadora (x0, y0, x1, y1)
font_name str Nombre PostScript de la fuente
font_size float Tamaño de fuente en puntos
is_bold bool Si el texto está en negrita
is_italic bool Si el texto está en cursiva

Métodos

Método Parámetros Devuelve Descripción
contains(needle) str bool Comprueba si el texto contiene una subcadena
starts_with(prefix) str bool Comprueba si el texto empieza por un prefijo
ends_with(suffix) str bool Comprueba si el texto termina en un sufijo

PdfImage

Representa un elemento de imagen en una página. Devuelto por PdfPage.find_images().

Propiedad Tipo Descripción
bbox tuple[float, float, float, float] Caja delimitadora (x0, y0, x1, y1)
width int Ancho de la imagen en píxeles
height int Alto de la imagen en píxeles
aspect_ratio float Relación ancho / alto

PdfAnnotation

Representa una anotación en una página. Devuelta por PdfPage.annotations().

Propiedad Tipo Descripción
subtype str Tipo de anotación (p. ej. "Link", "Highlight", "Text")
rect tuple[float, float, float, float] Posición (x0, y0, x1, y1)
contents `str None`
color `tuple[float, float, float] None`
is_modified bool Si la anotación ha sido modificada
is_new bool Si la anotación es de nueva incorporación

PdfElement

Envoltorio genérico de elemento. Devuelto por PdfPage.children().

Método Devuelve Descripción
is_text() bool Comprueba si el elemento es texto
is_image() bool Comprueba si el elemento es una imagen
is_path() bool Comprueba si el elemento es un trazado vectorial
is_table() bool Comprueba si el elemento es una tabla
is_structure() bool Comprueba si el elemento es un elemento de estructura
as_text() `PdfText None`
as_image() `PdfImage None`
Propiedad Tipo Descripción
bbox tuple[float, float, float, float] Caja delimitadora

TextChar

Representa un único carácter con posicionamiento y metadatos de fuente. Devuelto por PdfDocument.extract_chars().

from pdf_oxide import TextChar  # or access via PdfDocument
Atributo Tipo Descripción
char str El carácter Unicode
bbox tuple[float, float, float, float] Caja delimitadora (x0, y0, x1, y1)
font_name str Nombre PostScript de la fuente
font_size float Tamaño de fuente en puntos
font_weight str Peso ("thin", "light", "normal", "medium", "semi-bold", "bold", "extra-bold", "black")
is_italic bool Si el carácter está en cursiva
color tuple[float, float, float] Color RGB (r, g, b), valores 0.0–1.0
rotation_degrees float Rotación del carácter en grados
origin_x float Posición X del origen del texto
origin_y float Posición Y del origen del texto
advance_width float Ancho de avance del glifo
mcid `int None`

Ejemplo

from pdf_oxide import PdfDocument

doc = PdfDocument("paper.pdf")
chars = doc.extract_chars(0)

for ch in chars[:5]:
    print(f"'{ch.char}' at bbox={ch.bbox} "
          f"font={ch.font_name} size={ch.font_size:.1f} "
          f"weight={ch.font_weight} italic={ch.is_italic}")

TextSpan

Representa una secuencia de texto que comparte la misma fuente y estilo. Devuelto por PdfDocument.extract_spans().

Atributo Tipo Descripción
text str El contenido de texto
bbox tuple[float, float, float, float] Caja delimitadora (x0, y0, x1, y1)
font_name str Nombre PostScript de la fuente
font_size float Tamaño de fuente en puntos
is_bold bool Si el span está en negrita
is_italic bool Si el span está en cursiva
is_monospace bool Si la fuente es de ancho fijo (Courier, Consolas, etc.)
char_widths list[float] Anchos de avance por glifo para cajas delimitadoras precisas
color tuple[float, float, float] Color RGB (r, g, b), valores 0.0–1.0

Ejemplo

from pdf_oxide import PdfDocument

doc = PdfDocument("paper.pdf")
spans = doc.extract_spans(0)

for span in spans:
    print(f"'{span.text}' font={span.font_name} size={span.font_size:.1f} "
          f"bold={span.is_bold} italic={span.is_italic} color={span.color}")

Extracción de imágenes

extract_images() devuelve objetos ImageInfo con metadatos de imagen. Usa extract_image_bytes() para obtener los datos crudos de imagen aptos para guardar en disco.

Formato de retorno de extract_image_bytes()

Cada dict devuelto por extract_image_bytes() tiene las siguientes claves:

Clave Tipo Descripción
width int Ancho de la imagen en píxeles
height int Alto de la imagen en píxeles
data bytes Datos crudos de la imagen
format str Formato de la imagen (p. ej. "png", "jpeg")

Ejemplo

from pdf_oxide import PdfDocument

doc = PdfDocument("brochure.pdf")
images = doc.extract_image_bytes(0)

for i, img in enumerate(images):
    print(f"Image {i}: {img['width']}x{img['height']}")
    with open(f"image_{i}.{img['format']}", "wb") as f:
        f.write(img["data"])

SearchResult

Representa una coincidencia de búsqueda de texto. Devuelto por search() y search_page().

Atributo Tipo Descripción
page int Índice de página basado en cero
text str Texto coincidente
x float Posición X en puntos PDF
y float Posición Y en puntos PDF

FormField

Representa un campo de formulario. Devuelto por PdfDocument.get_form_fields().

Propiedad Tipo Descripción
name str Nombre completamente cualificado del campo
field_type str Tipo de campo: "text", "button", "choice", "signature" o "unknown"
value `str bool
tooltip `str None`
bounds `tuple[float, float, float, float] None`
flags `int None`
max_length `int None`
is_readonly bool Si el campo es de solo lectura
is_required bool Si el campo es obligatorio

TextWord

Una secuencia de texto agrupada por palabras. Devuelta por PdfDocument.extract_words() y PdfPageRegion.extract_words().

Propiedad Tipo Descripción
text str El texto de la palabra
bbox tuple[float, float, float, float] Caja delimitadora (x0, y0, x1, y1)
font_name str Nombre PostScript de la fuente
font_size float Tamaño de fuente en puntos
is_bold bool Si la palabra está en negrita
is_italic bool Si la palabra está en cursiva
chars list[TextChar] Caracteres que la componen

TextLine

Una secuencia de texto agrupada por líneas. Devuelta por PdfDocument.extract_text_lines() y PdfPageRegion.extract_text_lines().

Propiedad Tipo Descripción
text str El texto de la línea
bbox tuple[float, float, float, float] Caja delimitadora (x0, y0, x1, y1)
words list[TextWord] Palabras de la línea
chars list[TextChar] Caracteres de la línea

PdfPageRegion

Una región recortada de una página. Devuelta por PdfDocument.within() y PdfPage.region().

Propiedad Tipo Descripción
bbox tuple[float, float, float, float] Los límites de la región

Métodos

region.extract_text() -> str
region.extract_words() -> list[TextWord]
region.extract_text_lines() -> list[TextLine]
region.extract_tables(table_settings: dict | None = None) -> list[dict]
region.extract_images() -> list
region.extract_paths() -> list

Métodos de extracción acotados a la caja delimitadora de la región.


LayoutParams

Parámetros de maquetación adaptativos calculados para una página. Devueltos por PdfDocument.page_layout_params().

Propiedad Tipo Descripción
word_gap_threshold float Umbral de separación entre palabras en puntos
line_gap_threshold float Umbral de separación entre líneas en puntos
median_char_width float Ancho mediano de carácter
median_font_size float Tamaño mediano de fuente
median_line_spacing float Interlineado mediano
column_count int Número de columnas de texto detectadas

ExtractionProfile

Un perfil de extracción de texto ajustable que se pasa a extract_words() / extract_text_lines().

from pdf_oxide import ExtractionProfile

Constructores estáticos

ExtractionProfile.conservative()
ExtractionProfile.aggressive()
ExtractionProfile.balanced()
ExtractionProfile.academic()
ExtractionProfile.policy()
ExtractionProfile.form()
ExtractionProfile.government()
ExtractionProfile.scanned_ocr()
ExtractionProfile.adaptive()
ExtractionProfile.available() -> list[str]   # names of all built-in profiles

Propiedades

Propiedad Tipo Descripción
name str Nombre del perfil
tj_offset_threshold float Umbral de salto de palabra por offset del array TJ
word_margin_ratio float Proporción de margen de palabra
space_threshold_em_ratio float Umbral de ancho de espacio (proporción em)
space_char_multiplier float Multiplicador de carácter de espacio
use_adaptive_threshold bool Si los umbrales adaptativos están habilitados

OfficeConverter

Convierte documentos de Office (DOCX, XLSX, PPTX) a PDF. Requiere la feature office en la compilación de Rust.

from pdf_oxide import OfficeConverter

OfficeConverter()   # instances are stateless; the conversion methods are also usable as static methods

Métodos

OfficeConverter.from_docx(path: str) -> Pdf

Convierte un documento de Word a un objeto Pdf.

OfficeConverter.from_docx_bytes(data: bytes) -> Pdf

Convierte bytes de un documento de Word a un objeto Pdf.

OfficeConverter.from_xlsx(path: str) -> Pdf

Convierte una hoja de cálculo de Excel a un objeto Pdf.

OfficeConverter.from_xlsx_bytes(data: bytes) -> Pdf

Convierte bytes de una hoja de cálculo de Excel a un objeto Pdf.

OfficeConverter.from_pptx(path: str) -> Pdf

Convierte una presentación de PowerPoint a un objeto Pdf.

OfficeConverter.from_pptx_bytes(data: bytes) -> Pdf

Convierte bytes de una presentación de PowerPoint a un objeto Pdf.

OfficeConverter.convert(path: str) -> Pdf

Autodetecta el formato y convierte cualquier documento de Office admitido a un objeto Pdf.

Ejemplo

from pdf_oxide import OfficeConverter

pdf = OfficeConverter.from_docx("report.docx")
pdf.save("report.pdf")

# Or use convert() for auto-detection
pdf = OfficeConverter.convert("spreadsheet.xlsx")
pdf.save("spreadsheet.pdf")

Clases de gráficos

Estas clases están disponibles para la creación avanzada de PDFs con gráficos:

Color

from pdf_oxide import Color

Color(r: float, g: float, b: float)  # RGB, values 0.0-1.0
Color.from_hex("#ff0000")
Color.black()
Color.white()
Color.red()
Color.green()
Color.blue()

BlendMode

from pdf_oxide import BlendMode

BlendMode.NORMAL()
BlendMode.MULTIPLY()
BlendMode.SCREEN()
BlendMode.OVERLAY()
BlendMode.DARKEN()
BlendMode.LIGHTEN()
BlendMode.COLOR_DODGE()
BlendMode.COLOR_BURN()
BlendMode.HARD_LIGHT()
BlendMode.SOFT_LIGHT()
BlendMode.DIFFERENCE()
BlendMode.EXCLUSION()

ExtGState

from pdf_oxide import ExtGState

gs = ExtGState()
gs = gs.fill_alpha(0.5)
gs = gs.stroke_alpha(0.8)
gs = gs.alpha(0.5)  # Set both fill and stroke
gs = gs.blend_mode(BlendMode.MULTIPLY())

gs = ExtGState.semi_transparent()  # Preset

LineCap / LineJoin

from pdf_oxide import LineCap, LineJoin

LineCap.BUTT()       # Default
LineCap.ROUND()
LineCap.SQUARE()

LineJoin.MITER()     # Default
LineJoin.ROUND()
LineJoin.BEVEL()

Gradientes

from pdf_oxide import LinearGradient, RadialGradient, Color

# Linear gradient (fluent API)
grad = (LinearGradient()
    .start(0, 0)
    .end(100, 0)
    .add_stop(0.0, Color.red())
    .add_stop(1.0, Color.blue()))

# Convenience constructors
hgrad = LinearGradient.horizontal(200, Color.red(), Color.blue())
vgrad = LinearGradient.vertical(100, Color(1, 1, 0), Color(0, 0, 1))

# Radial gradient
rgrad = RadialGradient.centered(50, 50, 50)
rgrad = rgrad.add_stop(0.0, Color(1, 1, 0))
rgrad = rgrad.add_stop(1.0, Color(1, 0, 0))

PatternPresets

from pdf_oxide import PatternPresets, Color

PatternPresets.horizontal_stripes(width, height, stripe_height, color)
PatternPresets.vertical_stripes(width, height, stripe_width, color)
PatternPresets.checkerboard(size, color1, color2)
PatternPresets.dots(spacing, radius, color)
PatternPresets.diagonal_lines(size, line_width, color)
PatternPresets.crosshatch(size, line_width, color)

Clases de OCR

Requiere la feature ocr en la compilación de Rust.

OcrEngine

from pdf_oxide import OcrEngine, OcrConfig

engine = OcrEngine(
    det_model_path: str,
    rec_model_path: str,
    dict_path: str,
    config: OcrConfig | None = None
)

OcrConfig

from pdf_oxide import OcrConfig

config = OcrConfig(
    det_threshold: float | None = None,
    box_threshold: float | None = None,
    rec_threshold: float | None = None,
    num_threads: int | None = None,
    max_candidates: int | None = None,
    use_v5: bool = False
)

DocumentBuilder

Builder fluido para componer PDFs página a página. Consulta el ejemplo de más abajo y Crear desde cero.

from pdf_oxide import DocumentBuilder

Métodos a nivel de documento

Método Parámetros Descripción
DocumentBuilder() Construye un nuevo builder
title(title) str Establece el título del documento
author(author) str Establece el autor del documento
subject(subject) str Establece el asunto del documento
keywords(keywords) str Establece las palabras clave del documento
creator(creator) str Establece el nombre de la aplicación productora
on_open(script) str Establece una acción JavaScript de apertura a nivel de documento
tagged_pdf_ua1() Emite un documento accesible Tagged PDF/UA-1
language(lang) str Establece el idioma del documento (p. ej. "en-US")
role_map(custom, standard) str, str Asigna una etiqueta de estructura personalizada a una estándar
register_embedded_font(name, font) str, EmbeddedFont Registra una fuente (consume el EmbeddedFont)

Fábricas de páginas

builder.a4_page() -> FluentPageBuilder       # 595 x 842 pt
builder.letter_page() -> FluentPageBuilder   # 612 x 792 pt
builder.page(width: float, height: float) -> FluentPageBuilder

Salida

builder.build() -> bytes
builder.save(path: str) -> None
builder.save_encrypted(path: str, user_password: str, owner_password: str) -> None
builder.to_bytes_encrypted(user_password: str, owner_password: str) -> bytes

FluentPageBuilder

Almacena en búfer las operaciones a nivel de página hasta done(). Devuelto por DocumentBuilder.a4_page() / letter_page() / page(). Cada método devuelve self para encadenar; done() confirma la página y devuelve el DocumentBuilder padre.

Texto y maquetación

Método Parámetros Descripción
font(name, size) str, float Establece la fuente y el tamaño actuales
at(x, y) float, float Mueve el cursor a una posición absoluta
text(text) str Dibuja texto en el cursor
heading(level, text) int, str Dibuja un encabezado (nivel 1–6)
paragraph(text) str Dibuja un párrafo con ajuste de línea
space(points) float Avanza espacio vertical
horizontal_rule() Dibuja un divisor horizontal
columns(column_count, gap_pt, text) int, float, str Flujo de texto multicolumna equilibrado
footnote(ref_mark, note_text) str, str Marca de referencia en línea + nota al pie de página
new_page_same_size() Inicia una nueva página con las mismas dimensiones
measure(text) -> float str Mide el ancho del texto renderizado en puntos
remaining_space() -> float Espacio vertical restante en la página

Secuencias en línea

page.inline(text: str)
page.inline_bold(text: str)
page.inline_italic(text: str)
page.inline_color(text: str, r: float, g: float, b: float)
page.newline()

Enlaces y acciones

page.link_url(url: str)
page.link_page(page: int)
page.link_named(name: str)
page.link_javascript(script: str)
page.on_open(script: str)
page.on_close(script: str)
page.field_keystroke(script: str)
page.field_format(script: str)
page.field_validate(script: str)
page.field_calculate(script: str)

Anotaciones de marcado

page.highlight(color: tuple[float, float, float])
page.underline(color: tuple[float, float, float])
page.strikeout(color: tuple[float, float, float])
page.squiggly(color: tuple[float, float, float])
page.sticky_note(text: str)
page.sticky_note_at(x: float, y: float, text: str)
page.watermark(text: str)
page.watermark_confidential()
page.watermark_draft()
page.stamp(name: str)
page.freetext(x: float, y: float, w: float, h: float, text: str)

Widgets de AcroForm

page.text_field(name: str, x: float, y: float, w: float, h: float, default_value: str | None = None)
page.checkbox(name: str, x: float, y: float, w: float, h: float, checked: bool = False)
page.combo_box(name: str, x: float, y: float, w: float, h: float, options: list[str], selected: str | None = None)
page.radio_group(name: str, buttons: list[tuple[str, float, float, float, float]], selected: str | None = None)
page.push_button(name: str, x: float, y: float, w: float, h: float, caption: str)
page.signature_field(name: str, x: float, y: float, w: float, h: float)

Gráficos

page.rect(x: float, y: float, w: float, h: float)
page.filled_rect(x: float, y: float, w: float, h: float, r: float, g: float, b: float)
page.line(x1: float, y1: float, x2: float, y2: float)
page.text_in_rect(x: float, y: float, w: float, h: float, text: str, align: int | None = None)
page.stroke_rect(x, y, w, h, width=1.0, color=(0.0, 0.0, 0.0))
page.stroke_rect_dashed(x, y, w, h, dash, width=1.0, color=(0.0, 0.0, 0.0), phase=0.0)
page.stroke_line(x1, y1, x2, y2, width=1.0, color=(0.0, 0.0, 0.0))
page.stroke_line_dashed(x1, y1, x2, y2, dash, width=1.0, color=(0.0, 0.0, 0.0), phase=0.0)

Imágenes y códigos de barras

page.image_with_alt(bytes: bytes, x: float, y: float, w: float, h: float, alt_text: str)
page.image_artifact(bytes: bytes, x: float, y: float, w: float, h: float)
page.barcode_1d(barcode_type: int, data: str, x: float, y: float, w: float, h: float)
page.barcode_qr(data: str, x: float, y: float, size: float)

barcode_type: 0=Code128, 1=Code39, 2=EAN13, 3=EAN8, 4=UPCA, 5=ITF, 6=Code93, 7=Codabar.

Tablas

page.table(table: Table)
page.streaming_table(
    columns: list[Column],
    repeat_header: bool = False,
    mode: str = "fixed",
    sample_rows: int = 50,
    min_col_width_pt: float = 20.0,
    max_col_width_pt: float = 400.0,
    max_rowspan: int = 1,
    batch_size: int = 256
) -> StreamingTable

Confirmar

page.done() -> DocumentBuilder

EmbeddedFont

Una fuente TTF/OTF registrada con un DocumentBuilder.

from pdf_oxide import EmbeddedFont

EmbeddedFont.from_file(path: str) -> EmbeddedFont
EmbeddedFont.from_bytes(data: bytes, name: str | None = None) -> EmbeddedFont
Propiedad Tipo Descripción
name str El nombre registrado de la fuente

Tablas

Objetos de valor para la API fluida de tablas.

Align

from pdf_oxide import Align

Align.LEFT     # 0
Align.CENTER   # 1
Align.RIGHT    # 2

Column

from pdf_oxide import Column

Column(header: str, width: float = 100.0, align: Align | int | None = None)
Propiedad Tipo Descripción
header str Texto del encabezado de columna
width float Ancho de la columna en puntos
align int Alineación de la celda

Table

from pdf_oxide import Table

Table(columns: list[Column], rows: list[list[str]], has_header: bool = False)

Una tabla con búfer consumida por FluentPageBuilder.table(). Con has_header=True, los encabezados de columna se renderizan como una fila de cabecera con estilo.

StreamingTable

Un handle de tabla con streaming de filas devuelto por FluentPageBuilder.streaming_table(), para tablas demasiado grandes como para materializarse de una vez.

Método Parámetros Descripción
push_row(cells) list[str] Añade una fila de cadenas de celda
push_row_span(cells) list[tuple[str, int]] Añade una fila de celdas (text, colspan)
flush() Vuelca el lote actual
finish() Finaliza la tabla, devolviendo el FluentPageBuilder
column_count() – → int Número de columnas
pending_row_count() – → int Filas en búfer pero aún no confirmadas
batch_count() – → int Número de lotes completados

Plantillas de página

Artefactos de cabecera/pie de página repetidos que se aplican a lo largo de las páginas.

Artifact / ArtifactStyle

from pdf_oxide import Artifact, ArtifactStyle

Artifact()                       # empty artifact
Artifact.center(text: str)       # centered artifact text
artifact.with_left(text: str)    # add left-aligned text

style = ArtifactStyle()
style = style.font(name: str, size: float)
style = style.bold()
from pdf_oxide import Header, Footer

Header()                  # or Header.center(text: str)
Footer()                  # or Footer.center(text: str)

PageTemplate

from pdf_oxide import PageTemplate, Header, Footer

template = (PageTemplate()
    .header(Header.center("Confidential"))
    .footer(Footer.center("Page")))

Firmas digitales

Firma, sella temporalmente y verifica PDFs (PAdES / LTV). Requiere las features signatures (y, opcionalmente, tsa-client) en la compilación de Rust.

Certificate

from pdf_oxide import Certificate

Certificate.load(data: bytes) -> Certificate                       # DER certificate (verify only)
Certificate.load_pem(cert_pem: str, key_pem: str) -> Certificate   # signing credential
Certificate.load_pkcs12(data: bytes, password: str) -> Certificate # PKCS#12 / .p12 signing credential
Método Devuelve Descripción
subject() str DN del sujeto del certificado
issuer() str DN del emisor del certificado
serial() str Número de serie
validity() tuple[int, int] Marcas de tiempo Unix (not_before, not_after)
is_valid() bool Si el certificado se encuentra actualmente dentro de su ventana de validez

Signature

Devuelta por PdfDocument.signatures().

Propiedad / Método Tipo Descripción
signer_name `str None`
reason `str None`
location `str None`
contact_info `str None`
signing_time `int None`
covers_whole_document bool Si la firma cubre todo el archivo
pades_level PadesLevel Línea base PAdES detectada (B-B/B-T/B-LT)
verify() bool Verifica la firma criptográficamente
verify_detached(pdf_data) bool Verifica incluyendo el messageDigest frente a los bytes del archivo

Timestamp

from pdf_oxide import Timestamp

Timestamp.parse(data: bytes) -> Timestamp
Propiedad / Método Tipo Descripción
time int Hora del sello temporal (Unix)
serial str Número de serie de la respuesta de la TSA
policy_oid str OID de política de la TSA
tsa_name str Nombre de la TSA
hash_algorithm int Código del algoritmo de hash del message-imprint
message_imprint bytes El message imprint con hash
verify() bool Verifica el token de sello temporal

TsaClient

from pdf_oxide import TsaClient

client = TsaClient(
    url: str,
    username: str | None = None,
    password: str | None = None,
    timeout_seconds: int = 30,
    hash_algorithm: int = 2,
    use_nonce: bool = True,
    cert_req: bool = True
)
client.request_timestamp(data: bytes) -> Timestamp
client.request_timestamp_hash(digest: bytes, algorithm: int = 2) -> Timestamp

PadesLevel

from pdf_oxide import PadesLevel

PadesLevel.B_B     # baseline
PadesLevel.B_T     # + trusted timestamp
PadesLevel.B_LT    # + long-term validation material
PadesLevel.B_LTA   # + archival timestamp

RevocationMaterial

from pdf_oxide import RevocationMaterial

RevocationMaterial(
    certs: list[bytes] | None = None,
    crls: list[bytes] | None = None,
    ocsps: list[bytes] | None = None
)

Certificados, CRLs y respuestas OCSP codificados en DER para la firma B-LT.

Dss

Un Document Security Store analizado, devuelto por PdfDocument.dss().

Propiedad Tipo Descripción
certs list[bytes] Blobs DER de certificados a nivel de documento
crls list[bytes] Blobs DER de CRL
ocsps list[bytes] Blobs DER de respuestas OCSP
vri list[str] Claves VRI por firma (SHA-1 en hex de /Contents)

Funciones a nivel de módulo

from pdf_oxide import (
    sign_pdf_bytes, sign_pdf_bytes_pades, has_document_timestamp,
    generate_barcode_svg, generate_qr_svg,
    plan_split_by_bookmarks, split_by_bookmarks,
)

Firma

sign_pdf_bytes(pdf_data: bytes, cert: Certificate, reason: str | None = None, location: str | None = None) -> bytes

Firma bytes crudos de PDF con un Certificate de firma cargado y devuelve el PDF firmado.

sign_pdf_bytes_pades(
    pdf_data: bytes,
    cert: Certificate,
    level: PadesLevel,
    tsa_url: str | None = None,
    reason: str | None = None,
    location: str | None = None,
    revocation: RevocationMaterial | None = None
) -> bytes

Firma bytes crudos de PDF en un nivel de línea base PAdES. B_T/B_LT requieren un tsa_url.

has_document_timestamp(pdf_data: bytes) -> bool

Si el PDF lleva un sello temporal de archivo RFC 3161 a nivel de documento (PAdES-B-LTA).

Códigos de barras

generate_barcode_svg(barcode_type: int, data: str) -> str
generate_qr_svg(data: str, error_correction: int, size: int) -> str

Genera un código de barras 1D o un código QR como una cadena SVG. Requiere la feature barcodes.

División por marcadores

plan_split_by_bookmarks(src_bytes: bytes, title_prefix: str | None = None, ignore_case: bool = False, level: int = 1, include_front_matter: bool = True) -> list[dict]
split_by_bookmarks(src_bytes: bytes, title_prefix: str | None = None, ignore_case: bool = False, level: int = 1, include_front_matter: bool = True) -> list[tuple[dict, bytes]]

Planifica o realiza la división de un PDF en los límites de los marcadores. plan_* devuelve solo los metadatos de los segmentos; split_* devuelve cada segmento emparejado con sus bytes de PDF.

Aprovisionamiento de modelos de OCR

prefetch_models(languages: list[str]) -> str
model_manifest() -> str
prefetch_available() -> bool

Aprovisiona modelos de OCR para uso sin conexión / en entornos aislados, inspecciona el manifiesto de modelos (JSON) y comprueba si esta compilación puede descargar modelos.

Logging

setup_logging() -> None
set_log_level(level: str) -> None     # "off" | "error" | "warn" | "info" | "debug" | "trace"
get_log_level() -> str
disable_logging() -> None

Ajuste del motor

set_max_ops_per_stream(limit: int | None) -> int | None
set_preserve_unmapped_glyphs(preserve: bool) -> bool

Ajusta el límite de operadores por stream (protección frente a entradas adversarias) y la preservación de U+FFFD para glifos sin mapear. Ambos devuelven el valor anterior.

Gobernanza criptográfica

crypto_active_provider() -> str
crypto_available_providers() -> list[str]
crypto_use_fips() -> None                 # install the FIPS aws-lc-rs provider (requires the fips feature)
crypto_set_policy(spec: str) -> None      # e.g. "strict" or "compat;deny:rc4@write"
crypto_policy() -> str
crypto_inventory() -> list[str]
crypto_cbom() -> str                      # CycloneDX 1.6 CBOM (JSON)

API asíncrona

Envoltorios async/await que ejecutan operaciones bloqueantes en un pool de hilos. Los métodos reflejan sus equivalentes síncronos.

from pdf_oxide import AsyncPdfDocument, AsyncPdf, AsyncOfficeConverter

async def main():
    doc = await AsyncPdfDocument.open("input.pdf")
    text = await doc.extract_text(0)
    await doc.close()
    # Or use as an async context manager:
    async with await AsyncPdfDocument.from_bytes(pdf_bytes) as doc:
        md = await doc.to_markdown_all()
Clase Constructores Notas
AsyncPdfDocument await AsyncPdfDocument.open(path, password=None), await AsyncPdfDocument.from_bytes(data, password=None) Todos los métodos de PdfDocument están disponibles como awaitables; admite async with y .close()
AsyncPdf envuelve los métodos de fábrica de Pdf await pdf.save(path), await pdf.to_bytes()
AsyncOfficeConverter envuelve los métodos estáticos de OfficeConverter p. ej. await AsyncOfficeConverter.from_docx(path)

Manejo de errores

PdfError

Todos los errores específicos del PDF lanzan PdfError:

from pdf_oxide import PdfDocument, PdfError

try:
    doc = PdfDocument("file.pdf")
    text = doc.extract_text(0)
except PdfError as e:
    print(f"PDF error: {e}")
except FileNotFoundError:
    print("File not found")
except IndexError:
    print("Page index out of range")

Escenarios de error habituales:

Excepción Causa
PdfError PDF mal formado, cifrado sin contraseña, fallo de análisis
FileNotFoundError El archivo no existe
IndexError El índice de página supera page_count()
ValueError Argumento no válido (p. ej. índice de página negativo)

Ejemplo completo

from pdf_oxide import PdfDocument, Pdf

# --- Extraction ---
doc = PdfDocument("input.pdf")
print(f"Pages: {doc.page_count()}")

for i in range(doc.page_count()):
    text = doc.extract_text(i)
    print(f"Page {i + 1}: {len(text)} characters")

# Character-level analysis
chars = doc.extract_chars(0)
fonts = set(ch.font_name for ch in chars)
print(f"Fonts on page 1: {fonts}")

# Image extraction
images = doc.extract_image_bytes(0)
for i, img in enumerate(images):
    with open(f"extracted_{i}.{img['format']}", "wb") as f:
        f.write(img["data"])

# --- Creation ---
pdf = Pdf.from_markdown("# Report\n\nGenerated by PDF Oxide.",
                        title="Report", author="PDF Oxide")
pdf.save("report.pdf")

# --- Editing ---
doc = PdfDocument("document.pdf")
doc.set_title("Updated Title")
doc.set_author("New Author")
doc.rotate_all_pages(90)

# Search and replace via DOM
page = doc.page(0)
for text in page.find_text_containing("DRAFT"):
    page.set_text(text.id, "FINAL")
doc.save_page(page)

# Form filling
fields = doc.get_form_fields()
for f in fields:
    print(f"{f.name} ({f.field_type}) = {f.value}")
doc.set_form_field_value("name", "John Doe")

# Merge another PDF
merged_count = doc.merge_from("appendix.pdf")
print(f"Merged {merged_count} pages")

doc.save("output.pdf")

# --- Search ---
results = doc.search("configuration", case_insensitive=True)
for r in results:
    print(f"Page {r.page + 1}: '{r.text}' at ({r.x:.0f}, {r.y:.0f})")

Novedades de v0.3.38

DocumentBuilder / FluentPageBuilder / EmbeddedFont

from pdf_oxide import DocumentBuilder, EmbeddedFont, StampType

font = EmbeddedFont.from_file("DejaVuSans.ttf")
# Alt: EmbeddedFont.from_bytes(data: bytes, name: str | None = None)

(DocumentBuilder()
    .register_embedded_font("DejaVu", font)
    .letter_page()           # or .a4_page() / .page(size)
        .at(72, 720).font("DejaVu", 12).text("Hello")
        .heading(1, "Title")
        .paragraph("Body text with automatic wrapping")
        # Annotations (15 methods)
        .link_url("https://example.com")
        .link_page(2)
        .link_named("glossary")
        .highlight((1.0, 1.0, 0.0))
        .underline((0.0, 0.0, 1.0))
        .strikeout((1.0, 0.0, 0.0))
        .squiggly((1.0, 0.5, 0.0))
        .sticky_note("Review this")
        .stamp(StampType.APPROVED)
        .freetext((100, 500, 200, 50), "Comment")
        .watermark("DRAFT")
        .watermark_confidential()
        .watermark_draft()
        # AcroForm widgets (5 types)
        .text_field("name", 150, 400, 200, 20, "Jane Doe")
        .checkbox("agree", 72, 380, 15, 15, True)
        .combo_box("country", 150, 360, 200, 20, ["US", "UK"], "US")
        .radio_group("tier", [("free", 72, 340, 15, 15), ("pro", 120, 340, 15, 15)], "pro")
        .push_button("submit", 72, 300, 80, 25, "Submit")
        # Graphics primitives
        .rect(50, 270, 500, 2)
        .filled_rect(50, 260, 500, 2, (0.9, 0.9, 0.9))
        .line(50, 250, 550, 250)
    .done()
    .save_encrypted("out.pdf", "user-pw", "owner-pw"))
# Alt: .save("out.pdf") / .build() -> bytes
# Alt: .to_bytes_encrypted("user-pw", "owner-pw") -> bytes

Pipeline HTML + CSS

Pdf.from_html_css(html: str, css: str, font_bytes: bytes) -> Pdf
Pdf.from_html_css_with_fonts(html: str, css: str, fonts: list[tuple[str, bytes]]) -> Pdf

Consulta Crear desde HTML.

Verificación de firmas

from pdf_oxide import PdfDocument, Timestamp, TsaClient

doc = PdfDocument("signed.pdf")
doc.signature_count()                # int
for sig in doc.signatures():
    sig.signer_name                  # str
    sig.reason                       # str | None
    sig.location                     # str | None
    sig.signing_time                 # datetime | None
    sig.verify()                     # "Valid" | "Invalid" | "Unknown"
    sig.verify_detached(pdf_bytes)   # adds messageDigest check

# Timestamp
ts = Timestamp.parse(tst_bytes)
ts.time, ts.serial, ts.policy_oid, ts.tsa_name, ts.hash_algorithm, ts.message_imprint

# TSA client (behind `tsa-client` feature)
client = TsaClient(url="https://freetsa.org/tsr",
                   username=None, password=None,
                   timeout_seconds=30, hash_algorithm=2,
                   use_nonce=True, cert_req=True)
ts = client.request_timestamp(pdf_bytes)
ts = client.request_timestamp_hash(digest, algorithm=2)

Consulta Firmas digitales para más detalles.

Renderizado

doc.render_page_region(page: int, x: float, y: float, w: float, h: float, format: int = 0) -> bytes
doc.render_page_fit(page: int, fit_width: int, fit_height: int, format: int = 0) -> bytes

format: 0 = PNG, 1 = JPEG. Coordenadas en puntos PDF desde la esquina inferior izquierda.

Aplanado de Pdf

doc.flatten_to_images(dpi: int = 150) -> bytes

Other Language Bindings

PDF Oxide ofrece bindings nativos para todos los ecosistemas principales: Rust, Node.js, WASM, C#, Golang, Java, PHP, Ruby, C++, Swift, Kotlin, Dart, R, Julia, Zig, Scala, Clojure, Objective-C y Elixir.

Próximos pasos