Module adcp.types.domains.core.placement
Classes
class Identifier (**data: Any)-
Expand source code
class Identifier(AdCPBaseModel): model_config = ConfigDict( extra='allow', ) type: identifier_types.PropertyIdentifierTypes value: Annotated[ str, Field( description='Identifier value, optionally authority-prefixed for externally governed IDs (e.g., space:1234931339).' ), ]Base model for AdCP types with spec-compliant serialization.
Defaults to
extra='ignore'so unknown fields from newer spec versions are silently dropped rather than causing validation errors. Generated types whose schemas setadditionalProperties: trueoverride this withextra='allow'in their ownmodel_config.Set
ADCP_STRICT_VALIDATION=1in the environment ("1","true","yes","on"are accepted) to flip the default toextra='forbid'. Use this during spec upgrades to catch silently-dropped renamed fields in tests. See :func:_resolve_extra_policy.Important
The env var is resolved once at module import time. Set it in your shell or CI environment before
import adcpruns — mutatingos.environ["ADCP_STRICT_VALIDATION"]after the firstadcpimport has no effect on already-imported model classes (they captured the policy at class-body evaluation).Consumers who want per-model strict validation can override
model_configon their subclass.Create a new model by parsing and validating input data from keyword arguments.
Raises [
ValidationError][pydantic_core.ValidationError] if the input data cannot be validated to form a valid model.selfis explicitly positional-only to allowselfas a field name.Ancestors
- AdCPBaseModel
- pydantic.main.BaseModel
Class variables
var model_configvar type : PropertyIdentifierTypesvar value : str
Inherited members
class Kind (*args, **kwds)-
Expand source code
class Kind(StrEnum): publisher_ref = 'publisher_ref' seller_inline = 'seller_inline'Enum where members are also (and must be) strings
Ancestors
- enum.StrEnum
- builtins.str
- enum.ReprEnum
- enum.Enum
Class variables
var publisher_refvar seller_inline
class Mode (*args, **kwds)-
Expand source code
class Mode(StrEnum): targetable = 'targetable' included = 'included'Enum where members are also (and must be) strings
Ancestors
- enum.StrEnum
- builtins.str
- enum.ReprEnum
- enum.Enum
Class variables
var includedvar targetable
class Placement (**data: Any)-
Expand source code
class Placement(AdCPBaseModel): model_config = ConfigDict( extra='allow', ) kind: Annotated[ Kind, Field( description='Placement authority discriminator. `publisher_ref` is publisher-catalog identity; `seller_inline` is sales-agent-authored identity.' ), ] placement_id: Annotated[ str, Field( description='Placement identifier. For publisher_ref it is scoped by publisher_domain and resolves in adagents.json. For seller_inline it is scoped by seller_agent, or by the enclosing seller and product for legacy rows.' ), ] publisher_domain: Annotated[ str | None, Field( description="For publisher_ref, the domain whose adagents.json declares the placement and part of canonical identity. For seller_inline, optional inventory-publisher attribution only; it does not grant the seller authority to mint IDs in that publisher's catalog namespace.", pattern='^[a-z0-9]([a-z0-9-]*[a-z0-9])?(\\.[a-z0-9]([a-z0-9-]*[a-z0-9])?)*$', ), ] = None seller_agent: Annotated[ seller_agent_ref.SellerAgentReference | None, Field( description='Sales agent that defines a seller_inline placement. Together with placement_id this is its self-contained identity. New 3.2 sellers SHOULD populate it; legacy product-context inline placements may omit it. Not used for publisher_ref.' ), ] = None name: Annotated[ str | None, Field( description='Human-readable name for the placement (e.g., \'Homepage Banner\', \'Article Sidebar\'). Required for `kind: "seller_inline"`. May be omitted for publisher-referenced placements because buyers resolve the name from the publisher declaration identified by `{publisher_domain, placement_id}`.' ), ] = None description: Annotated[ str | None, Field(description='Detailed description of where and how the placement appears') ] = None mode: Annotated[ Mode, Field( description="Required product-level relationship to this placement. targetable means the buyer may include the publisher-scoped ref in targeting_overlay.placement_selection; a creative may be routed there only after it is purchased. included means fixed product inventory: it cannot be independently selected, but across discovery, create, and update a selected request exactly equal to the product's complete included placement set is an inherent restatement and may be echoed on the package without overlay_support.placement_selection. A product containing any included placement MUST NOT declare overlay_support.placement_selection; partial selection requires a separately selectable product configuration. During the migration window ending 2026-11-25, buyers MAY tolerate legacy products that omit mode and treat them as targetable; after that date buyers SHOULD fail closed." ), ] tags: Annotated[ list[str] | None, Field( description="Optional tags for grouping placements within a product (e.g., 'homepage', 'native', 'premium'). When the placement_id comes from the publisher registry, these should align with the registry tags unless the product is narrowing scope." ), ] = None format_ids: Annotated[ Sequence[format_id.FormatReferenceStructuredObject] | None, Field( deprecated=True, description='Deprecated in AdCP 3.2; removed in AdCP 4.0. Legacy named-format placement narrowing. Can include concrete, template, or parameterized format IDs. When present on a product placement, this field narrows the product-level `format_ids` contract and MUST NOT introduce formats the product does not accept. Use canonical `format_options`.', min_length=1, ), ] = None format_options: Annotated[ list[product_format_declaration.ProductFormatDeclaration] | None, Field( description="Canonical seller-side narrowing for this product placement. When present, these declarations are intersected with the product-level format_options and MUST NOT introduce a format outside that product upper bound. For kind publisher_ref, buyers MUST also resolve {publisher_domain, placement_id} in the publisher's adagents.json and intersect the publisher catalog constraint: use the public placement's format_options when present (resolving bare format_option_id references against same-file top-level formats[]), otherwise use applicable top-level formats[] scoped to that placement's properties. Omitting this inline field removes only the seller-inline layer; it does not bypass a publisher placement or property-scoped narrowing. The placement inherits the full product-level set only when no applicable publisher catalog narrowing exists. Unresolved publisher placement or format-option references fail closed. Locale policy participates in the same intersection: when the product policy is absent, a placement may introduce any concrete policy as a narrowing of the unconstrained option; when both are present, every placement accepted_language_range must be contained by a product range under RFC 4647 Basic Filtering (`fr-CA` narrows `fr`; `fr` does not narrow `fr-CA`). Buyers compute effective locale eligibility independently for each placement. Any effective locale-constrained route is canonical-only and has no projecting product or placement format_id.", min_length=1, ), ] = None video_placement_types: Annotated[ list[video_placement_type.VideoPlacementType] | None, Field( description='Declared video placement types for this product placement, using IAB Tech Lab/OpenRTB 2.6 video.plcmt definitions with AdCP-native names. Most concrete placements SHOULD declare a single value; aggregate placements MAY declare multiple values. This is seller-declared discovery metadata, not independent verification of inventory quality or delivery context.', min_length=1, ), ] = None audio_distribution_types: Annotated[ list[audio_distribution_type.AudioDistributionType] | None, Field( description='Declared audio distribution types for this product placement, using IAB Tech Lab/OpenRTB 2.6 audio.feed definitions with AdCP-native names. Most concrete placements SHOULD declare a single value; aggregate placements MAY declare multiple values. This is seller-declared discovery metadata, not independent verification of inventory quality or delivery context.', min_length=1, ), ] = None sponsored_placement_types: Annotated[ list[sponsored_placement_type.SponsoredPlacementType] | None, Field( description='Declared sponsored-placement types for this product placement, distinguishing where the catalog-driven retail-media placement renders on the retailer surface. Most concrete placements SHOULD declare a single value; aggregate placements MAY declare multiple values. This is seller-declared discovery metadata, not independent verification of inventory quality or delivery context.', min_length=1, ), ] = None social_placement_surfaces: Annotated[ list[social_placement_surface.SocialPlacementSurface] | None, Field( description='Declared social-placement surfaces for this product placement, distinguishing the in-app surface where the social placement renders. Most concrete placements SHOULD declare a single value; aggregate placements MAY declare multiple values. This is seller-declared discovery metadata, not independent verification of inventory quality or delivery context.', min_length=1, ), ] = None identifiers: Annotated[ list[Identifier] | None, Field( description='Optional external inventory identifiers for this placement, using the same {type, value} shape as property identifiers. Externally governed IDs should be authority-prefixed (e.g., space:1234931339, geopath:30961, fcc:73953). Seller-local IDs are opaque values scoped by the surrounding publisher namespace. Useful for DOOH venue and installed-endpoint IDs, broadcast facility IDs, and any channel where placements map to externally registered inventory. For kind: publisher_ref, the effective identifier set is the union of the resolved publisher declaration and this product declaration, de-duplicated by exact (type, value); a product cannot suppress a publisher-declared identifier by omission.', min_length=1, ), ] = None dooh_placement_attributes: ProductDoohPlacementAttributes | None = None @model_validator(mode='after') def _require_schema_required_group(self) -> Placement: # ``required`` asks whether the caller supplied the field, which is what # model_fields_set answers. An explicit null is a supplied value — on a # mutation input it is the command to clear — and a default the caller # never sent is not. for group in (('name',), ('publisher_domain',),): if all(name in self.model_fields_set for name in group): return self raise ValueError( 'Placement requires at least one of these field groups: name | publisher_domain' )Base model for AdCP types with spec-compliant serialization.
Defaults to
extra='ignore'so unknown fields from newer spec versions are silently dropped rather than causing validation errors. Generated types whose schemas setadditionalProperties: trueoverride this withextra='allow'in their ownmodel_config.Set
ADCP_STRICT_VALIDATION=1in the environment ("1","true","yes","on"are accepted) to flip the default toextra='forbid'. Use this during spec upgrades to catch silently-dropped renamed fields in tests. See :func:_resolve_extra_policy.Important
The env var is resolved once at module import time. Set it in your shell or CI environment before
import adcpruns — mutatingos.environ["ADCP_STRICT_VALIDATION"]after the firstadcpimport has no effect on already-imported model classes (they captured the policy at class-body evaluation).Consumers who want per-model strict validation can override
model_configon their subclass.Create a new model by parsing and validating input data from keyword arguments.
Raises [
ValidationError][pydantic_core.ValidationError] if the input data cannot be validated to form a valid model.selfis explicitly positional-only to allowselfas a field name.Ancestors
- AdCPBaseModel
- pydantic.main.BaseModel
Subclasses
Class variables
var audio_distribution_types : list[AudioDistributionType] | Nonevar description : str | Nonevar dooh_placement_attributes : ProductDoohPlacementAttributes | Nonevar format_ids : collections.abc.Sequence[FormatReferenceStructuredObject] | Nonevar format_options : list[ProductFormatDeclaration1 | ProductFormatDeclaration2 | ProductFormatDeclaration3 | ProductFormatDeclaration4 | ProductFormatDeclaration5 | ProductFormatDeclaration6 | ProductFormatDeclaration7 | ProductFormatDeclaration8 | ProductFormatDeclaration9 | ProductFormatDeclaration10 | ProductFormatDeclaration11 | ProductFormatDeclaration12 | ProductFormatDeclaration13 | ProductFormatDeclaration14 | ProductFormatDeclaration15 | ProductFormatDeclaration16] | Nonevar identifiers : list[Identifier] | Nonevar kind : Kindvar mode : Modevar model_configvar name : str | Nonevar placement_id : strvar publisher_domain : str | Nonevar seller_agent : SellerAgentReference | Nonevar sponsored_placement_types : list[SponsoredPlacementType] | Nonevar video_placement_types : list[VideoPlacementType] | None
Inherited members
class ProductDoohPlacementAttributes (**data: Any)-
Expand source code
class ProductDoohPlacementAttributes(AdCPBaseModel): model_config = ConfigDict( extra='allow', ) slot_duration_seconds: Annotated[ SchemaInt | None, Field( description='Scheduled duration of one ad slot in seconds. This is an inventory fact used for loop and share calculations, not the creative-duration contract.', ge=1, ), ] = None loop_duration_seconds: Annotated[ SchemaInt | None, Field( description='Duration of the full ad loop rotation in seconds and the canonical source for loop duration.', ge=1, ), ] = None screen_resolution: ProductDoohScreenResolution | None = None motion: Annotated[ dooh_motion_type.DoohMotionType | None, Field( description='Physical motion capability of a visual DOOH screen, not an accepted-format declaration. Omit for audio-only placements.' ), ] = NoneBase model for AdCP types with spec-compliant serialization.
Defaults to
extra='ignore'so unknown fields from newer spec versions are silently dropped rather than causing validation errors. Generated types whose schemas setadditionalProperties: trueoverride this withextra='allow'in their ownmodel_config.Set
ADCP_STRICT_VALIDATION=1in the environment ("1","true","yes","on"are accepted) to flip the default toextra='forbid'. Use this during spec upgrades to catch silently-dropped renamed fields in tests. See :func:_resolve_extra_policy.Important
The env var is resolved once at module import time. Set it in your shell or CI environment before
import adcpruns — mutatingos.environ["ADCP_STRICT_VALIDATION"]after the firstadcpimport has no effect on already-imported model classes (they captured the policy at class-body evaluation).Consumers who want per-model strict validation can override
model_configon their subclass.Create a new model by parsing and validating input data from keyword arguments.
Raises [
ValidationError][pydantic_core.ValidationError] if the input data cannot be validated to form a valid model.selfis explicitly positional-only to allowselfas a field name.Ancestors
- AdCPBaseModel
- pydantic.main.BaseModel
Class variables
var loop_duration_seconds : int | Nonevar model_configvar motion : DoohMotionType | Nonevar screen_resolution : ProductDoohScreenResolution | Nonevar slot_duration_seconds : int | None
Inherited members
class ProductDoohScreenResolution (**data: Any)-
Expand source code
class ProductDoohScreenResolution(AdCPBaseModel): model_config = ConfigDict( extra='forbid', ) width: Annotated[SchemaInt, Field(description='Screen width in pixels.', ge=1)] height: Annotated[SchemaInt, Field(description='Screen height in pixels.', ge=1)]Base model for AdCP types with spec-compliant serialization.
Defaults to
extra='ignore'so unknown fields from newer spec versions are silently dropped rather than causing validation errors. Generated types whose schemas setadditionalProperties: trueoverride this withextra='allow'in their ownmodel_config.Set
ADCP_STRICT_VALIDATION=1in the environment ("1","true","yes","on"are accepted) to flip the default toextra='forbid'. Use this during spec upgrades to catch silently-dropped renamed fields in tests. See :func:_resolve_extra_policy.Important
The env var is resolved once at module import time. Set it in your shell or CI environment before
import adcpruns — mutatingos.environ["ADCP_STRICT_VALIDATION"]after the firstadcpimport has no effect on already-imported model classes (they captured the policy at class-body evaluation).Consumers who want per-model strict validation can override
model_configon their subclass.Create a new model by parsing and validating input data from keyword arguments.
Raises [
ValidationError][pydantic_core.ValidationError] if the input data cannot be validated to form a valid model.selfis explicitly positional-only to allowselfas a field name.Ancestors
- AdCPBaseModel
- pydantic.main.BaseModel
Class variables
var height : intvar model_configvar width : int
Inherited members