aeat.adapters.inbound.pdf._pdfplumber module

Shared pdfplumber-backed page-text extraction.

Backs the per-format extract_pages_text / extract_pages_text_from_bytes public surfaces (borrador, declaracion, justificante). Each per-format backend remains the public entry point and is responsible for binding its own format identity to the primitive: it injects the format-specific error class plus the diagnostic phrasing that error messages must carry.

Public surface

Three return-shape families are supported:

All path-based diagnostics use the redacted <input-pdf> label. The bytes entry point is for secure-storage flows that should never materialise source PDF bytes as a plaintext temporary file.

The pdfminer logger level is governed centrally by aeat.core.logging.configure_logging() dictConfig (WARNING).

extract_pages_text_from_path(pdf_path, *, error_class, not_found_label, pdf_label)[source]

Read pdf_path page-by-page and return one stripped string per page.

Parameters:
  • pdf_path (Path) – Filesystem path of the PDF to read.

  • error_class (type[Exception]) – Format-specific exception class to raise on every failure mode (missing file, pdfplumber failure, empty PDF). Each per-format backend injects its own (e.g. BorradorParseError, DeclaracionParseError) so callers can except by their familiar concrete type.

  • not_found_label (str) – Prefix the file-not-found message uses (e.g. "Modelo 100 PDF not found", "declaración PDF not found").

  • pdf_label (str) – Article-prefixed phrase the empty-PDF message uses (e.g. "PDF", "the PDF") so the diagnostic reads naturally per format.

Return type:

tuple[str, ...]

Returns:

Tuple of stripped per-page text in page order. Empty pages preserve their slot as the empty string.

Raises:

Exception – An instance of the supplied error_class when the file does not exist, when pdfplumber cannot open it, or when every page is empty (suggesting a scan-only / XFA PDF without an embedded text layer).

extract_pages_text_from_bytes(pdf_bytes, *, error_class, pdf_label, source_label='in-memory PDF')[source]

Extract text from PDF bytes without materialising a plaintext file.

Parameters:
  • pdf_bytes (bytes) – In-memory source PDF bytes, typically read from secure storage.

  • error_class (type[Exception]) – Format-specific exception class raised on pdfplumber failure or an all-empty text layer.

  • pdf_label (str) – Article-prefixed phrase for the empty-PDF diagnostic.

  • source_label (str) – Redacted source phrase used in errors. Defaults to "in-memory PDF".

Return type:

tuple[str, ...]

Returns:

Tuple of stripped per-page text in page order.

extract_pages_text_concatenated(pdf_path, *, error_class)[source]

Return the concatenated text of pdf_path using pdfplumber.

Skips empty pages and joins the remaining page.extract_text() output with newlines. Unlike extract_pages_text_from_path(), this helper does NOT raise on an all-empty PDF; downstream layout-sensitive parsers (justificante) decide what an empty document means in their own domain terms.

Parameters:
  • pdf_path (Path) – Filesystem path of the PDF to read.

  • error_class (type[Exception]) – Format-specific exception raised when pdfplumber cannot open the file.

Return type:

str

Returns:

Single string with every non-empty page’s text joined by newlines. May be empty if every page is empty.

Raises:

Exception – An instance of the supplied error_class when pdfplumber cannot open the file.

extract_pages_text_with_fast_path(pdf_path, *, error_class, not_found_label, pdf_label, fast_path_extractor=None)[source]

Try fast_path_extractor first, falling back to pdfplumber.

The fast-path callable receives the same pdf_path and must return either a tuple of stripped per-page strings (consumed verbatim) or None to signal “fall through to pdfplumber”. Format-specific extractors (e.g. the pypdfium2 path used by declaracion with declaration-content canary regexes) live in the calling module so the canonical primitive stays content-neutral.

When fast_path_extractor is None this function is equivalent to extract_pages_text_from_path().

Return type:

tuple[str, ...]

Parameters: