cadrumo.adapters.outbound.aeat.sede.walker module¶
Playwright-driven sede walker: session → expedientes → PDF bytes.
The walker is the only side-effectful layer in adapters.outbound.aeat.sede. It
takes an AeatSession whose encrypted browser state carries
valid AEAT cookies, drives a read-only Playwright session over the
sede, and exposes two operations to callers:
walk_expedientes_tree()— listing traversal.capture_justificante()— expediente → authoritative PDF capture.
Both are read-only by construction: only page.goto and
context.request.get cross the wire. No click() onto submit
buttons, no form POSTs, no mutation verbs anywhere in the public
surface.
- assert_resumen_landing(landing_url)[source]¶
Refuse a landing that is not the expedientes resumen page.
Called after the branch expansion, which JS-clicks every
mostrarListadoanchor in the tree. Those anchors are AJAX expanders, so the page is expected not to move – but nothing established that it had not. The walker then snapshots the DOM and parses it AS the expedientes tree, so a navigation during expansion would be read as a tree with no error anywhere: the parser would simply find no rows, and an empty result is indistinguishable from a taxpayer with no expedientes.- Parameters:
landing_url (
str) – The URL AEAT actually served, read off the page.- Raises:
SedeNavigationError – When the walker is not on the resumen page.
- Return type:
- assert_landed_url_readable(landed_url, *, requested_url)[source]¶
Return the landed URL, refusing a navigation that produced no readable one.
The re-assertion after a
gotoused to be skipped entirely when the landed URL was empty, so the one case where the outcome could not be established was the one case that was not checked – fail-open in exactly the position the re-assertion exists to cover.- Parameters:
- Return type:
- Returns:
The landed URL, once established as readable.
- Raises:
SedeNavigationError – When the navigation produced no readable URL.
- async walk_expedientes_tree(session, *, modelo=None, settings=None)[source]¶
Enumerate every expediente visible under Mis Expedientes.
The sede renders an AJAX-expanded tree. This function expands every category branch whose label contains a
Modelo <N>token (or all branches whenmodelois None), then parses the resulting DOM for leaf expediente rows.- Parameters:
session (
AeatSession) – An authenticated session with encrypted cached AEAT cookies. Cl@ve-móvil and certificate sessions both qualify.modelo (
str|None) – When set, only expand category branches whose label references this modelo code (e.g."100"for IRPF). Saves DOM expansion work on large corpora.settings (
Settings|None) – OptionalSettingsoverride. Defaults tocore.config.load_settings().
- Return type:
- Returns:
Tuple of
Expedienterecords, ordered as AEAT renders them (most recent first in every captured case so far).- Raises:
SedeNavigationError – If
gotoor a required expansion fails.
- async capture_justificante(session, expediente, *, settings=None)[source]¶
End-to-end: expediente → CSV handle → PDF bytes →
SedeCapture.Navigates to the expediente detail page, extracts its CSV reference, and fetches the raw PDF in one session-reusing call. This is the preferred entry point for callers that just want “the AEAT record for this expediente”.
- Parameters:
session (
AeatSession) – Authenticated session.expediente (
Expediente) – Target expediente.
- Return type:
- Returns:
A fully populated
SedeCapture.- Raises:
SedeNavigationError – On goto failures.
JustificanteFetchError – On PDF download failures.