Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,16 @@ instructions and before/after examples.
(e.g., `CreateMediaBuySuccessResponse`) instead of numbered classes. Raw
`Assets*` imports are unsupported — they are code-generation artifacts and
will shift again.
* **Asset-content types renamed `<Type>Asset` → `<Type>Content`** (issue
#221). The payload-describing types (`AudioAsset`, `CssAsset`, `HtmlAsset`,
`ImageAsset`, `JavascriptAsset`, `TextAsset`, `UrlAsset`, `VideoAsset`,
`WebhookAsset`) are renamed to `AudioContent`, `CssContent`, `HtmlContent`,
`ImageContent`, `JavascriptContent`, `TextContent`, `UrlContent`,
`VideoContent`, `WebhookContent`. This disambiguates payload types from
the slot-describing `<Type>FormatAsset` family (`VideoContent` describes
what a creative delivers; `VideoFormatAsset` is a slot inside a format
definition). The old names are no longer exported from `adcp.types`. See
`MIGRATION_v3_to_v4.md` for a search-and-replace.

### Non-breaking

Expand Down
75 changes: 71 additions & 4 deletions MIGRATION_v3_to_v4.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ before/after code.
## Audit your exposure first

```bash
grep -rnE "BrandManifest|FormatCategory|DeliverTo|PromotedProducts|PromotedOfferings|PackageStatus|from adcp import Pricing|\.brand_manifest|adcp\.types\.generated_poc" src/
grep -rnE "BrandManifest|FormatCategory|DeliverTo|PromotedProducts|PromotedOfferings|PackageStatus|from adcp import Pricing|\.brand_manifest|adcp\.types\.generated_poc|(Audio|Css|Html|Image|Javascript|Text|Url|Video|Webhook)Asset\b" src/
```

Each match is either an import that will now raise `ImportError`, an attribute
Expand Down Expand Up @@ -203,15 +203,82 @@ renumbered to `Assets57`/`Assets149`. The stable names are:
| `Assets95…Assets106` | `ImageFormatGroupAsset` etc.| (same type inside a group) |

The `Format` prefix disambiguates these *format-slot* types from the
separate *asset-content* types (`VideoAsset`, `HtmlAsset`, `ImageAsset`,
etc. in `adcp.types`), which describe the actual asset payload (codec,
duration, file URL) delivered by creative sync — a distinct concept.
separate *asset-content* types (`VideoContent`, `HtmlContent`, `ImageContent`,
etc. in `adcp.types` — renamed from `<Type>Asset` in 4.0, see below),
which describe the actual asset payload (codec, duration, file URL)
delivered by creative sync — a distinct concept.

`tests/test_asset_aliases_stable.py` pins each alias to its expected
`asset_type` discriminator default. When upstream renumbers, that test
fails and points at the specific alias that drifted — fix the numbered
import in `src/adcp/types/aliases.py`, not your call sites.

### Asset-content types: `<Type>Asset` → `<Type>Content`

The payload-describing types — the classes you construct to attach an
actual image, video, or HTML payload to a `CreativeManifest` — are
renamed. The 3.x names collided with the `<Type>FormatAsset` slot types
described above; autocomplete showed two entries whose only difference
was a `Format` infix, and agent authors picked the wrong one.

| 3.x name | 4.0 name |
|---------------------|-----------------------|
| `AudioAsset` | `AudioContent` |
| `CssAsset` | `CssContent` |
| `HtmlAsset` | `HtmlContent` |
| `ImageAsset` | `ImageContent` |
| `JavascriptAsset` | `JavascriptContent` |
| `TextAsset` | `TextContent` |
| `UrlAsset` | `UrlContent` |
| `VideoAsset` | `VideoContent` |
| `WebhookAsset` | `WebhookContent` |

**Before (v3.x):**
```python
from adcp.types import ImageAsset, UrlAsset

assets = {
"primary_asset": ImageAsset(url="https://example.com/img.jpg",
width=300, height=250),
"clickthrough_url": UrlAsset(url="https://example.com"),
}
```

**After (v4.0):**
```python
from adcp.types import ImageContent, UrlContent

assets = {
"primary_asset": ImageContent(url="https://example.com/img.jpg",
width=300, height=250),
"clickthrough_url": UrlContent(url="https://example.com"),
}
```

Mechanical search-and-replace, nine names:

```bash
perl -pi -e '
s/\b(Audio|Css|Html|Image|Javascript|Text|Url|Video|Webhook)Asset\b/$1Content/g
' $(git ls-files "*.py")
```

The regex intentionally *omits* `VastAsset`, `DaastAsset`, `BriefAsset`,
`CatalogAsset`, and `MarkdownAsset` — none were on the public surface in
3.x, so no rename applies. If you have user-defined classes whose names
happen to end in one of the nine suffixes (e.g. `MyImageAsset`), the
word-boundary regex will match them too; review the diff before
committing.

Field shapes are unchanged — the class identity is the same Pydantic
model underneath. For VAST/DAAST, continue using the delivery-type
variants (`UrlVastAsset` / `InlineVastAsset` / `UrlDaastAsset` /
`InlineDaastAsset`), which are unchanged.

The `<Type>FormatAsset` slot types (unchanged) remain the way to inspect
a format *definition* — `VideoFormatAsset` is a slot declaration inside
a `Format`; `VideoContent` is the payload you deliver into that slot.

### Deep-submodule `format_category` shim

Some older import sites reach into the raw generated path:
Expand Down
57 changes: 38 additions & 19 deletions src/adcp/types/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,6 @@
AssignedPackage,
Assignments,
AudienceSource,
AudioAsset,
Authentication,
AuthenticationScheme,
AuthorizedAgents,
Expand Down Expand Up @@ -131,7 +130,6 @@
CreativePolicy,
CreativeStatus,
CreativeVariant,
CssAsset,
DaastTrackingEvent,
DaastVersion,
DailyBreakdownItem,
Expand Down Expand Up @@ -210,14 +208,11 @@
GetSignalsRequest,
GetSignalsResponse,
Gtin,
HtmlAsset,
HttpMethod,
Identifier,
IdentityMatchRequest,
IdentityMatchResponse,
ImageAsset,
Input,
JavascriptAsset,
JavascriptModuleType,
KellerType,
LandingPageRequirement,
Expand Down Expand Up @@ -350,7 +345,6 @@
Tags,
TargetingOverlay,
TaskType,
TextAsset,
TimeBasedPricingOption,
TimeUnit,
TmpError,
Expand All @@ -367,7 +361,6 @@
UpdatePropertyListResponse,
UpdateRightsRequest,
UpdateRightsResponse,
UrlAsset,
UrlAssetType,
ValidateContentDeliveryRequest,
ValidateContentDeliveryResponse,
Expand All @@ -376,16 +369,41 @@
VastVersion,
VcpmPricingOption,
VenueBreakdownItem,
VideoAsset,
ViewThreshold,
WcagLevel,
WebhookAsset,
WebhookResponseType,
)
from adcp.types._generated import (
AudioAsset as AudioContent,
)
from adcp.types._generated import (
CssAsset as CssContent,
)
from adcp.types._generated import (
HtmlAsset as HtmlContent,
)
from adcp.types._generated import (
ImageAsset as ImageContent,
)
from adcp.types._generated import (
JavascriptAsset as JavascriptContent,
)
from adcp.types._generated import (
Offer as TmpOffer,
)
from adcp.types._generated import TaskStatus as GeneratedTaskStatus
from adcp.types._generated import (
TextAsset as TextContent,
)
from adcp.types._generated import (
UrlAsset as UrlContent,
)
from adcp.types._generated import (
VideoAsset as VideoContent,
)
from adcp.types._generated import (
WebhookAsset as WebhookContent,
)
from adcp.types._generated import _ErrorFromError as Error
from adcp.types._generated import _PackageFromPackage as Package

Expand Down Expand Up @@ -1014,16 +1032,17 @@ def __init__(self, *args: object, **kwargs: object) -> None:
"ReportingWebhook",
"AuthenticationScheme",
"Security",
# Assets
"AudioAsset",
"CssAsset",
"HtmlAsset",
"ImageAsset",
"JavascriptAsset",
"TextAsset",
"UrlAsset",
"VideoAsset",
"WebhookAsset",
# Asset-content types (payload describing types — distinct from
# the `<Type>FormatAsset` slot types in aliases.py)
"AudioContent",
"CssContent",
"HtmlContent",
"ImageContent",
"JavascriptContent",
"TextContent",
"UrlContent",
"VideoContent",
"WebhookContent",
# Core types
"AgentConfig",
"Member",
Expand Down
36 changes: 19 additions & 17 deletions src/adcp/types/aliases.py
Original file line number Diff line number Diff line change
Expand Up @@ -1185,10 +1185,10 @@ def get_pricing(options: list[PricingOption]) -> None:
#
# 1. Individual asset slots (``item_type='individual'``) — top-level slots in
# a creative format. Aliased as ``<Type>FormatAsset``. The ``Format``
# prefix disambiguates from the separate asset-content types (``VideoAsset``,
# ``HtmlAsset``, etc. in ``adcp.types``) which describe the actual asset
# payload (codec, duration, file URL) delivered by creative sync — a
# distinct concept.
# prefix disambiguates from the separate asset-content types
# (``VideoContent``, ``HtmlContent``, etc. in ``adcp.types``) which
# describe the actual asset payload (codec, duration, file URL)
# delivered by creative sync — a distinct concept.
# 2. Group asset variants — the same asset types nested inside a
# ``RepeatableAssetGroup`` (``Assets94``). Aliased as ``<Type>FormatGroupAsset``.
#
Expand Down Expand Up @@ -1282,31 +1282,31 @@ def get_pricing(options: list[PricingOption]) -> None:
ImageFormatAsset = _ImageFormatAssetInternal
"""Image asset slot in a creative format (asset_type='image').

Distinct from ``ImageAsset`` in ``adcp.types`` (the asset-content type
Distinct from ``ImageContent`` in ``adcp.types`` (the asset-content type
describing an actual image payload — dimensions, file URL, etc.). This
alias names the slot shape used inside a format definition.
"""

VideoFormatAsset = _VideoFormatAssetInternal
"""Video asset slot in a creative format (asset_type='video').

Distinct from ``VideoAsset`` in ``adcp.types`` (the asset-content type
Distinct from ``VideoContent`` in ``adcp.types`` (the asset-content type
describing an actual video payload — codec, duration, file URL). This
alias names the slot shape used inside a format definition.
"""

AudioFormatAsset = _AudioFormatAssetInternal
"""Audio asset slot in a creative format (asset_type='audio').

Distinct from ``AudioAsset`` in ``adcp.types`` (the asset-content type
Distinct from ``AudioContent`` in ``adcp.types`` (the asset-content type
describing an actual audio payload). This alias names the slot shape
used inside a format definition.
"""

TextFormatAsset = _TextFormatAssetInternal
"""Text asset slot in a creative format (asset_type='text').

Distinct from ``TextAsset`` in ``adcp.types``. This alias names the slot
Distinct from ``TextContent`` in ``adcp.types``. This alias names the slot
shape used inside a format definition.
"""

Expand All @@ -1320,22 +1320,22 @@ def get_pricing(options: list[PricingOption]) -> None:
HtmlFormatAsset = _HtmlFormatAssetInternal
"""HTML asset slot in a creative format (asset_type='html').

Distinct from ``HtmlAsset`` in ``adcp.types`` (the asset-content type
Distinct from ``HtmlContent`` in ``adcp.types`` (the asset-content type
describing actual HTML payload). This alias names the slot shape used
inside a format definition.
"""

CssFormatAsset = _CssFormatAssetInternal
"""CSS asset slot in a creative format (asset_type='css').

Distinct from ``CssAsset`` in ``adcp.types``. This alias names the slot
Distinct from ``CssContent`` in ``adcp.types``. This alias names the slot
shape used inside a format definition.
"""

JavascriptFormatAsset = _JavascriptFormatAssetInternal
"""JavaScript asset slot in a creative format (asset_type='javascript').

Distinct from ``JavascriptAsset`` in ``adcp.types``. This alias names
Distinct from ``JavascriptContent`` in ``adcp.types``. This alias names
the slot shape used inside a format definition.
"""

Expand All @@ -1357,29 +1357,31 @@ def get_pricing(options: list[PricingOption]) -> None:
UrlFormatAsset = _UrlFormatAssetInternal
"""URL asset slot in a creative format (asset_type='url').

Distinct from ``UrlAsset`` in ``adcp.types``. This alias names the slot
Distinct from ``UrlContent`` in ``adcp.types``. This alias names the slot
shape used inside a format definition.
"""

WebhookFormatAsset = _WebhookFormatAssetInternal
"""Webhook asset slot in a creative format (asset_type='webhook').

Distinct from ``WebhookAsset`` in ``adcp.types``. This alias names the
Distinct from ``WebhookContent`` in ``adcp.types``. This alias names the
slot shape used inside a format definition.
"""

BriefFormatAsset = _BriefFormatAssetInternal
"""Brief asset slot in a creative format (asset_type='brief').

Distinct from ``BriefAsset`` in ``adcp.types``. This alias names the
slot shape used inside a format definition.
Distinct from the brief asset-content type (not currently exported on
the public surface). This alias names the slot shape used inside a
format definition.
"""

CatalogFormatAsset = _CatalogFormatAssetInternal
"""Catalog asset slot in a creative format (asset_type='catalog').

Distinct from ``CatalogAsset`` in ``adcp.types``. This alias names the
slot shape used inside a format definition.
Distinct from the catalog asset-content type (not currently exported on
the public surface). This alias names the slot shape used inside a
format definition.
"""

RepeatableAssetGroup = _RepeatableAssetGroupInternal
Expand Down
Loading
Loading