cadrumo.adapters.inbound.financial.providers._mapped_tabular module¶
Statement ingest for tabular exports of no recognised fixed layout.
MappedTabularProvider is the last provider detection tries. Every
exact fixed-layout parser — the bank CSV layouts, the spreadsheet, OFX, the N26
statement PDF — is offered the file first, and this lane sees it only when none
of them claimed it. That ordering is load-bearing: a known bank export must
keep taking its exact parser, because an exact layout match is a deterministic
read of a known structure, while this lane’s read depends on a column-role
mapping decided per file. Letting the fallback shadow an exact provider would
silently turn the deterministic parse into an inferred one.
The lane itself is deterministic end to end. core.tabular resolves
the file’s shape, a mapping supplies one FieldRole per column,
and _tabular_projection copies each cell into its role byte-for-byte.
Only the mapping is a judgement, and it is made once per file over a closed
allow-list of roles, never over a cell value.
A file is never refused for a row or a column the product does not understand: an unmapped column is reported, and a row that will not parse is reported and skipped while every other row still imports.
See also
default_tabular_mapping_resolver()The single wiring point through which detection obtains a mapping.
- MAPPED_TABULAR_EXTENSIONS: frozenset[str]¶
Extensions this lane will consider. A delimited text export can arrive under any of them; content normalization decides whether it is really tabular.
- REQUIRED_STATEMENT_ROLES: frozenset[FieldRole]¶
Roles a bank-movement row cannot do without.
FieldRoleis shared with the invoice-book lane and carries no statement-specific date or movement amount member, so a statement’s booked date reads underINVOICE_DATEand its amount underGRAND_TOTAL.
- TabularMappingResolver¶
Supplies one role per column for a normalized table, or
Nonewhen it cannot.alias of
Callable[[NormalizedTable],ColumnRoleMapping|None]
- default_tabular_mapping_resolver()[source]¶
Return the mapping resolver detection uses, or
Nonewhen none is installed.The single wiring point between this lane and whatever establishes column roles. It resolves to the semantic column-role mapper, which decides one role per column from the file’s header vocabulary alone, once per file. Every cell is still copied by
_tabular_projectionunder that mapping, so nothing about how values reach a row changed when this stopped returningNone.- Return type:
Callable[[NormalizedTable],ColumnRoleMapping|None] |None
- class MappedTabularProvider(mapping_resolver=None)[source]¶
Bases:
FinancialProviderIngest bank movements from a tabular export under a column-role mapping.
- Variables:
mapping_resolver – Supplies the per-file column-role mapping. Defaults to
default_tabular_mapping_resolver(), so production wiring has one home; tests and callers holding their own mapping pass it directly.- Parameters:
mapping_resolver (TabularMappingResolver | None)
- name: ClassVar[str]¶
- supported_extensions: ClassVar[frozenset[str]]¶
- source_format: ClassVar[SourceFormat]¶
- verification_source: ClassVar[CorpusVerificationSource]¶
- provisional_pending_specimen: ClassVar[bool]¶
- validate_source(path)[source]¶
Report whether the source normalizes and maps, and what was not understood.
Validation is a full dry projection: every column the mapping did not establish and every row that will not parse is reported here, so the operator sees the whole picture before ingest rather than one row at a time. The source stays valid as long as at least one row parses.
- Return type:
- Parameters:
path (Path)
- ingest(path)[source]¶
Yield one
ParsedLedgerRowper importable row of the mapped table.A row that will not parse is logged and skipped; the rest still import.
- Raises:
InvalidFinancialSourceError – The source does not normalize, or no column-role mapping could be established for it.
- Return type:
- Parameters:
path (Path)