Skip to content

types: make version-scoped models typed and composable #1046

Description

@bokelley

Problem

SDK 8.0.0b4 now provides version-scoped validation models under
adcp.types.v30, v31, and v32, which fixes the wire-validation and MCP
schema-selection half of #1036. The Python model surface remains opaque,
however: each versioned request/response is a RootModel[dict[str, Any]]
rather than a typed, composable Pydantic model.

from adcp.types import ListCreativesRequest as CurrentListCreativesRequest
from adcp.types.v31 import ListCreativesRequest as V31ListCreativesRequest

assert "assignment_projection" in CurrentListCreativesRequest.model_fields
assert set(V31ListCreativesRequest.model_fields) == {"root"}
assert V31ListCreativesRequest.model_fields["root"].annotation == dict[str, Any]

This means a 3.1 adopter can validate a completed dictionary, but cannot use
the version-scoped model as its normal application type:

  • no typed constructor or IDE/mypy support for fields;
  • no request.account, request.filters, etc.;
  • no typed nested values;
  • no supported inheritance point for adopter-only fields or validators;
  • no version-scoped nested models to use in application schemas.

The last point matters for seller frameworks. Our schemas extend SDK models
and add internal fields with exclude=True. With b4, the only usable parent is
the unversioned (currently 3.2) generated model, so a 3.1 server still inherits
3.2-only fields and requiredness. We then have to patch 3.1 semantics locally
(for example, reject assignment_projection / assignment_limit and restore
required package budgets) even though the SDK has the correct 3.1 bundle.

Requested public surface

Please make version-scoped types usable as normal typed Pydantic application
models, not validation envelopes. Any implementation shape is fine if it
provides these properties:

  1. v31.ListCreativesRequest exposes its 3.1 fields with precise annotations
    and requiredness.
  2. Nested types needed to compose or extend a versioned request/response have
    a stable, collision-safe public import path.
  3. Adopters can subclass a versioned type and add excluded internal fields or
    validators without converting to/from an untyped root dictionary.
  4. Runtime validation continues to use the pinned schema bundle.
  5. Tests cover the known 3.1/3.2 deltas: creative assignment fields and
    PackageRequest.budget requiredness.

If fully generated per-version Pydantic trees are intentionally out of scope,
please expose another supported typed composition/inheritance API and document
that adcp.types.v3x is a boundary validator only.

Relationship to #1036

This is a follow-up, not a request to undo its work. Version-pinned dispatch
and MCP schemas now behave correctly. The remaining gap is Python type safety
and composability for adopters implementing a version-pinned server.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions