aeat.application.portals._service module

Read-only portal discovery wrapping the domain registry.

PortalsService exposes a local read surface over the immutable portal registry. Each entry is identified by a Portal value, carries a PortalCategory axis, and may be associated with a ModeloCode so callers can filter portal metadata without inspecting the raw registry.

The service returns PortalRow projections of PortalMetadata; it never opens URLs, checks reachability, requires a live-read gate, or emits bucket events.

exception PortalNotFoundError(message=None, *, context=None, suggestion=None, translated_message=None)[source]

Bases: AeatError

Raised when portal lookup targets a Portal absent from the registry.

Parameters:
  • message (str | None)

  • context (Mapping[str, object] | None)

  • suggestion (str | None)

  • translated_message (str | None)

Return type:

None

code: ClassVar[ErrorCode]
class PortalRow(**data)[source]

Bases: BaseModel

Operator-facing row in aeat app live portals list output.

Slimmer than the underlying PortalMetadata: we elide the translation-key indirection for notes and surface only the primary fields the operator can act on. The CLI renderer applies i18n where needed.

Parameters:
portal: Portal
url: str
category: PortalCategory
auth_methods: tuple[str, ...]
url_stability: str
active: bool
replaced_by: Portal | None
label_key: str
purpose_key: str
class PortalsService(registry=None)[source]

Bases: object

Local-only portal-registry read surface.

No remote contact, no bucket events, no mutation. Pure projection over the immutable domain.portals.PORTAL_REGISTRY. Injecting a registry supports tests and alternate catalogue snapshots while preserving the same Portal to PortalMetadata contract.

Parameters:

registry (dict[Portal, PortalMetadata] | None)

list_portals(*, category=None, modelo=None, include_retired=False)[source]

Project the registry to operator-facing rows with optional filters.

Parameters:
Return type:

tuple[PortalRow, …]

category and modelo are independent filters. Retired portals (active=False) are excluded by default; pass include_retired=True to surface them so the operator can trace where a deprecated URL was supposed to redirect to.

Returns:

The list of portals.

Return type:

tuple[PortalRow, …]

Parameters:
show(portal)[source]

Return the PortalRow for one Portal.

Raises PortalNotFoundError when the requested portal code is absent from the injected registry.

Return type:

PortalRow

Parameters:

portal (Portal)