mundane.api.set_loader ====================== .. py:module:: mundane.api.set_loader .. autoapi-nested-parse:: Fetch, allowlist, validate, and snapshot external card sets — the only HTTP-aware card code. The engine never reaches the network; this module does. Given a list of set URLs it: (1) allowlists each (only the ``mundane-cards`` raw origin), (2) fetches with hardening (https, timeout, no redirects, size cap, content-type check), (3) validates each body against the **vendored** schema, (4) builds the cards via the engine loader, rejecting duplicate composed ids, and (5) returns the resolved pool plus a JSON-ready snapshot with a content hash so an exported game replays self-contained. On any failure it raises before the caller stores anything. Attributes ---------- .. autoapisummary:: mundane.api.set_loader.DEFAULT_SET_URLS mundane.api.set_loader.ALLOWLIST_HOST mundane.api.set_loader.ALLOWLIST_PATH_PREFIX mundane.api.set_loader.MAX_SET_BYTES mundane.api.set_loader.FETCH_TIMEOUT_SECONDS mundane.api.set_loader._SCHEMA mundane.api.set_loader._VALIDATOR mundane.api.set_loader.Fetcher Exceptions ---------- .. autoapisummary:: mundane.api.set_loader.SetURLNotAllowedError mundane.api.set_loader.SetFetchError mundane.api.set_loader.SetSchemaError Classes ------- .. autoapisummary:: mundane.api.set_loader.ResolvedPool Functions --------- .. autoapisummary:: mundane.api.set_loader._check_allowed mundane.api.set_loader.default_fetch mundane.api.set_loader.load_sets Module Contents --------------- .. py:data:: DEFAULT_SET_URLS :type: tuple[str, Ellipsis] :value: ('https://raw.githubusercontent.com/letsbuilda/mundane-cards/main/sets/core.json',) .. py:data:: ALLOWLIST_HOST :value: 'raw.githubusercontent.com' .. py:data:: ALLOWLIST_PATH_PREFIX :value: '/letsbuilda/mundane-cards/' .. py:data:: MAX_SET_BYTES :value: 1048576 .. py:data:: FETCH_TIMEOUT_SECONDS :value: 5.0 .. py:data:: _SCHEMA :type: dict[str, object] .. py:data:: _VALIDATOR .. py:data:: Fetcher Fetches the raw bytes of a set at a URL. Injectable so tests can serve a fixture offline. .. py:exception:: SetURLNotAllowedError Bases: :py:obj:`Exception` A requested set URL is not on the allowlist. Maps to HTTP 422. .. py:exception:: SetFetchError Bases: :py:obj:`Exception` A set could not be fetched (network, timeout, status, content-type, or size). Maps to 502. .. py:exception:: SetSchemaError Bases: :py:obj:`Exception` A fetched set was not valid JSON or failed schema validation. Maps to HTTP 422. .. py:class:: ResolvedPool The engine-facing pool plus the serialisable snapshot (resolved cards + content hash). .. py:attribute:: cards :type: dict[str, mundane.engine.state.Card] .. py:attribute:: snapshot :type: dict[str, object] .. py:function:: _check_allowed(url: str, host: str, prefix: str) -> None Reject ``url`` unless it is https, exactly on ``host``, and under ``prefix`` (parsed, not substring). .. py:function:: default_fetch(url: str) -> bytes Fetch ``url`` with hardening: a hard timeout, no redirects, a size cap, and a content-type check. .. py:function:: load_sets(set_urls: collections.abc.Sequence[str], *, fetch: Fetcher = default_fetch, allowlist_host: str = ALLOWLIST_HOST, allowlist_prefix: str = ALLOWLIST_PATH_PREFIX) -> ResolvedPool Allowlist, fetch, validate, and build the combined pool + snapshot for ``set_urls``. Raises before returning on any problem: :class:`SetURLNotAllowedError` / :class:`SetSchemaError` / engine ``UnknownEffectError`` / ``InvalidEffectParamsError`` / ``DuplicateCardError`` (all 422 at the API), or :class:`SetFetchError` (502).