Module adcp.types.domains.compliance.comply_test_controller_request

Classes

class Account (**data: Any)
Expand source code
class Account(AdCPBaseModel):
    model_config = ConfigDict(
        extra='allow',
    )
    sandbox: Annotated[
        Literal[True],
        Field(
            description='MUST be true. The seller MUST verify the targeted account is sandbox by looking up the persisted account record, not by trusting this field. A request asserting sandbox: false schema-rejects before reaching the seller — defense-in-depth on top of the per-request gate.'
        ),
    ]

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 set additionalProperties: true override this with extra='allow' in their own model_config.

Set ADCP_STRICT_VALIDATION=1 in the environment ("1", "true", "yes", "on" are accepted) to flip the default to extra='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 adcp runs — mutating os.environ["ADCP_STRICT_VALIDATION"] after the first adcp import 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_config on 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.

self is explicitly positional-only to allow self as a field name.

Ancestors

Class variables

var model_config
var sandbox : Literal[True]

Inherited members

class AdvanceTo (*args, **kwds)
Expand source code
class AdvanceTo(StrEnum):
    within_grace = 'within_grace'
    past_grace = 'past_grace'

Enum where members are also (and must be) strings

Ancestors

  • enum.StrEnum
  • builtins.str
  • enum.ReprEnum
  • enum.Enum

Class variables

var past_grace
var within_grace
class Arm (*args, **kwds)
Expand source code
class Arm(StrEnum):
    submitted = 'submitted'
    completed = 'completed'
    input_required = 'input-required'
    rejected = 'rejected'

Enum where members are also (and must be) strings

Ancestors

  • enum.StrEnum
  • builtins.str
  • enum.ReprEnum
  • enum.Enum

Class variables

var completed
var input_required
var rejected
var submitted
class ComplyTestControllerRequest (**data: Any)
Expand source code
class ComplyTestControllerRequest(AdcpRequest, AdcpVersionEnvelope):
    model_config = ConfigDict(
        extra='allow',
    )
    scenario: Annotated[
        str,
        Field(
            description="Test scenario to execute. 'list_scenarios' discovers supported scenarios. 'force_*' and 'simulate_*' trigger state transitions. 'reporting_core_lifecycle_probe' installs a caller/account-scoped Core fixture whose first elapsed obligation is visible before any report, advances its virtual clock into delayed or action_required, and can publish deterministic zero-row or non-empty revisions, restate a provisional revision, restate one the caller already received, or cross the consumer-status deadline and consumer-mismatch escalation boundaries, without waiting for wall-clock boundaries. Other scenarios provide deterministic sandbox probes for their documented lifecycle checks. Runners and sellers MUST accept unknown scenario strings - new scenarios may be added in additive releases."
        ),
    ]
    params: Annotated[
        Params | None,
        Field(
            description='Scenario-specific parameters. Required for all scenarios except list_scenarios.'
        ),
    ] = None
    context: context_1.ContextObject | None = None
    ext: ext_1.ExtensionObject | None = None
    account: Annotated[
        Account | None,
        Field(
            description="Sandbox account assertion. The runner MUST set sandbox: true on every comply_test_controller request. The seller MUST refuse the request (returning a structured error) if the targeted account is not a sandbox account in the seller's persisted records. This field is a caller-side declaration of intent — it does not grant sandbox status; sellers verify against their own account state. The (Sandbox) verification tier is defined by this gate: real production endpoints accept sandbox-flagged traffic and process it without real-world side effects, no separate test-mode endpoint required. See spec issue #3755 and the (Sandbox) framing in #4379."
        ),
    ] = None

The request message of a task in the pinned bundle's task registry.

A consumer holding one can resolve its account, decide at-most-once, echo its context and negotiate version – the whole transport-boundary job – before knowing which tool it is. issubclass(model, AdcpRequest) is the registration-time proof that a model is spec-derived rather than a hand-written parallel: a field test passes for a forged model, descent does not.

Each accessor returns the field's value, or None when this tool's schema declares no such field. Only 49 of the 87 request schemas declare an account and only 43 an idempotency_key, so asking the request is what replaces getattr(req, "account", None) against Any at the boundary.

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.

self is explicitly positional-only to allow self as a field name.

Ancestors

Class variables

var account : Account | None
var context : ContextObject | None
var ext : ExtensionObject | None
var model_config
var params : Params | None
var scenario : str

Inherited members

class Kind (*args, **kwds)
Expand source code
class Kind(StrEnum):
    cumulative = 'cumulative'
    period = 'period'
    rolling = 'rolling'

Enum where members are also (and must be) strings

Ancestors

  • enum.StrEnum
  • builtins.str
  • enum.ReprEnum
  • enum.Enum

Class variables

var cumulative
var period
var rolling
class Metric (**data: Any)
Expand source code
class Metric(AdCPBaseModel):
    model_config = ConfigDict(
        extra='allow',
    )
    metric_id: vendor_metric_id.VendorMetricId

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 set additionalProperties: true override this with extra='allow' in their own model_config.

Set ADCP_STRICT_VALIDATION=1 in the environment ("1", "true", "yes", "on" are accepted) to flip the default to extra='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 adcp runs — mutating os.environ["ADCP_STRICT_VALIDATION"] after the first adcp import 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_config on 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.

self is explicitly positional-only to allow self as a field name.

Ancestors

Class variables

var metric_id : VendorMetricId
var model_config

Inherited members

class NotYetMeasurableVendorMetric (**data: Any)
Expand source code
class NotYetMeasurableVendorMetric(AdCPBaseModel):
    model_config = ConfigDict(
        extra='forbid',
    )
    vendor: brand_ref.BrandReference
    metric_id: vendor_metric_id.VendorMetricId
    qualifier: Annotated[
        committed_metric.Qualifier | None,
        Field(
            description='Qualifier for the exact committed vendor-metric row whose measurement is deferred.'
        ),
    ] = None

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 set additionalProperties: true override this with extra='allow' in their own model_config.

Set ADCP_STRICT_VALIDATION=1 in the environment ("1", "true", "yes", "on" are accepted) to flip the default to extra='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 adcp runs — mutating os.environ["ADCP_STRICT_VALIDATION"] after the first adcp import 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_config on 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.

self is explicitly positional-only to allow self as a field name.

Ancestors

Subclasses

Class variables

var metric_id : VendorMetricId
var model_config
var qualifier : Qualifier | None
var vendor : BrandReference

Inherited members

class NotYetMeasurableVendorMetricsByPackageItem (**data: Any)
Expand source code
class NotYetMeasurableVendorMetricsByPackageItem(NotYetMeasurableVendorMetric):
    pass

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 set additionalProperties: true override this with extra='allow' in their own model_config.

Set ADCP_STRICT_VALIDATION=1 in the environment ("1", "true", "yes", "on" are accepted) to flip the default to extra='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 adcp runs — mutating os.environ["ADCP_STRICT_VALIDATION"] after the first adcp import 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_config on 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.

self is explicitly positional-only to allow self as a field name.

Ancestors

Class variables

var model_config

Inherited members

class Operation (*args, **kwds)
Expand source code
class Operation(StrEnum):
    seed_inaccessible_item = 'seed_inaccessible_item'
    query_eligibility = 'query_eligibility'
    advance_time = 'advance_time'
    recreate_catalog = 'recreate_catalog'
    prepare = 'prepare'
    expire_proposal = 'expire_proposal'
    publish_zero_row = 'publish_zero_row'
    publish_nonempty = 'publish_nonempty'
    restate_snapshot = 'restate_snapshot'
    restate_after_received = 'restate_after_received'
    omit_obligation = 'omit_obligation'
    advance_past_status_deadline = 'advance_past_status_deadline'
    advance_past_escalation = 'advance_past_escalation'
    publish_official_adjustment = 'publish_official_adjustment'
    probe_scheduler_dst = 'probe_scheduler_dst'
    suppress_readiness = 'suppress_readiness'
    advance_within_retention = 'advance_within_retention'
    revoke_access = 'revoke_access'
    publish_adjustment = 'publish_adjustment'

Enum where members are also (and must be) strings

Ancestors

  • enum.StrEnum
  • builtins.str
  • enum.ReprEnum
  • enum.Enum

Class variables

var advance_past_escalation
var advance_past_status_deadline
var advance_time
var advance_within_retention
var expire_proposal
var omit_obligation
var prepare
var probe_scheduler_dst
var publish_adjustment
var publish_nonempty
var publish_official_adjustment
var publish_zero_row
var query_eligibility
var recreate_catalog
var restate_after_received
var restate_snapshot
var revoke_access
var seed_inaccessible_item
var suppress_readiness
class Params (**data: Any)
Expand source code
class Params(AdCPBaseModel):
    model_config = ConfigDict(
        extra='allow',
    )
    creative_id: Annotated[
        str | None,
        Field(
            description='Creative to transition (force_creative_status) or seed (seed_creative).'
        ),
    ] = None
    account_id: Annotated[
        str | None,
        Field(
            description='Account to transition, simulate, or seed. Used by force_account_status, simulate_budget_spend, and seed_account.'
        ),
    ] = None
    media_buy_id: Annotated[
        str | None,
        Field(
            description='Media buy to transition or purge (force_media_buy_status, force_media_buy_purge), simulate (simulate_delivery, simulate_budget_spend), or seed (seed_media_buy).'
        ),
    ] = None
    session_id: Annotated[
        str | None, Field(description='Session to transition. Used by force_session_status.')
    ] = None
    product_id: Annotated[
        str | None,
        Field(
            description='Product to seed or prepare for deterministic compact lifecycle testing. Used by seed_product, seed_pricing_option, compact_product_lifecycle_probe prepare, and compact_direct_buy_lifecycle_probe prepare.'
        ),
    ] = None
    proposal_id: Annotated[
        str | None,
        Field(
            description='Committed proposal whose hold the compact_product_lifecycle_probe expires.',
            min_length=1,
        ),
    ] = None
    pricing_option_id: Annotated[
        str | None,
        Field(
            description='Pricing option to seed, scoped to a product. Used by seed_pricing_option.'
        ),
    ] = None
    plan_id: Annotated[str | None, Field(description='Plan to seed. Used by seed_plan.')] = None
    rights_id: Annotated[
        str | None, Field(description='Rights grant to seed. Used by seed_rights_grant.')
    ] = None
    fixture: Annotated[
        dict[str, Any] | None,
        Field(
            description='Arbitrary fixture payload carried by seed_* scenarios. Shape matches the domain object the seed scenario creates (account, product, creative, plan, media buy, pricing option, rights grant). Seller MAY reject malformed fixtures with INVALID_PARAMS. Kept permissive so storyboard authors can declare the minimum shape each test needs without the spec locking down every field.'
        ),
    ] = None
    operation: Annotated[
        Operation | None,
        Field(
            description="Scenario-specific probe operation. catalog_item_availability_probe uses seed_inaccessible_item, query_eligibility, advance_time, and recreate_catalog. compact_product_lifecycle_probe uses prepare to make one seeded product's compact proposal, acceptance, operational-control, and MediaBuy readback path deterministic and expire_proposal to advance strictly beyond a committed proposal's stored expires_at and process the hold lapse. compact_direct_buy_lifecycle_probe uses prepare to make one seeded product's list, direct-purchase, operational-control, and readback path deterministic. reporting_core_lifecycle_probe uses prepare, advance_time, publish_zero_row, publish_nonempty, restate_snapshot, restate_after_received, omit_obligation, advance_past_status_deadline, and advance_past_escalation to exercise obligation availability, health deadlines, explicit reporting, provisional restatement, stale-received grace, buyer-side missing-obligation detection, counted consumer-status silence, and consumer-mismatch escalation. advance_past_status_deadline moves the clock strictly past expected_at plus the advertised automated_recovery_window_seconds without recording any consumer status, so obligation_counts.consumer_status_pending is gradable; advance_past_escalation moves it strictly past the open CONSUMER_STATUS_MISMATCH issue opened_at plus the advertised consumer_mismatch_escalation_seconds and returns both that boundary and any still-future stale_received_grace_deadline, so the escalation precedence rule is gradable. restate_snapshot publishes a new snapshot revision that immediately supersedes the current snapshot for the same logical slice and is invalid when the current revision is official. restate_after_received does the same restatement but only against the revision named in received_reporting_revision_id, so the stale-received grace projection can be graded live; it returns the grace deadline and advance_to positions the virtual clock inside or past it. Reliable Reporting tier probes use prepare plus publish_official_adjustment, probe_scheduler_dst, suppress_readiness, advance_within_retention, revoke_access, or publish_adjustment to seed deterministic Core-integrity, Managed Delivery, and Reconciled Billing lifecycle evidence."
        ),
    ] = None
    target_health: Annotated[
        TargetHealth | None,
        Field(
            description='Clock-derived health boundary selected by reporting_core_lifecycle_probe advance_time. The controller chooses the corresponding deterministic target time; callers do not supply timestamps.'
        ),
    ] = None
    received_reporting_revision_id: Annotated[
        str | None,
        Field(
            description="Revision the caller currently reports as received, required by reporting_core_lifecycle_probe restate_after_received. The seller MUST reject the operation unless this names the caller's current required revision for the fixture obligation, and a seller advertising consumer_status_task MUST additionally require a current received consumer status from this caller naming it. This binds the restatement to a real prior read instead of restating into a vacuum.",
            max_length=255,
            min_length=1,
            pattern='^[A-Za-z0-9_.:-]{1,255}$',
        ),
    ] = None
    advance_to: Annotated[
        AdvanceTo | None,
        Field(
            description='Where reporting_core_lifecycle_probe restate_after_received leaves the virtual clock relative to the returned stale_received_grace_deadline. within_grace grades the delayed projection; past_grace grades the escalation to action_required. Repeating the operation is convergent: it reuses the committed restatement and only moves the clock.'
        ),
    ] = AdvanceTo.within_grace
    catalog_id: Annotated[
        str | None,
        Field(
            description='Catalog operated on by catalog_item_availability_probe.',
            max_length=255,
            min_length=1,
        ),
    ] = None
    catalog_generation: Annotated[
        str | None,
        Field(
            description='Catalog incarnation operated on by catalog_item_availability_probe.',
            max_length=255,
            min_length=1,
        ),
    ] = None
    item_id: Annotated[
        str | None,
        Field(
            description='Catalog item operated on by catalog_item_availability_probe.',
            max_length=255,
            min_length=1,
        ),
    ] = None
    target_time: Annotated[
        AwareDatetime | None,
        Field(
            description='Deterministic sandbox clock target used by catalog_item_availability_probe advance_time.'
        ),
    ] = None
    status: Annotated[
        str | None,
        Field(
            description="Target status for the resource. Type depends on scenario: creative-status for force_creative_status, account-status for force_account_status, media-buy-status for force_media_buy_status. For force_session_status, must be 'complete' or 'terminated'."
        ),
    ] = None
    rejection_reason: Annotated[
        str | None,
        Field(
            description='Reason for rejection. Used by force_creative_status and force_media_buy_status when status = rejected.'
        ),
    ] = None
    purge_kind: Annotated[
        PurgeKind | None,
        Field(
            description='Purge mode for force_creative_purge. soft retains a list_creatives tombstone; hard removes the creative entirely.'
        ),
    ] = None
    reason_code: Annotated[
        creative_event_reason_code.CreativeEventReasonCode | None,
        Field(
            description='Creative lifecycle reason code for force_creative_status and force_creative_purge.'
        ),
    ] = None
    reason_detail: Annotated[
        str | None,
        Field(
            description='Human-readable detail for force_creative_status and force_creative_purge.'
        ),
    ] = None
    termination_reason: Annotated[
        str | None,
        Field(
            description='Reason for termination (e.g., session_timeout, host_terminated, policy_violation). Used by force_session_status when status = terminated.'
        ),
    ] = None
    impressions: Annotated[
        SchemaInt | None,
        Field(description='Impressions to simulate. Used by simulate_delivery.', ge=0),
    ] = None
    clicks: Annotated[
        SchemaInt | None, Field(description='Clicks to simulate. Used by simulate_delivery.', ge=0)
    ] = None
    plays: Annotated[
        SchemaInt | None,
        Field(
            description='Raw DOOH or broadcast plays to add to delivery. Used by simulate_delivery for single-package buys; sellers MUST surface the cumulative value at totals.plays and by_package[0].plays in the next get_media_buy_delivery response. Multi-package simulations require a future package-scoped form and MUST reject this media-buy-scoped field.',
            ge=0,
        ),
    ] = None
    dooh_metrics: Annotated[
        delivery_metrics.DoohMetrics | None,
        Field(
            description='DOOH delivery detail to inject. Used by simulate_delivery for single-package buys; the latest injected block replaces the previous simulated DOOH detail and MUST surface at totals.dooh_metrics and by_package[0].dooh_metrics. Multi-package simulations require a future package-scoped form and MUST reject this media-buy-scoped field.'
        ),
    ] = None
    conversions: Annotated[
        SchemaInt | None,
        Field(description='Conversions to simulate. Used by simulate_delivery.', ge=0),
    ] = None
    delivery_date: Annotated[
        date | None,
        Field(
            description="Calendar date, in the product's reporting_capabilities.timezone, attributable to this simulated delivery batch. Used by simulate_delivery to seed deterministic date-range tests. When get_media_buy_delivery supplies start_date or end_date, dated batches are included when delivery_date is greater than or equal to start_date and strictly less than end_date. Omit to preserve cumulative, unfiltered simulation behavior."
        ),
    ] = None
    conversion_value: Annotated[
        StrictFloat | None,
        Field(
            description='Total attributed conversion value to simulate in the delivery reporting currency. Used by simulate_delivery.',
            ge=0.0,
        ),
    ] = None
    commissionable_value: Annotated[
        StrictFloat | None,
        Field(
            description='Settled attributed value eligible for revenue-share commission to simulate in the delivery reporting currency. Used by simulate_delivery.',
            ge=0.0,
        ),
    ] = None
    reported_spend: Annotated[
        ReportedSpend | None,
        Field(
            description='Spend as reported in delivery data. Does not affect budget. Used by simulate_delivery.'
        ),
    ] = None
    reach: Annotated[
        StrictFloat | None,
        Field(
            description="Unique reach count to inject into the simulated delivery row. Used by simulate_delivery. The unit of measurement matches the reach_unit declared on the media buy's optimization goal. When supplied, sellers MUST surface this value at `totals.reach` in the next get_media_buy_delivery response.",
            ge=0.0,
        ),
    ] = None
    frequency: Annotated[
        StrictFloat | None,
        Field(
            description='Average frequency per reach unit to inject. Used by simulate_delivery. When supplied, sellers MUST surface this value at `totals.frequency`, including frequency-only delivery. The measurement window for this frequency value is declared in `reach_window` when also present.',
            ge=0.0,
        ),
    ] = None
    reach_unit: Annotated[
        reach_unit_1.ReachUnit | None,
        Field(
            description='Unit for an injected reach or frequency value. Used by simulate_delivery. When supplied with reach or frequency, sellers MUST surface it on the corresponding delivery row.'
        ),
    ] = None
    reach_window: Annotated[
        ReachWindow | None,
        Field(
            description='Measurement window semantics to attach to the simulated reach and frequency values. Used by simulate_delivery. When present, sellers MUST populate `reach_window` on the delivery row so buyers can determine the window semantics (cumulative vs. period vs. rolling). Omitting this param produces a row with no `reach_window` — valid per schema but sum-unsafe. Mirrors the `reach_window` shape in delivery-metrics.json.'
        ),
    ] = None
    viewability: Annotated[
        delivery_metrics.Viewability | None,
        Field(
            description='Viewability metrics to inject into simulated delivery. Uses the canonical delivery viewability shape, including viewed-seconds distributions. This media-buy-scoped form is valid only for a single-package buy, where the reference seller surfaces the same values at package and media-buy totals grain.'
        ),
    ] = None
    vendor_metric_values: Annotated[
        list[vendor_metric_value.VendorMetricValue] | None,
        Field(
            description="Vendor-defined metric values to inject into the next delivery report. Used by simulate_delivery. The reference seller reconciles these rows against each package's seller-stamped committed_metrics contract."
        ),
    ] = None
    vendor_metric_values_by_package: Annotated[
        dict[str, list[vendor_metric_value.VendorMetricValue]] | None,
        Field(
            description='Package-scoped vendor-defined values to inject, keyed by package_id. Used by simulate_delivery for multi-package buys. Sellers MUST use this form whenever more than one package could carry the same vendor/metric_id key; the legacy media-buy-scoped vendor_metric_values form is unambiguous only for a single-package buy.'
        ),
    ] = None
    not_yet_measurable_vendor_metrics: Annotated[
        list[NotYetMeasurableVendorMetric] | None,
        Field(
            description='Committed vendor metrics that are not yet measurable for the simulated measurement window. Used by simulate_delivery to prove that a future metric is omitted from missing_metrics until its measurement window matures.'
        ),
    ] = None
    not_yet_measurable_vendor_metrics_by_package: Annotated[
        dict[str, list[NotYetMeasurableVendorMetricsByPackageItem]] | None,
        Field(
            description="Package-scoped committed vendor metrics that are not yet measurable for the simulated window, keyed by package_id. Used by simulate_delivery for multi-package buys so a deferral on one package never suppresses another package's overdue gap."
        ),
    ] = None
    spend_percentage: Annotated[
        StrictFloat | None,
        Field(
            description='Spend to this percentage of budget (0–100). Used by simulate_budget_spend.',
            ge=0.0,
            le=100.0,
        ),
    ] = None
    arm: Annotated[
        Arm | None,
        Field(
            description="Response arm for the next forced operation call. Used by force_create_media_buy_arm, force_get_products_arm, force_get_signals_arm, and force_get_creative_features_arm. 'submitted' is supported for all four operations; get_creative_features also supports 'completed' with a deterministic result; create_media_buy also supports 'input-required'; get_products also supports 'rejected'. Async completion after a submitted task is covered by force_task_completion; 'working' is an out-of-band progress signal, not an initial response arm."
        ),
    ] = None
    task_id: Annotated[
        str | None,
        Field(
            description="Deterministic task handle the seller MUST emit verbatim on the next forced operation response when arm is 'submitted'. The seller MUST accept this exact value on subsequent tasks/get or get_task_status calls within the same authenticated sandbox account + principal pair and MUST return REFERENCE_NOT_FOUND for the same task_id under any other account or principal. Sandbox task_ids are caller-opaque strings - the seller's production task-id format rules do not apply.",
            max_length=128,
        ),
    ] = None
    evaluation_id: Annotated[
        str | None,
        Field(
            description='Deterministic provider evaluation identity the seller MUST emit on the next forced get_creative_features submitted acknowledgement and preserve on its terminal completion result.',
            max_length=255,
            min_length=1,
        ),
    ] = None
    message: Annotated[
        str | None,
        Field(
            description='Optional human-readable explanation surfaced on the next forced operation response. Used by force_create_media_buy_arm, force_get_products_arm, force_get_signals_arm, and force_get_creative_features_arm for the submitted arm. Plain text only.',
            max_length=2000,
        ),
    ] = None
    reason: Annotated[
        str | None,
        Field(
            description="Deterministic buyer-facing reason the seller MUST emit on the next get_products response when force_get_products_arm uses arm 'rejected'. Plain text only; MUST NOT expose confidential internal rules, inventory identifiers, credentials, or stack traces.",
            max_length=2000,
            min_length=1,
        ),
    ] = None
    suggestions: Annotated[
        list[Suggestion] | None,
        Field(
            description="Optional deterministic alternatives the seller MUST emit on the next get_products rejection. Used only by force_get_products_arm with arm 'rejected'.",
            max_length=20,
            min_length=1,
        ),
    ] = None
    format_id: Annotated[
        str | None,
        Field(
            deprecated=True,
            description='**DEPRECATED 3.x compatibility fixture.** Legacy named-format ID to seed for seed_creative_format scenarios. The seller MUST expose it through the deprecated list_creative_formats projection for the duration of the compliance session. Canonical 3.2 scenarios seed creative.supported_formats capabilities instead.',
        ),
    ] = None
    vendor: Annotated[
        brand_ref.BrandReference | None,
        Field(
            description="Measurement vendor whose catalog is being seeded. Used by seed_measurement_catalog. The seller MUST treat `metrics[]` as this vendor's `get_adcp_capabilities.measurement.metrics[]` snapshot for the duration of the compliance session."
        ),
    ] = None
    metrics: Annotated[
        list[Metric] | None,
        Field(
            description='Measurement catalog entries to seed for the vendor. Used by seed_measurement_catalog. Shape mirrors `get_adcp_capabilities.measurement.metrics[]`; each metric_id is unique within the seeded vendor catalog.',
            min_length=1,
        ),
    ] = None
    tool: Annotated[
        str | None,
        Field(
            description="Tool name whose upstream dependency to affect. Used by force_upstream_unavailable. The seller marks the named upstream as unreachable for subsequent calls to this tool within the compliance session. Sellers MAY accept a wildcard ('*') to affect all tools."
        ),
    ] = None
    upstream_name: Annotated[
        str | None,
        Field(
            description="Human-readable identifier for the upstream dependency to force unavailable (e.g., 'inventory-service', 'creative-agent'). Used by force_upstream_unavailable. When omitted, the seller marks its default upstream for the specified tool as unavailable. Sellers MUST include the same name in STALE_RESPONSE error.details.upstream.name on the affected response."
        ),
    ] = None
    cache_age_seconds: Annotated[
        SchemaInt | None,
        Field(
            description='Deterministic age of the stale cache entry used by force_upstream_unavailable. When supplied, the seller MUST emit this exact value in the matching STALE_RESPONSE error.details.cache_age_seconds on the next affected response. This lets the conformance runner bind the advisory code and its required detail fields to the same errors[] entry without assuming array order.',
            ge=0,
        ),
    ] = None
    result: Annotated[
        task_completion_data.ComplianceTaskCompletionData | None,
        Field(
            description="Deterministic result payload. force_get_creative_features_arm uses it when arm is completed and returns it on the next matching operation call. force_task_completion records it against an existing task and supports the bounded get_products, get_signals, create_media_buy, and get_creative_features completion union; polling and production SDKs resolve all task results through the originating task's manifest response mapping instead of embedding a global result union. The seller MUST preserve caller-supplied fields. Sellers MUST emit INVALID_PARAMS when the payload does not match the required response branch and MAY reject payloads exceeding 256 KB."
        ),
    ] = None

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 set additionalProperties: true override this with extra='allow' in their own model_config.

Set ADCP_STRICT_VALIDATION=1 in the environment ("1", "true", "yes", "on" are accepted) to flip the default to extra='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 adcp runs — mutating os.environ["ADCP_STRICT_VALIDATION"] after the first adcp import 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_config on 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.

self is explicitly positional-only to allow self as a field name.

Ancestors

Class variables

var account_id : str | None
var advance_to : AdvanceTo | None
var arm : Arm | None
var cache_age_seconds : int | None
var catalog_generation : str | None
var catalog_id : str | None
var clicks : int | None
var commissionable_value : float | None
var conversion_value : float | None
var conversions : int | None
var creative_id : str | None
var delivery_date : datetime.date | None
var dooh_metrics : DoohMetrics | None
var evaluation_id : str | None
var fixture : dict[str, typing.Any] | None
var format_id : str | None
var frequency : float | None
var impressions : int | None
var item_id : str | None
var media_buy_id : str | None
var message : str | None
var metrics : list[Metric] | None
var model_config
var not_yet_measurable_vendor_metrics : list[NotYetMeasurableVendorMetric] | None
var not_yet_measurable_vendor_metrics_by_package : dict[str, list[NotYetMeasurableVendorMetricsByPackageItem]] | None
var operation : Operation | None
var plan_id : str | None
var plays : int | None
var pricing_option_id : str | None
var product_id : str | None
var proposal_id : str | None
var purge_kind : PurgeKind | None
var reach : float | None
var reach_unit : ReachUnit | None
var reach_window : ReachWindow | None
var reason : str | None
var reason_code : CreativeEventReasonCode | None
var reason_detail : str | None
var received_reporting_revision_id : str | None
var rejection_reason : str | None
var reported_spend : ReportedSpend | None
var result : GetProductsResponse | GetSignalsResponse | CreateMediaBuyResponse1 | GetCreativeFeaturesComplianceCompletion | None
var rights_id : str | None
var session_id : str | None
var spend_percentage : float | None
var status : str | None
var suggestions : list[Suggestion] | None
var target_health : TargetHealth | None
var target_time : pydantic.types.AwareDatetime | None
var task_id : str | None
var termination_reason : str | None
var tool : str | None
var upstream_name : str | None
var vendor : BrandReference | None
var vendor_metric_values : list[VendorMetricValue] | None
var vendor_metric_values_by_package : dict[str, list[VendorMetricValue]] | None
var viewability : Viewability | None

Inherited members

class PurgeKind (*args, **kwds)
Expand source code
class PurgeKind(StrEnum):
    soft = 'soft'
    hard = 'hard'

Enum where members are also (and must be) strings

Ancestors

  • enum.StrEnum
  • builtins.str
  • enum.ReprEnum
  • enum.Enum

Class variables

var hard
var soft
class ReachWindow (**data: Any)
Expand source code
class ReachWindow(AdCPBaseModel):
    model_config = ConfigDict(
        extra='allow',
    )
    kind: Annotated[
        Kind,
        Field(
            description='Window kind. `cumulative` — no period field required. `period` and `rolling` — period field REQUIRED.'
        ),
    ]
    period: Annotated[
        duration.Duration | None,
        Field(
            description="Duration of the measurement window. REQUIRED when kind is `period` or `rolling`. Matches the `period` field in delivery-metrics.json's reach_window block."
        ),
    ] = None

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 set additionalProperties: true override this with extra='allow' in their own model_config.

Set ADCP_STRICT_VALIDATION=1 in the environment ("1", "true", "yes", "on" are accepted) to flip the default to extra='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 adcp runs — mutating os.environ["ADCP_STRICT_VALIDATION"] after the first adcp import 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_config on 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.

self is explicitly positional-only to allow self as a field name.

Ancestors

Class variables

var kind : Kind
var model_config
var period : Duration | None

Inherited members

class ReportedSpend (**data: Any)
Expand source code
class ReportedSpend(AdCPBaseModel):
    amount: Annotated[StrictFloat, Field(ge=0.0)]
    currency: Annotated[str, Field(pattern='^[A-Z]{3}$')]

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 set additionalProperties: true override this with extra='allow' in their own model_config.

Set ADCP_STRICT_VALIDATION=1 in the environment ("1", "true", "yes", "on" are accepted) to flip the default to extra='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 adcp runs — mutating os.environ["ADCP_STRICT_VALIDATION"] after the first adcp import 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_config on 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.

self is explicitly positional-only to allow self as a field name.

Ancestors

Class variables

var amount : float
var currency : str
var model_config

Inherited members

class Suggestion (value: Any = <object object>, *, root: Any = <object object>)
Expand source code
class Suggestion(ScalarStr):
    __slots__ = ()
    _constraints = {'max_length': 1000, 'min_length': 1}

A str generated from a JSON Schema string root.

Ancestors

  • adcp.types._scalar.ScalarStr
  • adcp.types._scalar._ScalarRoot
  • builtins.str
class TargetHealth (*args, **kwds)
Expand source code
class TargetHealth(StrEnum):
    delayed = 'delayed'
    action_required = 'action_required'

Enum where members are also (and must be) strings

Ancestors

  • enum.StrEnum
  • builtins.str
  • enum.ReprEnum
  • enum.Enum

Class variables

var action_required
var delayed