Module adcp.canonical_formats.format_options

Closed-set format_options[] validation.

Per AdCP 3.1 ProductFormatDeclaration.seller_preference (normative):

<code>format\_options\[]</code> IS the closed set of accepted formats; anything
outside the list is rejected at <code>create\_media\_buy</code> regardless of
preference.

Sellers MUST reject a create_media_buy whose creative manifest declares a format_kind outside the product's published format_options[]. This module provides the pre-call guard.

Two helpers:

Functions

def find_declaration_by_kind(format_kind: str | CanonicalFormatKind,
format_options: Iterable[ProductFormatDeclaration],
*,
capability_id: str | None = None) ‑> ProductFormatDeclaration | None
Expand source code
def find_declaration_by_kind(
    format_kind: str | CanonicalFormatKind,
    format_options: Iterable[ProductFormatDeclaration],
    *,
    capability_id: str | None = None,
) -> ProductFormatDeclaration | None:
    """Look up the declaration in ``format_options[]`` matching the kind.

    Disambiguates with ``capability_id`` when the closed set carries
    multiple declarations sharing the same ``format_kind`` (the case
    where ``capability_id`` is REQUIRED per
    ``ProductFormatDeclaration.capability_id``).

    Args:
        format_kind: The kind to match. Accepts string or enum.
        format_options: The product's ``format_options[]``.
        capability_id: When provided, only declarations whose
            ``capability_id`` equals this value are considered a match.
            When omitted, the first kind match wins; this is unambiguous
            only when every declaration of that kind shares the same
            ``capability_id``.

    Returns:
        The matching declaration, or ``None`` when no declaration in the
        closed set satisfies the query.
    """
    wanted = _coerce_kind(format_kind)
    for d in format_options:
        if _coerce_kind(d.format_kind) != wanted:
            continue
        if capability_id is not None and d.capability_id != capability_id:
            continue
        return d
    return None

Look up the declaration in format_options[] matching the kind.

Disambiguates with capability_id when the closed set carries multiple declarations sharing the same format_kind (the case where capability_id is REQUIRED per ProductFormatDeclaration.capability_id).

Args

format_kind
The kind to match. Accepts string or enum.
format_options
The product's format_options[].
capability_id
When provided, only declarations whose capability_id equals this value are considered a match. When omitted, the first kind match wins; this is unambiguous only when every declaration of that kind shares the same capability_id.

Returns

The matching declaration, or None when no declaration in the closed set satisfies the query.

def find_declaration_by_v1_format_id(format_id: FormatId, format_options: Iterable[ProductFormatDeclaration]) ‑> ProductFormatDeclaration | None
Expand source code
def find_declaration_by_v1_format_id(
    format_id: FormatId,
    format_options: Iterable[ProductFormatDeclaration],
) -> ProductFormatDeclaration | None:
    """Look up the declaration whose ``v1_format_ref[]`` includes ``format_id``.

    Seller-side helper for processing v1 ``create_media_buy`` requests
    against a product publishing v2 ``format_options[]``. A buyer
    targeting a v1 ``format_id`` lands here: the SDK walks the closed
    set looking for the declaration that asserted this v1 ref.

    Matches on both ``agent_url`` and ``id`` — a v1 format identity is
    the ``(agent_url, id)`` pair, not the id alone. Returns the first
    declaration whose ``v1_format_ref[]`` contains a structurally equal
    entry.

    Args:
        format_id: The v1 ``FormatId`` the buyer's manifest targets.
        format_options: The product's ``format_options[]`` closed set.

    Returns:
        The matching declaration, or ``None`` when no declaration in the
        closed set asserts this v1 ref. ``None`` means the request
        should be rejected with ``UNSUPPORTED_FEATURE`` — the v1
        ``format_id`` is not a recognised entry for this product. If a
        caller expected a legacy ID such as ``display_300x250`` to match a
        parameterized canonical ref, use ``formats_are_equivalent`` or
        ``format_is_supported`` from :mod:`adcp.canonical_formats` instead of
        this closed-set v1 reference lookup.
    """
    target_url = canonicalize_agent_url(format_id.agent_url)
    target_id = format_id.id
    for decl in format_options:
        refs = decl.v1_format_ref or []
        for ref in refs:
            ref_url = canonicalize_agent_url(ref.agent_url)
            if ref_url == target_url and ref.id == target_id:
                return decl
    return None

Look up the declaration whose v1_format_ref[] includes format_id.

Seller-side helper for processing v1 create_media_buy requests against a product publishing v2 format_options[]. A buyer targeting a v1 format_id lands here: the SDK walks the closed set looking for the declaration that asserted this v1 ref.

Matches on both agent_url and id — a v1 format identity is the (agent_url, id) pair, not the id alone. Returns the first declaration whose v1_format_ref[] contains a structurally equal entry.

Args

format_id
The v1 FormatId the buyer's manifest targets.
format_options
The product's format_options[] closed set.

Returns

The matching declaration, or None when no declaration in the closed set asserts this v1 ref. None means the request should be rejected with UNSUPPORTED_FEATURE — the v1 format_id is not a recognised entry for this product. If a caller expected a legacy ID such as display_300x250 to match a parameterized canonical ref, use formats_are_equivalent or format_is_supported from :mod:adcp.canonical_formats instead of this closed-set v1 reference lookup.

def validate_format_kind_in_options(format_kind: str | CanonicalFormatKind,
format_options: Iterable[ProductFormatDeclaration]) ‑> None
Expand source code
def validate_format_kind_in_options(
    format_kind: str | CanonicalFormatKind,
    format_options: Iterable[ProductFormatDeclaration],
) -> None:
    """Raise if ``format_kind`` isn't published in ``format_options[]``.

    Args:
        format_kind: The kind a buyer's manifest targets. Accepts both
            the wire-string form (``"image"``) and the typed enum form
            (``CanonicalFormatKind.image``).
        format_options: The product's closed set of accepted format
            declarations.

    Raises:
        FormatKindNotInClosedSetError: when no declaration in the closed
            set carries that ``format_kind``. The seller MUST surface
            ``UNSUPPORTED_FEATURE`` on the response.
    """
    wanted = _coerce_kind(format_kind)
    accepted = [_coerce_kind(d.format_kind) for d in format_options]
    if wanted not in accepted:
        raise FormatKindNotInClosedSetError(wanted, accepted)

Raise if format_kind isn't published in format_options[].

Args

format_kind
The kind a buyer's manifest targets. Accepts both the wire-string form ("image") and the typed enum form (CanonicalFormatKind.image).
format_options
The product's closed set of accepted format declarations.

Raises

FormatKindNotInClosedSetError
when no declaration in the closed set carries that format_kind. The seller MUST surface UNSUPPORTED_FEATURE on the response.

Classes

class FormatKindNotInClosedSetError (format_kind: str, accepted_kinds: list[str])
Expand source code
class FormatKindNotInClosedSetError(ValueError):
    """Raised when a ``format_kind`` is not in the product's ``format_options[]``.

    Carries the rejected kind plus the closed set on the exception
    instance so handlers can surface them on the wire response (e.g.,
    via ``error.details.accepted_values``). Use :meth:`to_wire_error`
    to construct the response ``Error`` directly.
    """

    def __init__(
        self,
        format_kind: str,
        accepted_kinds: list[str],
    ) -> None:
        self.format_kind = format_kind
        self.accepted_kinds = accepted_kinds
        super().__init__(
            f"format_kind={format_kind!r} is not in the product's format_options[] "
            f"closed set (accepted: {sorted(set(accepted_kinds))!r})."
        )

    def to_wire_error(
        self,
        *,
        field: str = "manifest.format_kind",
        message: str | None = None,
    ) -> Error:
        """Build the wire-correct ``UNSUPPORTED_FEATURE`` ``Error`` for the response.

        Per ``error.json``, closed-set rejections SHOULD use
        ``details.rejected_value`` + ``details.accepted_values`` so
        buyer-side diagnostic tooling can surface the accepted set
        without per-seller pattern matching.

        Args:
            field: JSONPath-lite pointer to the rejected field on the
                buyer's request (default ``"manifest.format_kind"`` —
                the typical ``create_media_buy`` location).
            message: Override the default human-readable message.
        """
        return Error(
            code="UNSUPPORTED_FEATURE",
            message=message or str(self),
            field=field,
            details={
                "rejected_value": self.format_kind,
                "accepted_values": sorted(set(self.accepted_kinds)),
            },
        )

Raised when a format_kind is not in the product's format_options[].

Carries the rejected kind plus the closed set on the exception instance so handlers can surface them on the wire response (e.g., via error.details.accepted_values). Use :meth:to_wire_error to construct the response Error directly.

Ancestors

  • builtins.ValueError
  • builtins.Exception
  • builtins.BaseException

Methods

def to_wire_error(self, *, field: str = 'manifest.format_kind', message: str | None = None) ‑> adcp.types.generated_poc.core.error.Error
Expand source code
def to_wire_error(
    self,
    *,
    field: str = "manifest.format_kind",
    message: str | None = None,
) -> Error:
    """Build the wire-correct ``UNSUPPORTED_FEATURE`` ``Error`` for the response.

    Per ``error.json``, closed-set rejections SHOULD use
    ``details.rejected_value`` + ``details.accepted_values`` so
    buyer-side diagnostic tooling can surface the accepted set
    without per-seller pattern matching.

    Args:
        field: JSONPath-lite pointer to the rejected field on the
            buyer's request (default ``"manifest.format_kind"`` —
            the typical ``create_media_buy`` location).
        message: Override the default human-readable message.
    """
    return Error(
        code="UNSUPPORTED_FEATURE",
        message=message or str(self),
        field=field,
        details={
            "rejected_value": self.format_kind,
            "accepted_values": sorted(set(self.accepted_kinds)),
        },
    )

Build the wire-correct UNSUPPORTED_FEATURE Error for the response.

Per error.json, closed-set rejections SHOULD use details.rejected_value + details.accepted_values so buyer-side diagnostic tooling can surface the accepted set without per-seller pattern matching.

Args

field
JSONPath-lite pointer to the rejected field on the buyer's request (default "manifest.format_kind" — the typical create_media_buy location).
message
Override the default human-readable message.