cadrumo.core.document_shape module¶
Closed taxonomy of evidence-document shapes derived from content bytes.
Replaces the two-member MediaKind (PDF / IMAGE) that was derived
from a declared MIME type. That derivation could not see inside a document,
so a ZUGFeRD / Factur-X invoice – a PDF that carries a complete machine-
readable EN16931 XML payload as an embedded file – was indistinguishable from
a scan of a paper receipt. Both answered PDF, and the most exactly readable
document in the corpus was read as rendered prose.
The shape is therefore derived from the bytes themselves. It exists so a reader can ask what can be recovered exactly from this document before choosing a strategy, and so the routing order is inspectable: a document carrying a structured record reaches no model at all.
- class DocumentShape(*values)[source]¶
Bases:
StrEnumWhat a resolved evidence document actually is, by content.
Members are ordered from most to least exactly readable. The three
XML_*members andPDF_EMBEDDED_XMLall carry a structured record; everything below them requires text extraction or a model.- XML_CII¶
Standalone EN16931 Cross Industry Invoice (UN/CEFACT syntax).
- XML_UBL¶
Standalone EN16931 UBL invoice (OASIS syntax).
- XML_FACTURAE¶
Standalone Facturae 3.2.x invoice (the Spanish national format).
- PDF_EMBEDDED_XML¶
PDF carrying a structured invoice as an embedded file (ZUGFeRD / Factur-X).
- XML_AEAT_SII¶
a BATCH of ledger records, not one invoice document.
Deliberately not a member of
STRUCTURED_DOCUMENT_SHAPES. That set routes a document into the single-invoice reader, and one SII file declares its record collections atmaxOccurs=10000; routing a batch into a singular reader would silently keep the first record and discard the rest. Which family each record belongs to – facturas emitidas, recibidas, a baja, or one of the twelve non-invoice families – is classified per RECORD, never per file.- Type:
AEAT SII submission
- XML_AEAT_VERIFACTU¶
a batch of registro de facturacion records.
Not a member of
STRUCTURED_DOCUMENT_SHAPES, for the same reason asXML_AEAT_SII. ItsRegistroFacturais a CHOICE ofRegistroAltaorRegistroAnulacionrepeated tomaxOccurs=1000, so a single submission may MIX registrations and cancellations and cannot be classified from the file alone.- Type:
VERI*FACTU submission
- PDF_TEXT_LAYER¶
PDF with an extractable text layer but no structured record.
- PDF_SCAN¶
PDF whose pages carry no extractable text; readable only by rasterising.
- IMAGE¶
A bare image of a document.
- UNKNOWN¶
Bytes matching no recognised shape. Never guessed at, always refused.
- STRUCTURED_DOCUMENT_SHAPES: frozenset[DocumentShape]¶
Shapes carrying a structured SINGLE-INVOICE record, readable with no model.
Membership means “one document, one invoice, readable by
parse_einvoice_document”. The AEAT record-batch shapes are excluded on purpose: they are equally structured and equally model-free, but they carry a COLLECTION of ledger records, so admitting them here would route a batch into a reader that returns one invoice and silently drop every record after the first. No single-invoice reader accepts them: the evidence path leaves them outside this set and refuses them as filing artefacts until a dedicated reconciliation reader exists. A future reader would need a collection return type rather than silently discarding records.Hand-listed rather than derived, so adding a structured member forces a deliberate decision about which of the two readers it belongs to.
- PDF_CONTAINER_SHAPES: frozenset[DocumentShape]¶
Shapes whose bytes are a PDF, whatever the PDF turns out to carry.
The read paths that rasterise pages, or try a text layer before falling back to vision, need exactly this question: is this a PDF container? They previously asked it of
MediaKind, which is derived from the STORED MIME TYPE – a label the producer attached, which cannot see inside the document. That is the same blindness the shape probe exists to remove, so asking the label was the one remaining way a caller could be told “PDF” by something that never opened it.Hand-listed for the same reason as the sets above: a new PDF-carrying shape should force a decision about whether page rasterisation is meaningful for it, rather than being swept in by a name prefix.