cadrumo.core.external_constants module

External constants registry loaded from external_constants.toml.

Centralises third-party hostnames, AEAT service paths, OAuth scopes, and remote API endpoints. The TOML file sits beside this module and is parsed once per process via load_external_constants(). Every section is modelled as a frozen, strict pydantic v2 model so callers see typed, immutable values and any drift between the TOML and the schema fails fast at import time.

This is a read-only remote-mirror registry for public, externally defined constants. Runtime-tunable values such as timeouts, storage roots, and operator choices belong in core.config.Settings; profile data, tokens, passphrases, bucket ids, and SQL routes do not belong here. Loading the registry only reads packaged TOML (or an explicit audit/test path) and never opens storage, writes files, or contacts remote providers.

The typed root is ExternalConstants, with AEAT-specific subsections grouped under AeatSection; callers normally reach it through core.config.Settings.external_constants(). The volatile Pre303 and IVA-wallet browser surface remains lazily validated as AeatPre303Surface so selector churn does not poison unrelated configuration reads.

DEFAULT_CURRENCY: Final[str]

ISO 4217 currency code for the Euro, used as the functional currency throughout AEAT.

BINARY_MIME_TYPE: Final[str]

Standard binary MIME type for opaque byte-stream payloads (Drive uploads, blob store, fichero).

JSON_MIME_TYPE: Final[str]

IANA-registered MIME type for JSON document payloads.

CSV_MIME_TYPE: Final[str]

IANA-registered MIME type for comma-separated value exports.

JSONL_MIME_TYPE: Final[str]

MIME type for newline-delimited JSON export streams.

XLSX_MIME_TYPE: Final[str]

MIME type for Office Open XML spreadsheet workbooks.

CLASSIFIED_BY_MANUAL: Final[str]

Sentinel written to classified_by when the operator provides a classification directly (no rule engine involved). The field also accepts "rule:<id>" payloads; this named constant prevents the literal from drifting across the application and domain layers.

CLASSIFIED_BY_AUTO: Final[str]

Sentinel written to classified_by when the classification was produced automatically by the rule engine with no operator override.

class AeatDomainSection(**data)[source]

Bases: _Frozen

AEAT and related government hostnames.

Hostnames are registry data, not executable literals in live drivers. Callers combine these origins with path sections below instead of re-declaring Sede, Cl@ve, BOE, or numbered AEAT subdomain strings.

Parameters:

data (Any)

host_suffix: str
sede: str
www1: str
www2: str
www3: str
www6: str
www12: str
aeat_gob: str
legacy_host_suffix: str
legacy_www: str
clave: str
boe: str
class AeatSedePathSection(**data)[source]

Bases: _Frozen

Relative path templates against configured AEAT origins.

These values are route fragments and templates only; consumers choose the correct origin from AeatDomainSection or an overrideable core.config.Settings field before building a full URL.

Parameters:

data (Any)

auth_gate_4033: str
expedientes_resumen: str
declarations_listing: str
cotejo_query: str
cotejo_document: str
notifications_summary: str
notifications_query: str
notifications_detail: str
certificate_selector: str
r210_simulator_open_ajax: str
borrador_100_detail_template: str
declaracion_consult: str
clave_movil_login: str
expediente_detail_template: str
irpf_expediente_detail_year_prefix: str
irpf_expediente_detail_year_suffix: str
notificaciones: str
iva_compensation_wallet: str
censal_datos: str
class AeatClaveMovilSurface(**data)[source]

Bases: _Frozen

Externally-defined Cl@ve Móvil page identifiers and shape markers.

Parameters:

data (Any)

selector_access_url_template: str
selector_access_path_marker: str
dialogo_representacion_path_marker: str
dialogo_representacion_path: str
obtener_clave_movil_path_marker: str
obtener_clave_movil_qr_path_marker: str
cancelar_clave_movil_path_marker: str
obtener_clave_movil_qr_path: str
obtener_clave_movil_non_qr_path: str
autentica_dni_nie_contraste_path: str
cancelar_clave_movil_path: str
obtener_clave_movil_browser_global: str
authorize_button_selector: str
nif_input_selector: str
dni_fecha_input_selector: str
dni_fecha_visible_selector: str
nie_soporte_input_selector: str
nie_soporte_visible_selector: str
continue_button_selector: str
continue_button_visible_selector: str
verification_code_selector: str
wait_text_markers: tuple[str, ...]
pending_petition_text_markers: tuple[str, ...]
class AeatClavePermanenteSurface(**data)[source]

Bases: _Frozen

Externally-defined Cl@ve Permanente selector-page and IdP form markers.

Cl@ve Permanente reuses the same AEAT auth-method selector page as Cl@ve Movil (selector_access_url_template); the Cl@ve IdP itself then renders a DNI/NIE + password form rather than the QR/push screen. These IdP form selectors and error markers are the least stable part of this surface — they track the Cl@ve frontend, not an AEAT-published contract — and may need redesign if the Cl@ve frontend changes shape.

Parameters:

data (Any)

selector_access_url_template: str
selector_access_path_marker: str
username_input_selector: str
password_input_selector: str
submit_button_selector: str
elevation_sms_marker: str
invalid_credentials_marker: str
account_locked_marker: str
password_expired_marker: str
class AeatPre303Surface(**data)[source]

Bases: _Frozen

Externally-defined Pre303 and IVA compensation wallet surface markers.

Parameters:

data (Any)

presentation_service_path: str
access_help_path: str
faq_general_path: str
faq_specific_path: str
functionalities_path: str
procedures_path: str
iva_wallet_header_tokens: tuple[str, ...]
iva_wallet_total_label_tokens: tuple[str, ...]
iva_wallet_empty_page_tokens: tuple[str, ...]
representation_own_name_selector: str
representation_own_name_label_selector: str
representation_representative_selector: str
representation_submit_selector: str
representation_own_name_action_label: str
wallet_discovered_entrypoint_action_label: str
wallet_execute_read_action_label: str
alert_modal_selector: str
alert_continue_button_text: str
wallet_form_selector: str
wallet_execute_submit_selector: str
wallet_ejercicio_input_selector: str
wallet_periodo_input_selector: str
official_access_auth_methods: tuple[str, ...]
class AeatHelpPageSection(**data)[source]

Bases: _Frozen

Static help/landing pages rooted under the sede origin.

Parameters:

data (Any)

csv_verification: str
renta_web_open_landing: str
nif_iva_landing: str
manual_practicos_root: str
class AeatNotificationsQuery(**data)[source]

Bases: _Frozen

Filter parameters driving AEAT’s notifications search surface.

The surface defaults its date range to a single month. Reading it without supplying a range therefore answers “what arrived this month”, which is not the question the notifications register is asked.

Variables:
  • lookback_years – How far back the search window reaches from today.

  • date_format – strftime pattern AEAT accepts for the filter dates.

  • tipo_consulta_all – Filter value selecting every notification kind.

  • leida_all – Filter value selecting both read and unread rows.

  • detail_view_action – Action token returning the notification PDF.

Parameters:

data (Any)

lookback_years: int
date_format: str
tipo_consulta_all: str
leida_all: str
detail_view_action: str
class AeatOracleSection(**data)[source]

Bases: _Frozen

Absolute URLs of AEAT parity oracles.

Parameters:

data (Any)

nif_iva_verification: str
groi_check: str
renta_web_open_app_template: str
groi_auth_unlock_descriptor: str
nif_iva_auth_locked_descriptor: str
class AeatLiveSafety(**data)[source]

Bases: _Frozen

Centralized allow-list labels for audited live AEAT browser actions.

The patterns identify reviewed action categories for live-surface guards. They do not authorize a write by themselves; command policy, capability checks, and live-write gates remain responsible for deciding whether an operation may run.

Parameters:

data (Any)

auth_browser_action_patterns: tuple[str, ...]
wallet_browser_action_patterns: tuple[str, ...]
declarations_browser_action_patterns: tuple[str, ...]
consult_oracle_browser_action_patterns: tuple[str, ...]
renta_web_open_browser_action_patterns: tuple[str, ...]
censal_browser_action_patterns: tuple[str, ...]
censal_forbidden_landing_markers: tuple[str, ...]
class AeatPortalPathSection(**data)[source]

Bases: _Frozen

Centralized AEAT portal catalogue paths keyed by Portal id.

Portal entries resolve their route fragments from this registry so the catalogue can describe AEAT surfaces without carrying host or path source literals in each entry module.

Parameters:

data (Any)

filing_censo_path_regex: str
filing_censo_path_description: str
paths: dict[str, str]
class AeatSection(**data)[source]

Bases: _Frozen

Aggregates every AEAT-flavoured constant subsection.

The pre303 web-scraping surface (IVA-compensation-wallet routes, representation-gate selectors, parser markers) is the most volatile section of the registry: every value tracks the AEAT portal’s HTML and may break on a portal redesign. To keep that volatility from poisoning the whole registry — and therefore every Settings() construction, since core.config.Settings resolves AEAT-URL defaults through load_external_constants() — the raw [aeat.pre303] mapping is kept untyped and validated lazily into a strict AeatPre303Surface only on first access via the pre303 property. A missing or malformed pre303 block thus never raises while parsing the registry; it surfaces as a clean core.errors.hierarchy.CoreValidationError to the wallet / representation flows that actually consume it, and leaves selector-free commands (config profile status, modelo list, …) entirely unaffected.

Parameters:

data (Any)

domains: AeatDomainSection
sede_paths: AeatSedePathSection
clave_movil: AeatClaveMovilSurface
clave_permanente: AeatClavePermanenteSurface
pre303_raw: dict[str, Any]
help_pages: AeatHelpPageSection
notifications_query: AeatNotificationsQuery
oracles: AeatOracleSection
live_safety: AeatLiveSafety
portal_paths: AeatPortalPathSection
property pre303: AeatPre303Surface[source]

Return the strict-validated AeatPre303Surface (Pre303 / IVA-wallet surface).

Validation is deferred to first access so a malformed or absent [aeat.pre303] block cannot break registry parsing for the many CLI paths that never scrape the AEAT portal. When the block is broken the leaked pydantic.ValidationError is wrapped in a core.errors.hierarchy.CoreValidationError carrying the section identity and the failing error’s type as machine facts. The wrapper renders no prose and copies no validation message: the operator-facing text is the registered code’s translation key, and the recovery is resolved downstream from the facts.

class GoogleOAuthScopeSection(**data)[source]

Bases: _Frozen

OAuth scope strings the Google integration requests.

Parameters:

data (Any)

openid: str
email: str
drive_file: str
spreadsheets: str
class GoogleServiceSection(**data)[source]

Bases: _Frozen

Google-hosted service surfaces.

Parameters:

data (Any)

oauth_scopes: GoogleOAuthScopeSection
class OnlineServicesSection(**data)[source]

Bases: _Frozen

Aggregates non-AEAT online service constants.

Parameters:

data (Any)

google: GoogleServiceSection
class ExternalConstants(**data)[source]

Bases: _Frozen

Top-level registry model mirroring the TOML root.

The root intentionally separates AEAT-owned surfaces from other online services so call sites can depend on the narrow subsection they need while still sharing one typed registry load.

Parameters:
aeat: AeatSection
online_services: OnlineServicesSection
PDF_MIME_TYPE: Final[str]

IANA-registered MIME type for PDF document payloads.

PDF_EXTENSION: Final[str]

PDF file-extension string (lower-case, dot-prefixed).

XML_MIME_TYPE: Final[str]

IANA-registered MIME type for XML document payloads (RFC 7303 prefers this over the discouraged text/xml). Deliberately the GENERIC container type: a structured e-invoice may be Facturae, EN16931 CII or UBL, and which one it is can only be settled by probing the bytes. Storing a syntax-specific type would restate as a declared fact the very claim the document-shape probe exists to derive – the mistake that once routed a ZUGFeRD invoice, whose declared type said “PDF”, down the prose-extraction path.

XLS_EXTENSION: Final[Literal['.xls']]

Legacy binary Excel workbook file-extension string (lower-case, dot-prefixed).

XLSX_EXTENSION: Final[Literal['.xlsx']]

Excel / Open-XML workbook file-extension string (lower-case, dot-prefixed).

XLSM_EXTENSION: Final[Literal['.xlsm']]

Excel macro-enabled workbook file-extension string (lower-case, dot-prefixed).

LATIN_1_ENCODING: Final[str]

Legacy ISO-8859-1 / Latin-1 encoding used by AEAT sede fixed-width response bodies.

UTF_8_ENCODING: Final[str]

UTF-8 character encoding used for all text file I/O in the application layer.

PROVENANCE_SOURCE_MANUAL_CLI: Final[str]

Provenance source identifier for facts entered interactively via the CLI.

PROVENANCE_SOURCE_CENSO_ARTEFACT: Final[str]

Provenance source identifier for censal facts parsed from an operator-supplied Certificado de Situación Censal (procedure G313) artefact. A NON-OFFICIAL evidence tier: the artefact is operator-channel input, never stamped AEAT-verified, so the overview calendar’s censo.enrolment_unverified posture is unaffected by facts carrying this token.

SANDBOX_LABEL_PREFIX: Final[str]

Reserved operator-visible bucket-label prefix identifying a sandbox profile. A profile whose plaintext manifest label starts with this token is a sandbox: an isolated, discardable bucket. Declared in the light core layer so the state-free CLI surface (aeat / --help / --version) can check the active bucket’s sandbox status without importing the heavy bucket_maintenance / workflow facades. bucket_maintenance._sandbox re-exports it as the canonical application-facing name.

OUTPUT_LANGUAGE_ENV_VAR: Final[str]

Environment variable name used to override the CLI output language at runtime.

class OutputLanguage(*values)[source]

Bases: StrEnum

Closed enumeration of CLI / API output language BCP-47 tags.

The four members match the locale catalogues committed under src/cadrumo/locales/. Adding a new operator-facing language requires landing the catalogue first and then extending this enum so the loader-side gates remain in sync.

ES
EN
CA
HU
DEFAULT_OUTPUT_LANGUAGE: Final[OutputLanguage]

BCP-47 language tag for the default CLI and API output language (Spanish).

SUPPORTED_OUTPUT_LANGUAGES: Final[tuple[str, ...]]

Ordered tuple of BCP-47 language tags supported by the CLI and API output layer. Kept as tuple[str, ...] (not tuple[OutputLanguage, ...]) so click.Choice(SUPPORTED_OUTPUT_LANGUAGES) renders the operator-facing lowercase tags ([es|en|ca|hu]) on parse failure rather than the enum NAMES ([ES|EN|CA|HU]) that Click derives from StrEnum members. The OutputLanguage enum stays the canonical closed-set authority above; this constant is the str-typed projection used at the click.Choice boundary.

load_external_constants(path=None)[source]

Return the parsed external-constants registry.

Cached per-process; the first call reads and validates external_constants.toml from the package directory via importlib.resources so the resolution path is identical under editable installs and built wheels. Passing path is reserved for audits and tests that need to validate an alternate TOML payload against the same schema.

Parameters:

path (Path | None) – Optional TOML file to parse instead of the packaged registry.

Return type:

ExternalConstants

Returns:

The process-wide cached ExternalConstants instance.