aeat.adapters.outbound.aeat.browser._site_health_parsers module¶
Marker-based parsers for AEAT site-health classification.
Three pure functions inspect the HTTP status, headers, and body of a response
and decide whether it looks like AEAT maintenance, a Web Application Firewall
challenge, or a rate-limit response. evaluate_response() runs them in a
deterministic order and returns the first non-None
SiteHealthStatus.
The parsers are deliberately synchronous, side-effect free, and free of any
Playwright dependency. adapters.outbound.aeat.browser._site_health_probe.probe_response()
is the adapter boundary used by
adapters.outbound.aeat.browser.BrowserSession.navigate(); it turns
navigation responses into SiteHealthStatus records that can be carried
by core.errors.SiteHealthError. The marker corpora reflect the
observed mantenimiento, WAF, and rate-limit responses on AEAT Sede Electrónica.
See also
adapters.outbound.aeat.browser._site_health.SiteHealthStatusFrozen record returned by every positive parser classification.
adapters.outbound.aeat.browser._site_health.SiteHealthStateClosed state catalogue emitted by this parser suite.
- parse_mantenimiento_banner(url, http_status, headers, html, *, rate_limit_retry_after_default, _lowered=None)[source]¶
Detect an AEAT maintenance banner or interstitial.
Classifies the response as
SiteHealthState.MANTENIMIENTOwhen two or more curated body markers match, or when exactly one body marker matches alongside a title containingmantenimientoorinterrupcion. A title-only match with zero body markers never classifies: at least one body-marker hit is required as corroborating evidence to suppress false positives from unrelated pages whose<title>happens to mention maintenance.- Parameters:
url (
str) – The probe URL.http_status (
int) – The observed HTTP status code.headers (
Mapping[str,str]) – Case-insensitive mapping of response headers.html (
str) – The response body.rate_limit_retry_after_default (
int) – Ignored here; accepted so the three parsers share a uniform signature wired from the browser session hook._lowered (
str|None) – Optional pre-lowercased body forwarded fromevaluate_response()to avoid redundant work. Public callers should leave itNone.
- Return type:
- Returns:
A populated
SiteHealthStatusorNonewhen no maintenance markers fire.
- parse_waf_challenge(url, http_status, headers, html, *, rate_limit_retry_after_default, _lowered=None)[source]¶
Detect a WAF block / challenge page.
Triggers either when the response is a 403 and any WAF marker is present, or when the body contains
request blockedalongside areference id/support idcorrelation token regardless of status code.- Parameters:
url (
str) – The probe URL.http_status (
int) – The observed HTTP status code.headers (
Mapping[str,str]) – Case-insensitive mapping of response headers.html (
str) – The response body.rate_limit_retry_after_default (
int) – Ignored; reserved for interface parity._lowered (
str|None) – Pre-computed lowercasedhtml; computed fromhtmlwhen omitted.
- Return type:
- Returns:
A populated
SiteHealthStatusorNonewhen the response does not look WAF-blocked.
- parse_rate_limit_response(url, http_status, headers, html, *, rate_limit_retry_after_default, now=None, _lowered=None)[source]¶
Detect a rate-limit response (HTTP 429 or 503).
Short-circuits unless
http_statusis 429 or 503. When the response is a 503 and the body also matches a maintenance marker the parser yieldsNonesoparse_mantenimiento_banner()can win; AEAT mantenimiento pages frequently answer with 503.Retry-Afteris read case-insensitively fromheadersand supports both forms permitted by RFC 9110 §10.2.3: a non-negative integer delta-seconds, or an HTTP-date. For HTTP-date values the delta is computed againstnow(defaulting todatetime.now()in UTC), clamped to a non-negative integer. If both parses fail, or the computed delta would be zero, the parser falls back torate_limit_retry_after_default.- Parameters:
url (
str) – The probe URL.http_status (
int) – The observed HTTP status code.headers (
Mapping[str,str]) – Case-insensitive mapping of response headers.html (
str) – The response body.rate_limit_retry_after_default (
int) – Fallback value (seconds) when theRetry-Afterheader is missing or unparseable.now (
datetime|None) – Injection seam for deterministic tests of the HTTP-date branch. Defaults todatetime.now()in UTC at call time._lowered (
str|None) – Optional pre-lowercased body forwarded fromevaluate_response().
- Return type:
- Returns:
A populated
SiteHealthStatusorNonewhen the response is not a rate-limit answer.
- evaluate_response(url, http_status, headers, html, *, rate_limit_retry_after_default)[source]¶
Run the full parser suite and return the first non-OK hit.
This is the public parser entry point consumed by
adapters.outbound.aeat.browser._site_health_probe.probe_response().BrowserSessionthen raisescore.errors.SiteHealthErrorfor any returned status.Parsers are evaluated in cost-then-specificity order:
parse_rate_limit_response()(cheapest, header-first short-circuit; yields to mantenimiento when a 503 carries mantenimiento markers).
- Parameters:
- Return type:
- Returns:
A populated
SiteHealthStatusdescribing the detected non-OK state, orNonewhen no parser classified the response (i.e. the response looks healthy).