aeat.adapters.inbound.sanitizer._records module¶
Strict pydantic v2 records for the adapters.inbound.sanitizer subpackage.
Every record in this module is frozen, extra=”forbid”,
strict=True. Cleartext PII lives exclusively in
pydantic.SecretStr fields so accidental repr / log
inclusion does not leak the source value. Synthetic replacements
are validated against the same checksum / shape rules the project
applies to live values, so a sanitised fixture round-trips through
production parsers unchanged.
SecretStr is a display/logging guard, not a storage policy. Operator
mapping files that contain real values must remain outside git; committed audit
records should contain only synthetic values, hashes, surface names, and counts.
- class NifReplacement(**data)[source]¶
Bases:
_ReplacementBaseReplacement entry whose synthetic value must be a valid NIF/NIE.
- Parameters:
real (SecretStr)
synthetic (Annotated[str, StringConstraints(strip_whitespace=False, to_upper=None, to_lower=None, strict=None, min_length=1, max_length=None, pattern=None, ascii_only=None)])
surface_label (Annotated[str, StringConstraints(strip_whitespace=False, to_upper=None, to_lower=None, strict=None, min_length=1, max_length=None, pattern=None, ascii_only=None)])
- class NameReplacement(**data)[source]¶
Bases:
_ReplacementBaseReplacement entry for a taxpayer or representative name.
The synthetic value is constrained to a non-blank uppercased string so it round-trips through parsers that expect AEAT’s
APELLIDO APELLIDO NOMBREshape.- Parameters:
real (SecretStr)
synthetic (Annotated[str, StringConstraints(strip_whitespace=False, to_upper=None, to_lower=None, strict=None, min_length=1, max_length=None, pattern=None, ascii_only=None)])
surface_label (Annotated[str, StringConstraints(strip_whitespace=False, to_upper=None, to_lower=None, strict=None, min_length=1, max_length=None, pattern=None, ascii_only=None)])
- class AddressReplacement(**data)[source]¶
Bases:
_ReplacementBaseReplacement entry for a postal address.
- Parameters:
real (SecretStr)
synthetic (Annotated[str, StringConstraints(strip_whitespace=False, to_upper=None, to_lower=None, strict=None, min_length=1, max_length=None, pattern=None, ascii_only=None)])
surface_label (Annotated[str, StringConstraints(strip_whitespace=False, to_upper=None, to_lower=None, strict=None, min_length=1, max_length=None, pattern=None, ascii_only=None)])
- class ExpedienteReplacement(**data)[source]¶
Bases:
_ReplacementBaseReplacement entry for an AEAT expediente identifier.
AEAT expedientes are typically opaque 13-19 character alphanumeric strings; the synthetic value preserves the same length window so width-sensitive layout cues survive.
- Parameters:
real (SecretStr)
synthetic (Annotated[str, StringConstraints(strip_whitespace=False, to_upper=None, to_lower=None, strict=None, min_length=1, max_length=None, pattern=None, ascii_only=None)])
surface_label (Annotated[str, StringConstraints(strip_whitespace=False, to_upper=None, to_lower=None, strict=None, min_length=1, max_length=None, pattern=None, ascii_only=None)])
- class CsvReplacement(**data)[source]¶
Bases:
_ReplacementBaseReplacement entry for an AEAT Código Seguro de Verificación.
AEAT CSVs are 16-character base32-like strings. The synthetic value preserves the length so downstream parsers that match on length-bounded patterns continue to match.
- Parameters:
real (SecretStr)
synthetic (Annotated[str, StringConstraints(strip_whitespace=False, to_upper=None, to_lower=None, strict=None, min_length=1, max_length=None, pattern=None, ascii_only=None)])
surface_label (Annotated[str, StringConstraints(strip_whitespace=False, to_upper=None, to_lower=None, strict=None, min_length=1, max_length=None, pattern=None, ascii_only=None)])
- class NrcReplacement(**data)[source]¶
Bases:
_ReplacementBaseReplacement entry for an AEAT Número de Referencia Completo.
- Parameters:
real (SecretStr)
synthetic (Annotated[str, StringConstraints(strip_whitespace=False, to_upper=None, to_lower=None, strict=None, min_length=1, max_length=None, pattern=None, ascii_only=None)])
surface_label (Annotated[str, StringConstraints(strip_whitespace=False, to_upper=None, to_lower=None, strict=None, min_length=1, max_length=None, pattern=None, ascii_only=None)])
- class IbanReplacement(**data)[source]¶
Bases:
_ReplacementBaseReplacement entry for an IBAN (ES- prefixed).
- Parameters:
real (SecretStr)
synthetic (Annotated[str, StringConstraints(strip_whitespace=False, to_upper=None, to_lower=None, strict=None, min_length=1, max_length=None, pattern=None, ascii_only=None)])
surface_label (Annotated[str, StringConstraints(strip_whitespace=False, to_upper=None, to_lower=None, strict=None, min_length=1, max_length=None, pattern=None, ascii_only=None)])
- class ImporteReplacement(**data)[source]¶
Bases:
_ReplacementBaseReplacement entry for a monetary amount in AEAT comma-decimal shape.
- Parameters:
real (SecretStr)
synthetic (Annotated[str, StringConstraints(strip_whitespace=False, to_upper=None, to_lower=None, strict=None, min_length=1, max_length=None, pattern=None, ascii_only=None)])
surface_label (Annotated[str, StringConstraints(strip_whitespace=False, to_upper=None, to_lower=None, strict=None, min_length=1, max_length=None, pattern=None, ascii_only=None)])
- class ArbitraryReplacement(**data)[source]¶
Bases:
_ReplacementBaseReplacement entry with no shape constraint.
Use sparingly — every arbitrary entry bypasses checksum and layout validation, so a poorly chosen synthetic can break a deep-extractor regression. Reserve for ad-hoc strings such as capture-time fingerprints or one-off identifiers.
- Parameters:
real (SecretStr)
synthetic (Annotated[str, StringConstraints(strip_whitespace=False, to_upper=None, to_lower=None, strict=None, min_length=1, max_length=None, pattern=None, ascii_only=None)])
surface_label (Annotated[str, StringConstraints(strip_whitespace=False, to_upper=None, to_lower=None, strict=None, min_length=1, max_length=None, pattern=None, ascii_only=None)])
- class TokenMap(**data)[source]¶
Bases:
BaseModelDeclarative input mapping for
sanitize_pdf().Each tuple holds zero-or-more replacement records of the matching category. Empty tuples are permitted; a TokenMap with every category empty is structurally valid but produces a no-replacement sanitisation (the metadata + dynamic-surface scrub still runs). The real values inside replacement entries are the operator-supplied authority for the rewrite; the sanitizer does not run probabilistic PII discovery.
- Variables:
nif – Replacements for NIF / NIE values.
name – Replacements for taxpayer / representative names.
address – Replacements for postal addresses.
expediente – Replacements for AEAT expediente identifiers.
csv – Replacements for Código Seguro de Verificación strings.
nrc – Replacements for Número de Referencia Completo strings.
iban – Replacements for ES-prefixed IBANs.
importe – Replacements for AEAT comma-decimal monetary amounts.
arbitrary – Replacements without shape constraints.
- Parameters:
nif (tuple[NifReplacement, ...])
name (tuple[NameReplacement, ...])
address (tuple[AddressReplacement, ...])
expediente (tuple[ExpedienteReplacement, ...])
csv (tuple[CsvReplacement, ...])
nrc (tuple[NrcReplacement, ...])
iban (tuple[IbanReplacement, ...])
importe (tuple[ImporteReplacement, ...])
arbitrary (tuple[ArbitraryReplacement, ...])
- nif: tuple[NifReplacement, ...]¶
- name: tuple[NameReplacement, ...]¶
- address: tuple[AddressReplacement, ...]¶
- expediente: tuple[ExpedienteReplacement, ...]¶
- csv: tuple[CsvReplacement, ...]¶
- nrc: tuple[NrcReplacement, ...]¶
- iban: tuple[IbanReplacement, ...]¶
- importe: tuple[ImporteReplacement, ...]¶
- arbitrary: tuple[ArbitraryReplacement, ...]¶
- class Replacement(**data)[source]¶
Bases:
BaseModelOne token-replace edit recorded in
SanitizationResult.replacements_applied.- Variables:
surface – Closed-set surface name (DocInfo key, content- stream, structtree text, …).
surface_index – Tuple-encoded location within the surface. For content streams,
(page_index, instruction_index).real_sha256 – SHA-256 of the cleartext PII the entry matched against. Never the cleartext itself — committing the cleartext into
replacements_appliedwould defeat the entire sanitiser. Treat this hash as fixture-review metadata, not as a production de-identification key.synthetic – The synthetic replacement text that landed in the output. Safe to log.
encoding – Encoding form in which the operand was rewritten (literal string, hex string, etc.).
- Parameters:
surface (Literal['docinfo_title', 'docinfo_subject', 'docinfo_author', 'docinfo_keywords', 'docinfo_creator', 'docinfo_producer', 'docinfo_creation_date', 'docinfo_mod_date', 'docinfo_other', 'xmp_packet', 'xmp_dc_title', 'xmp_dc_description', 'xmp_dc_creator', 'xmp_pdf_keywords', 'xmp_pdfa_claim', 'content_stream', 'annotation_contents', 'annotation_drop', 'structtree_actualtext', 'structtree_alt', 'structtree_dropped', 'attachments', 'javascript', 'open_action', 'additional_actions', 'optional_content_groups', 'acroform_field_value', 'acroform_dropped', 'page_thumbnail', 'outlines', 'page_labels', 'incremental_update_history'])
real_sha256 (str)
synthetic (Annotated[str, StringConstraints(strip_whitespace=False, to_upper=None, to_lower=None, strict=None, min_length=1, max_length=None, pattern=None, ascii_only=None)])
encoding (Literal['literal', 'hex', 'actualtext', 'docinfo_string', 'xmp_string'])
- surface: _SurfaceName¶
- surface_index: tuple[int, ...]¶
- real_sha256: str¶
- synthetic: _NonEmptyStr¶
- encoding: _EncodingName¶
- class ScrubbedSurface(**data)[source]¶
Bases:
BaseModelCounter for one PII surface that was wiped (vs. token-replaced).
- Variables:
surface – Closed-set surface name.
count – Number of items removed (0 when the surface was absent in the source — recorded so callers can audit the sanitiser’s coverage).
- Parameters:
surface (Literal['docinfo_title', 'docinfo_subject', 'docinfo_author', 'docinfo_keywords', 'docinfo_creator', 'docinfo_producer', 'docinfo_creation_date', 'docinfo_mod_date', 'docinfo_other', 'xmp_packet', 'xmp_dc_title', 'xmp_dc_description', 'xmp_dc_creator', 'xmp_pdf_keywords', 'xmp_pdfa_claim', 'content_stream', 'annotation_contents', 'annotation_drop', 'structtree_actualtext', 'structtree_alt', 'structtree_dropped', 'attachments', 'javascript', 'open_action', 'additional_actions', 'optional_content_groups', 'acroform_field_value', 'acroform_dropped', 'page_thumbnail', 'outlines', 'page_labels', 'incremental_update_history'])
count (int)
- surface: _SurfaceName¶
- count: int¶
- class SanitizationWarning(**data)[source]¶
Bases:
BaseModelOne non-fatal warning emitted during sanitisation.
- Variables:
code – Closed-set warning identifier.
detail – Free-form detail string. Must NOT contain cleartext PII; the caller is responsible for constructing a PII-safe detail.
- Parameters:
code (Literal['unknown_surface_present', 'encoding_inferred', 'structtree_dropped_lossy', 'pdfa_claim_invalidated', 'digital_signature_present_refusing', 'incremental_update_history_consolidated', 'source_sha256_already_in_known_sanitized_set', 'missing_replacement_target'])
detail (Annotated[str, StringConstraints(strip_whitespace=False, to_upper=None, to_lower=None, strict=None, min_length=1, max_length=None, pattern=None, ascii_only=None)])
- code: _WarningCode¶
- detail: _NonEmptyStr¶
- class DeterminismFlags(**data)[source]¶
Bases:
BaseModelCaptured save-flag set used to produce byte-stable output.
- Variables:
deterministic_id – Whether
deterministic_idwas passed (true in normal operation).static_id – Debug-only
static_idflag (false in normal operation).object_stream_mode – One of
"preserve","generate", or"disable".linearize – Whether linearisation was requested.
recompress_flate – Whether flate streams were recompressed.
compress_streams – Whether streams were compressed.
- Parameters:
- deterministic_id: bool¶
- static_id: bool¶
- object_stream_mode: Literal['preserve', 'generate', 'disable']¶
- linearize: bool¶
- recompress_flate: bool¶
- compress_streams: bool¶
- class SanitizationResult(**data)[source]¶
Bases:
BaseModelOutcome of a successful
sanitize_pdf()call.The
output_bytesfield carries the sanitised PDF; the CLI shell writes it to disk. The library function itself never touches the filesystem. The result is an audit record for fixture preparation, not an application persistence model.- Variables:
output_bytes – Byte-for-byte sanitised PDF.
source_sha256 – SHA-256 of the input bytes.
output_sha256 – SHA-256 of
output_bytes.source_size_bytes – Size of the input.
output_size_bytes – Size of
output_bytes.sanitizer_version – Version string of the sanitiser at the time of the run.
determinism_flags – Captured save-flag set.
replacements_applied – One row per token-replace edit.
surfaces_scrubbed – One row per PII surface that was wiped.
warnings – Non-fatal warnings.
- Parameters:
output_bytes (bytes)
source_sha256 (str)
output_sha256 (str)
source_size_bytes (int)
output_size_bytes (int)
sanitizer_version (Annotated[str, StringConstraints(strip_whitespace=False, to_upper=None, to_lower=None, strict=None, min_length=1, max_length=None, pattern=None, ascii_only=None)])
determinism_flags (DeterminismFlags)
replacements_applied (tuple[Replacement, ...])
surfaces_scrubbed (tuple[ScrubbedSurface, ...])
warnings (tuple[SanitizationWarning, ...])
- output_bytes: bytes¶
- source_sha256: str¶
- output_sha256: str¶
- source_size_bytes: int¶
- output_size_bytes: int¶
- sanitizer_version: _NonEmptyStr¶
- determinism_flags: DeterminismFlags¶
- replacements_applied: tuple[Replacement, ...]¶
- surfaces_scrubbed: tuple[ScrubbedSurface, ...]¶
- warnings: tuple[SanitizationWarning, ...]¶