adcp 2.12.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (176) hide show
  1. adcp/__init__.py +364 -0
  2. adcp/__main__.py +440 -0
  3. adcp/adagents.py +642 -0
  4. adcp/client.py +1057 -0
  5. adcp/config.py +82 -0
  6. adcp/exceptions.py +185 -0
  7. adcp/protocols/__init__.py +9 -0
  8. adcp/protocols/a2a.py +484 -0
  9. adcp/protocols/base.py +190 -0
  10. adcp/protocols/mcp.py +440 -0
  11. adcp/py.typed +0 -0
  12. adcp/simple.py +451 -0
  13. adcp/testing/__init__.py +53 -0
  14. adcp/testing/test_helpers.py +311 -0
  15. adcp/types/__init__.py +561 -0
  16. adcp/types/_generated.py +237 -0
  17. adcp/types/aliases.py +748 -0
  18. adcp/types/base.py +26 -0
  19. adcp/types/core.py +174 -0
  20. adcp/types/generated_poc/__init__.py +3 -0
  21. adcp/types/generated_poc/adagents.py +411 -0
  22. adcp/types/generated_poc/core/__init__.py +3 -0
  23. adcp/types/generated_poc/core/activation_key.py +30 -0
  24. adcp/types/generated_poc/core/assets/__init__.py +3 -0
  25. adcp/types/generated_poc/core/assets/audio_asset.py +26 -0
  26. adcp/types/generated_poc/core/assets/css_asset.py +20 -0
  27. adcp/types/generated_poc/core/assets/daast_asset.py +61 -0
  28. adcp/types/generated_poc/core/assets/html_asset.py +18 -0
  29. adcp/types/generated_poc/core/assets/image_asset.py +19 -0
  30. adcp/types/generated_poc/core/assets/javascript_asset.py +23 -0
  31. adcp/types/generated_poc/core/assets/text_asset.py +20 -0
  32. adcp/types/generated_poc/core/assets/url_asset.py +28 -0
  33. adcp/types/generated_poc/core/assets/vast_asset.py +63 -0
  34. adcp/types/generated_poc/core/assets/video_asset.py +24 -0
  35. adcp/types/generated_poc/core/assets/webhook_asset.py +53 -0
  36. adcp/types/generated_poc/core/brand_manifest.py +201 -0
  37. adcp/types/generated_poc/core/context.py +15 -0
  38. adcp/types/generated_poc/core/creative_asset.py +102 -0
  39. adcp/types/generated_poc/core/creative_assignment.py +27 -0
  40. adcp/types/generated_poc/core/creative_filters.py +86 -0
  41. adcp/types/generated_poc/core/creative_manifest.py +68 -0
  42. adcp/types/generated_poc/core/creative_policy.py +28 -0
  43. adcp/types/generated_poc/core/delivery_metrics.py +111 -0
  44. adcp/types/generated_poc/core/deployment.py +78 -0
  45. adcp/types/generated_poc/core/destination.py +43 -0
  46. adcp/types/generated_poc/core/dimensions.py +18 -0
  47. adcp/types/generated_poc/core/error.py +29 -0
  48. adcp/types/generated_poc/core/ext.py +15 -0
  49. adcp/types/generated_poc/core/format.py +260 -0
  50. adcp/types/generated_poc/core/format_id.py +50 -0
  51. adcp/types/generated_poc/core/frequency_cap.py +19 -0
  52. adcp/types/generated_poc/core/measurement.py +40 -0
  53. adcp/types/generated_poc/core/media_buy.py +40 -0
  54. adcp/types/generated_poc/core/package.py +68 -0
  55. adcp/types/generated_poc/core/performance_feedback.py +78 -0
  56. adcp/types/generated_poc/core/placement.py +37 -0
  57. adcp/types/generated_poc/core/product.py +164 -0
  58. adcp/types/generated_poc/core/product_filters.py +97 -0
  59. adcp/types/generated_poc/core/promoted_offerings.py +102 -0
  60. adcp/types/generated_poc/core/promoted_products.py +38 -0
  61. adcp/types/generated_poc/core/property.py +64 -0
  62. adcp/types/generated_poc/core/property_id.py +21 -0
  63. adcp/types/generated_poc/core/property_tag.py +21 -0
  64. adcp/types/generated_poc/core/protocol_envelope.py +61 -0
  65. adcp/types/generated_poc/core/publisher_property_selector.py +75 -0
  66. adcp/types/generated_poc/core/push_notification_config.py +51 -0
  67. adcp/types/generated_poc/core/reporting_capabilities.py +51 -0
  68. adcp/types/generated_poc/core/response.py +24 -0
  69. adcp/types/generated_poc/core/signal_filters.py +29 -0
  70. adcp/types/generated_poc/core/sub_asset.py +55 -0
  71. adcp/types/generated_poc/core/targeting.py +53 -0
  72. adcp/types/generated_poc/core/webhook_payload.py +96 -0
  73. adcp/types/generated_poc/creative/__init__.py +3 -0
  74. adcp/types/generated_poc/creative/list_creative_formats_request.py +88 -0
  75. adcp/types/generated_poc/creative/list_creative_formats_response.py +55 -0
  76. adcp/types/generated_poc/creative/preview_creative_request.py +153 -0
  77. adcp/types/generated_poc/creative/preview_creative_response.py +169 -0
  78. adcp/types/generated_poc/creative/preview_render.py +152 -0
  79. adcp/types/generated_poc/enums/__init__.py +3 -0
  80. adcp/types/generated_poc/enums/adcp_domain.py +12 -0
  81. adcp/types/generated_poc/enums/asset_content_type.py +23 -0
  82. adcp/types/generated_poc/enums/auth_scheme.py +12 -0
  83. adcp/types/generated_poc/enums/available_metric.py +19 -0
  84. adcp/types/generated_poc/enums/channels.py +19 -0
  85. adcp/types/generated_poc/enums/co_branding_requirement.py +13 -0
  86. adcp/types/generated_poc/enums/creative_action.py +15 -0
  87. adcp/types/generated_poc/enums/creative_agent_capability.py +14 -0
  88. adcp/types/generated_poc/enums/creative_sort_field.py +16 -0
  89. adcp/types/generated_poc/enums/creative_status.py +14 -0
  90. adcp/types/generated_poc/enums/daast_tracking_event.py +21 -0
  91. adcp/types/generated_poc/enums/daast_version.py +12 -0
  92. adcp/types/generated_poc/enums/delivery_type.py +12 -0
  93. adcp/types/generated_poc/enums/dimension_unit.py +14 -0
  94. adcp/types/generated_poc/enums/feed_format.py +13 -0
  95. adcp/types/generated_poc/enums/feedback_source.py +14 -0
  96. adcp/types/generated_poc/enums/format_category.py +17 -0
  97. adcp/types/generated_poc/enums/format_id_parameter.py +12 -0
  98. adcp/types/generated_poc/enums/frequency_cap_scope.py +16 -0
  99. adcp/types/generated_poc/enums/history_entry_type.py +12 -0
  100. adcp/types/generated_poc/enums/http_method.py +12 -0
  101. adcp/types/generated_poc/enums/identifier_types.py +29 -0
  102. adcp/types/generated_poc/enums/javascript_module_type.py +13 -0
  103. adcp/types/generated_poc/enums/landing_page_requirement.py +13 -0
  104. adcp/types/generated_poc/enums/markdown_flavor.py +12 -0
  105. adcp/types/generated_poc/enums/media_buy_status.py +14 -0
  106. adcp/types/generated_poc/enums/metric_type.py +18 -0
  107. adcp/types/generated_poc/enums/notification_type.py +14 -0
  108. adcp/types/generated_poc/enums/pacing.py +13 -0
  109. adcp/types/generated_poc/enums/preview_output_format.py +12 -0
  110. adcp/types/generated_poc/enums/pricing_model.py +17 -0
  111. adcp/types/generated_poc/enums/property_type.py +17 -0
  112. adcp/types/generated_poc/enums/publisher_identifier_types.py +15 -0
  113. adcp/types/generated_poc/enums/reporting_frequency.py +13 -0
  114. adcp/types/generated_poc/enums/signal_catalog_type.py +13 -0
  115. adcp/types/generated_poc/enums/sort_direction.py +12 -0
  116. adcp/types/generated_poc/enums/standard_format_ids.py +45 -0
  117. adcp/types/generated_poc/enums/task_status.py +19 -0
  118. adcp/types/generated_poc/enums/task_type.py +15 -0
  119. adcp/types/generated_poc/enums/update_frequency.py +14 -0
  120. adcp/types/generated_poc/enums/url_asset_type.py +13 -0
  121. adcp/types/generated_poc/enums/validation_mode.py +12 -0
  122. adcp/types/generated_poc/enums/vast_tracking_event.py +26 -0
  123. adcp/types/generated_poc/enums/vast_version.py +15 -0
  124. adcp/types/generated_poc/enums/webhook_response_type.py +14 -0
  125. adcp/types/generated_poc/enums/webhook_security_method.py +13 -0
  126. adcp/types/generated_poc/media_buy/__init__.py +3 -0
  127. adcp/types/generated_poc/media_buy/build_creative_request.py +41 -0
  128. adcp/types/generated_poc/media_buy/build_creative_response.py +51 -0
  129. adcp/types/generated_poc/media_buy/create_media_buy_request.py +94 -0
  130. adcp/types/generated_poc/media_buy/create_media_buy_response.py +56 -0
  131. adcp/types/generated_poc/media_buy/get_media_buy_delivery_request.py +47 -0
  132. adcp/types/generated_poc/media_buy/get_media_buy_delivery_response.py +235 -0
  133. adcp/types/generated_poc/media_buy/get_products_request.py +48 -0
  134. adcp/types/generated_poc/media_buy/get_products_response.py +28 -0
  135. adcp/types/generated_poc/media_buy/list_authorized_properties_request.py +38 -0
  136. adcp/types/generated_poc/media_buy/list_authorized_properties_response.py +84 -0
  137. adcp/types/generated_poc/media_buy/list_creative_formats_request.py +74 -0
  138. adcp/types/generated_poc/media_buy/list_creative_formats_response.py +56 -0
  139. adcp/types/generated_poc/media_buy/list_creatives_request.py +76 -0
  140. adcp/types/generated_poc/media_buy/list_creatives_response.py +214 -0
  141. adcp/types/generated_poc/media_buy/package_request.py +63 -0
  142. adcp/types/generated_poc/media_buy/provide_performance_feedback_request.py +125 -0
  143. adcp/types/generated_poc/media_buy/provide_performance_feedback_response.py +53 -0
  144. adcp/types/generated_poc/media_buy/sync_creatives_request.py +63 -0
  145. adcp/types/generated_poc/media_buy/sync_creatives_response.py +105 -0
  146. adcp/types/generated_poc/media_buy/update_media_buy_request.py +195 -0
  147. adcp/types/generated_poc/media_buy/update_media_buy_response.py +55 -0
  148. adcp/types/generated_poc/pricing_options/__init__.py +3 -0
  149. adcp/types/generated_poc/pricing_options/cpc_option.py +43 -0
  150. adcp/types/generated_poc/pricing_options/cpcv_option.py +45 -0
  151. adcp/types/generated_poc/pricing_options/cpm_auction_option.py +58 -0
  152. adcp/types/generated_poc/pricing_options/cpm_fixed_option.py +43 -0
  153. adcp/types/generated_poc/pricing_options/cpp_option.py +64 -0
  154. adcp/types/generated_poc/pricing_options/cpv_option.py +77 -0
  155. adcp/types/generated_poc/pricing_options/flat_rate_option.py +93 -0
  156. adcp/types/generated_poc/pricing_options/vcpm_auction_option.py +61 -0
  157. adcp/types/generated_poc/pricing_options/vcpm_fixed_option.py +47 -0
  158. adcp/types/generated_poc/protocols/__init__.py +3 -0
  159. adcp/types/generated_poc/protocols/adcp_extension.py +37 -0
  160. adcp/types/generated_poc/signals/__init__.py +3 -0
  161. adcp/types/generated_poc/signals/activate_signal_request.py +32 -0
  162. adcp/types/generated_poc/signals/activate_signal_response.py +51 -0
  163. adcp/types/generated_poc/signals/get_signals_request.py +53 -0
  164. adcp/types/generated_poc/signals/get_signals_response.py +59 -0
  165. adcp/utils/__init__.py +7 -0
  166. adcp/utils/operation_id.py +15 -0
  167. adcp/utils/preview_cache.py +491 -0
  168. adcp/utils/response_parser.py +171 -0
  169. adcp/validation.py +172 -0
  170. adcp-2.12.0.data/data/ADCP_VERSION +1 -0
  171. adcp-2.12.0.dist-info/METADATA +992 -0
  172. adcp-2.12.0.dist-info/RECORD +176 -0
  173. adcp-2.12.0.dist-info/WHEEL +5 -0
  174. adcp-2.12.0.dist-info/entry_points.txt +2 -0
  175. adcp-2.12.0.dist-info/licenses/LICENSE +17 -0
  176. adcp-2.12.0.dist-info/top_level.txt +1 -0
@@ -0,0 +1,20 @@
1
+ # generated by datamodel-codegen:
2
+ # filename: core/assets/css_asset.json
3
+ # timestamp: 2025-11-22T15:23:24+00:00
4
+
5
+ from __future__ import annotations
6
+
7
+ from typing import Annotated
8
+
9
+ from adcp.types.base import AdCPBaseModel
10
+ from pydantic import ConfigDict, Field
11
+
12
+
13
+ class CssAsset(AdCPBaseModel):
14
+ model_config = ConfigDict(
15
+ extra='forbid',
16
+ )
17
+ content: Annotated[str, Field(description='CSS content')]
18
+ media: Annotated[
19
+ str | None, Field(description="CSS media query context (e.g., 'screen', 'print')")
20
+ ] = None
@@ -0,0 +1,61 @@
1
+ # generated by datamodel-codegen:
2
+ # filename: core/assets/daast_asset.json
3
+ # timestamp: 2025-11-22T15:23:24+00:00
4
+
5
+ from __future__ import annotations
6
+
7
+ from typing import Annotated, Literal
8
+
9
+ from adcp.types.base import AdCPBaseModel
10
+ from pydantic import AnyUrl, ConfigDict, Field
11
+
12
+ from ...enums import daast_tracking_event
13
+ from ...enums import daast_version as daast_version_1
14
+
15
+
16
+ class DaastAsset1(AdCPBaseModel):
17
+ model_config = ConfigDict(
18
+ extra='forbid',
19
+ )
20
+ companion_ads: Annotated[
21
+ bool | None, Field(description='Whether companion display ads are included')
22
+ ] = None
23
+ daast_version: Annotated[
24
+ daast_version_1.DaastVersion | None, Field(description='DAAST specification version')
25
+ ] = None
26
+ delivery_type: Annotated[
27
+ Literal['url'],
28
+ Field(description='Discriminator indicating DAAST is delivered via URL endpoint'),
29
+ ]
30
+ duration_ms: Annotated[
31
+ int | None, Field(description='Expected audio duration in milliseconds (if known)', ge=0)
32
+ ] = None
33
+ tracking_events: Annotated[
34
+ list[daast_tracking_event.DaastTrackingEvent] | None,
35
+ Field(description='Tracking events supported by this DAAST tag'),
36
+ ] = None
37
+ url: Annotated[AnyUrl, Field(description='URL endpoint that returns DAAST XML')]
38
+
39
+
40
+ class DaastAsset2(AdCPBaseModel):
41
+ model_config = ConfigDict(
42
+ extra='forbid',
43
+ )
44
+ companion_ads: Annotated[
45
+ bool | None, Field(description='Whether companion display ads are included')
46
+ ] = None
47
+ content: Annotated[str, Field(description='Inline DAAST XML content')]
48
+ daast_version: Annotated[
49
+ daast_version_1.DaastVersion | None, Field(description='DAAST specification version')
50
+ ] = None
51
+ delivery_type: Annotated[
52
+ Literal['inline'],
53
+ Field(description='Discriminator indicating DAAST is delivered as inline XML content'),
54
+ ]
55
+ duration_ms: Annotated[
56
+ int | None, Field(description='Expected audio duration in milliseconds (if known)', ge=0)
57
+ ] = None
58
+ tracking_events: Annotated[
59
+ list[daast_tracking_event.DaastTrackingEvent] | None,
60
+ Field(description='Tracking events supported by this DAAST tag'),
61
+ ] = None
@@ -0,0 +1,18 @@
1
+ # generated by datamodel-codegen:
2
+ # filename: core/assets/html_asset.json
3
+ # timestamp: 2025-11-22T15:23:24+00:00
4
+
5
+ from __future__ import annotations
6
+
7
+ from typing import Annotated
8
+
9
+ from adcp.types.base import AdCPBaseModel
10
+ from pydantic import ConfigDict, Field
11
+
12
+
13
+ class HtmlAsset(AdCPBaseModel):
14
+ model_config = ConfigDict(
15
+ extra='forbid',
16
+ )
17
+ content: Annotated[str, Field(description='HTML content')]
18
+ version: Annotated[str | None, Field(description="HTML version (e.g., 'HTML5')")] = None
@@ -0,0 +1,19 @@
1
+ # generated by datamodel-codegen:
2
+ # filename: core/assets/image_asset.json
3
+ # timestamp: 2025-11-22T19:16:02+00:00
4
+
5
+ from __future__ import annotations
6
+
7
+ from typing import Annotated
8
+
9
+ from pydantic import AnyUrl, Field
10
+
11
+ from ..dimensions import Dimensions
12
+
13
+
14
+ class ImageAsset(Dimensions):
15
+ alt_text: Annotated[str | None, Field(description='Alternative text for accessibility')] = None
16
+ format: Annotated[
17
+ str | None, Field(description='Image file format (jpg, png, gif, webp, etc.)')
18
+ ] = None
19
+ url: Annotated[AnyUrl, Field(description='URL to the image asset')]
@@ -0,0 +1,23 @@
1
+ # generated by datamodel-codegen:
2
+ # filename: core/assets/javascript_asset.json
3
+ # timestamp: 2025-11-22T15:23:24+00:00
4
+
5
+ from __future__ import annotations
6
+
7
+ from typing import Annotated
8
+
9
+ from adcp.types.base import AdCPBaseModel
10
+ from pydantic import ConfigDict, Field
11
+
12
+ from ...enums import javascript_module_type
13
+
14
+
15
+ class JavascriptAsset(AdCPBaseModel):
16
+ model_config = ConfigDict(
17
+ extra='forbid',
18
+ )
19
+ content: Annotated[str, Field(description='JavaScript content')]
20
+ module_type: Annotated[
21
+ javascript_module_type.JavascriptModuleType | None,
22
+ Field(description='JavaScript module type'),
23
+ ] = None
@@ -0,0 +1,20 @@
1
+ # generated by datamodel-codegen:
2
+ # filename: core/assets/text_asset.json
3
+ # timestamp: 2025-11-22T15:23:24+00:00
4
+
5
+ from __future__ import annotations
6
+
7
+ from typing import Annotated
8
+
9
+ from adcp.types.base import AdCPBaseModel
10
+ from pydantic import ConfigDict, Field
11
+
12
+
13
+ class TextAsset(AdCPBaseModel):
14
+ model_config = ConfigDict(
15
+ extra='forbid',
16
+ )
17
+ content: Annotated[str, Field(description='Text content')]
18
+ language: Annotated[str | None, Field(description="Language code (e.g., 'en', 'es', 'fr')")] = (
19
+ None
20
+ )
@@ -0,0 +1,28 @@
1
+ # generated by datamodel-codegen:
2
+ # filename: core/assets/url_asset.json
3
+ # timestamp: 2025-11-22T15:23:24+00:00
4
+
5
+ from __future__ import annotations
6
+
7
+ from typing import Annotated
8
+
9
+ from adcp.types.base import AdCPBaseModel
10
+ from pydantic import AnyUrl, ConfigDict, Field
11
+
12
+ from ...enums import url_asset_type
13
+
14
+
15
+ class UrlAsset(AdCPBaseModel):
16
+ model_config = ConfigDict(
17
+ extra='forbid',
18
+ )
19
+ description: Annotated[
20
+ str | None, Field(description='Description of what this URL points to')
21
+ ] = None
22
+ url: Annotated[AnyUrl, Field(description='URL reference')]
23
+ url_type: Annotated[
24
+ url_asset_type.UrlAssetType | None,
25
+ Field(
26
+ description="Type of URL asset: 'clickthrough' for user click destination (landing page), 'tracker_pixel' for impression/event tracking via HTTP request (fires GET, expects pixel/204 response), 'tracker_script' for measurement SDKs that must load as <script> tag (OMID verification, native event trackers using method:2)"
27
+ ),
28
+ ] = None
@@ -0,0 +1,63 @@
1
+ # generated by datamodel-codegen:
2
+ # filename: core/assets/vast_asset.json
3
+ # timestamp: 2025-11-22T15:23:24+00:00
4
+
5
+ from __future__ import annotations
6
+
7
+ from typing import Annotated, Literal
8
+
9
+ from adcp.types.base import AdCPBaseModel
10
+ from pydantic import AnyUrl, ConfigDict, Field
11
+
12
+ from ...enums import vast_tracking_event
13
+ from ...enums import vast_version as vast_version_1
14
+
15
+
16
+ class VastAsset1(AdCPBaseModel):
17
+ model_config = ConfigDict(
18
+ extra='forbid',
19
+ )
20
+ delivery_type: Annotated[
21
+ Literal['url'],
22
+ Field(description='Discriminator indicating VAST is delivered via URL endpoint'),
23
+ ]
24
+ duration_ms: Annotated[
25
+ int | None, Field(description='Expected video duration in milliseconds (if known)', ge=0)
26
+ ] = None
27
+ tracking_events: Annotated[
28
+ list[vast_tracking_event.VastTrackingEvent] | None,
29
+ Field(description='Tracking events supported by this VAST tag'),
30
+ ] = None
31
+ url: Annotated[AnyUrl, Field(description='URL endpoint that returns VAST XML')]
32
+ vast_version: Annotated[
33
+ vast_version_1.VastVersion | None, Field(description='VAST specification version')
34
+ ] = None
35
+ vpaid_enabled: Annotated[
36
+ bool | None,
37
+ Field(description='Whether VPAID (Video Player-Ad Interface Definition) is supported'),
38
+ ] = None
39
+
40
+
41
+ class VastAsset2(AdCPBaseModel):
42
+ model_config = ConfigDict(
43
+ extra='forbid',
44
+ )
45
+ content: Annotated[str, Field(description='Inline VAST XML content')]
46
+ delivery_type: Annotated[
47
+ Literal['inline'],
48
+ Field(description='Discriminator indicating VAST is delivered as inline XML content'),
49
+ ]
50
+ duration_ms: Annotated[
51
+ int | None, Field(description='Expected video duration in milliseconds (if known)', ge=0)
52
+ ] = None
53
+ tracking_events: Annotated[
54
+ list[vast_tracking_event.VastTrackingEvent] | None,
55
+ Field(description='Tracking events supported by this VAST tag'),
56
+ ] = None
57
+ vast_version: Annotated[
58
+ vast_version_1.VastVersion | None, Field(description='VAST specification version')
59
+ ] = None
60
+ vpaid_enabled: Annotated[
61
+ bool | None,
62
+ Field(description='Whether VPAID (Video Player-Ad Interface Definition) is supported'),
63
+ ] = None
@@ -0,0 +1,24 @@
1
+ # generated by datamodel-codegen:
2
+ # filename: core/assets/video_asset.json
3
+ # timestamp: 2025-11-22T19:16:02+00:00
4
+
5
+ from __future__ import annotations
6
+
7
+ from typing import Annotated
8
+
9
+ from pydantic import AnyUrl, Field
10
+
11
+ from ..dimensions import Dimensions
12
+
13
+
14
+ class VideoAsset(Dimensions):
15
+ bitrate_kbps: Annotated[
16
+ int | None, Field(description='Video bitrate in kilobits per second', ge=1)
17
+ ] = None
18
+ duration_ms: Annotated[
19
+ int | None, Field(description='Video duration in milliseconds', ge=1)
20
+ ] = None
21
+ format: Annotated[str | None, Field(description='Video file format (mp4, webm, mov, etc.)')] = (
22
+ None
23
+ )
24
+ url: Annotated[AnyUrl, Field(description='URL to the video asset')]
@@ -0,0 +1,53 @@
1
+ # generated by datamodel-codegen:
2
+ # filename: core/assets/webhook_asset.json
3
+ # timestamp: 2025-11-22T15:23:24+00:00
4
+
5
+ from __future__ import annotations
6
+
7
+ from typing import Annotated
8
+
9
+ from adcp.types.base import AdCPBaseModel
10
+ from pydantic import AnyUrl, ConfigDict, Field
11
+
12
+ from ...enums import http_method, webhook_response_type, webhook_security_method
13
+
14
+
15
+ class Security(AdCPBaseModel):
16
+ api_key_header: Annotated[
17
+ str | None, Field(description="Header name for API key (e.g., 'X-API-Key')")
18
+ ] = None
19
+ hmac_header: Annotated[
20
+ str | None, Field(description="Header name for HMAC signature (e.g., 'X-Signature')")
21
+ ] = None
22
+ method: Annotated[
23
+ webhook_security_method.WebhookSecurityMethod, Field(description='Authentication method')
24
+ ]
25
+
26
+
27
+ class WebhookAsset(AdCPBaseModel):
28
+ model_config = ConfigDict(
29
+ extra='forbid',
30
+ )
31
+ method: Annotated[http_method.HttpMethod | None, Field(description='HTTP method')] = (
32
+ http_method.HttpMethod.POST
33
+ )
34
+ required_macros: Annotated[
35
+ list[str] | None,
36
+ Field(description='Universal macros that must be provided for webhook to function'),
37
+ ] = None
38
+ response_type: Annotated[
39
+ webhook_response_type.WebhookResponseType,
40
+ Field(description='Expected content type of webhook response'),
41
+ ]
42
+ security: Annotated[Security, Field(description='Security configuration for webhook calls')]
43
+ supported_macros: Annotated[
44
+ list[str] | None,
45
+ Field(
46
+ description='Universal macros that can be passed to webhook (e.g., {DEVICE_TYPE}, {COUNTRY})'
47
+ ),
48
+ ] = None
49
+ timeout_ms: Annotated[
50
+ int | None,
51
+ Field(description='Maximum time to wait for response in milliseconds', ge=10, le=5000),
52
+ ] = 500
53
+ url: Annotated[AnyUrl, Field(description='Webhook URL to call for dynamic content')]
@@ -0,0 +1,201 @@
1
+ # generated by datamodel-codegen:
2
+ # filename: core/brand_manifest.json
3
+ # timestamp: 2025-11-22T15:23:24+00:00
4
+
5
+ from __future__ import annotations
6
+
7
+ from enum import Enum
8
+ from typing import Annotated, Any
9
+
10
+ from adcp.types.base import AdCPBaseModel
11
+ from pydantic import AnyUrl, AwareDatetime, ConfigDict, EmailStr, Field
12
+
13
+ from ..enums import asset_content_type
14
+
15
+
16
+ class Asset(AdCPBaseModel):
17
+ model_config = ConfigDict(
18
+ extra='forbid',
19
+ )
20
+ asset_id: Annotated[str, Field(description='Unique identifier for this asset')]
21
+ asset_type: Annotated[
22
+ asset_content_type.AssetContentType,
23
+ Field(
24
+ description='Type of asset. Note: Brand manifests typically contain basic media assets (image, video, audio, text). Code assets (html, javascript, css) and ad markup (vast, daast) are usually not part of brand asset libraries.'
25
+ ),
26
+ ]
27
+ description: Annotated[str | None, Field(description='Asset description or usage notes')] = None
28
+ duration_seconds: Annotated[
29
+ float | None, Field(description='Video/audio duration in seconds')
30
+ ] = None
31
+ file_size_bytes: Annotated[int | None, Field(description='File size in bytes')] = None
32
+ format: Annotated[str | None, Field(description="File format (e.g., 'jpg', 'mp4', 'mp3')")] = (
33
+ None
34
+ )
35
+ height: Annotated[int | None, Field(description='Image/video height in pixels')] = None
36
+ metadata: Annotated[
37
+ dict[str, Any] | None, Field(description='Additional asset-specific metadata')
38
+ ] = None
39
+ name: Annotated[str | None, Field(description='Human-readable asset name')] = None
40
+ tags: Annotated[
41
+ list[str] | None,
42
+ Field(
43
+ description="Tags for asset discovery (e.g., 'holiday', 'lifestyle', 'product_shot')"
44
+ ),
45
+ ] = None
46
+ url: Annotated[AnyUrl, Field(description='URL to CDN-hosted asset file')]
47
+ width: Annotated[int | None, Field(description='Image/video width in pixels')] = None
48
+
49
+
50
+ class Colors(AdCPBaseModel):
51
+ accent: Annotated[
52
+ str | None, Field(description='Accent color (hex format)', pattern='^#[0-9A-Fa-f]{6}$')
53
+ ] = None
54
+ background: Annotated[
55
+ str | None, Field(description='Background color (hex format)', pattern='^#[0-9A-Fa-f]{6}$')
56
+ ] = None
57
+ primary: Annotated[
58
+ str | None,
59
+ Field(description='Primary brand color (hex format)', pattern='^#[0-9A-Fa-f]{6}$'),
60
+ ] = None
61
+ secondary: Annotated[
62
+ str | None,
63
+ Field(description='Secondary brand color (hex format)', pattern='^#[0-9A-Fa-f]{6}$'),
64
+ ] = None
65
+ text: Annotated[
66
+ str | None, Field(description='Text color (hex format)', pattern='^#[0-9A-Fa-f]{6}$')
67
+ ] = None
68
+
69
+
70
+ class Contact(AdCPBaseModel):
71
+ email: Annotated[EmailStr | None, Field(description='Contact email')] = None
72
+ phone: Annotated[str | None, Field(description='Contact phone number')] = None
73
+
74
+
75
+ class Disclaimer(AdCPBaseModel):
76
+ context: Annotated[
77
+ str | None,
78
+ Field(
79
+ description="When this disclaimer applies (e.g., 'financial_products', 'health_claims', 'all')"
80
+ ),
81
+ ] = None
82
+ required: Annotated[bool | None, Field(description='Whether this disclaimer must appear')] = (
83
+ True
84
+ )
85
+ text: Annotated[str, Field(description='Disclaimer text')]
86
+
87
+
88
+ class Fonts(AdCPBaseModel):
89
+ font_urls: Annotated[
90
+ list[AnyUrl] | None, Field(description='URLs to web font files if using custom fonts')
91
+ ] = None
92
+ primary: Annotated[str | None, Field(description='Primary font family name')] = None
93
+ secondary: Annotated[str | None, Field(description='Secondary font family name')] = None
94
+
95
+
96
+ class Logo(AdCPBaseModel):
97
+ height: Annotated[int | None, Field(description='Logo height in pixels')] = None
98
+ tags: Annotated[
99
+ list[str] | None,
100
+ Field(
101
+ description="Semantic tags describing the logo variant (e.g., 'dark', 'light', 'square', 'horizontal', 'icon')"
102
+ ),
103
+ ] = None
104
+ url: Annotated[AnyUrl, Field(description='URL to the logo asset')]
105
+ width: Annotated[int | None, Field(description='Logo width in pixels')] = None
106
+
107
+
108
+ class Metadata(AdCPBaseModel):
109
+ created_date: Annotated[
110
+ AwareDatetime | None, Field(description='When this brand manifest was created')
111
+ ] = None
112
+ updated_date: Annotated[
113
+ AwareDatetime | None, Field(description='When this brand manifest was last updated')
114
+ ] = None
115
+ version: Annotated[str | None, Field(description='Brand card version number')] = None
116
+
117
+
118
+ class FeedFormat(Enum):
119
+ google_merchant_center = 'google_merchant_center'
120
+ facebook_catalog = 'facebook_catalog'
121
+ custom = 'custom'
122
+
123
+
124
+ class UpdateFrequency(Enum):
125
+ realtime = 'realtime'
126
+ hourly = 'hourly'
127
+ daily = 'daily'
128
+ weekly = 'weekly'
129
+
130
+
131
+ class ProductCatalog(AdCPBaseModel):
132
+ model_config = ConfigDict(
133
+ extra='forbid',
134
+ )
135
+ categories: Annotated[
136
+ list[str] | None,
137
+ Field(description='Product categories available in the catalog (for filtering)'),
138
+ ] = None
139
+ feed_format: Annotated[FeedFormat | None, Field(description='Format of the product feed')] = (
140
+ FeedFormat.google_merchant_center
141
+ )
142
+ feed_url: Annotated[AnyUrl, Field(description='URL to product catalog feed')]
143
+ last_updated: Annotated[
144
+ AwareDatetime | None, Field(description='When the product catalog was last updated')
145
+ ] = None
146
+ update_frequency: Annotated[
147
+ UpdateFrequency | None, Field(description='How frequently the product catalog is updated')
148
+ ] = None
149
+
150
+
151
+ class BrandManifest(AdCPBaseModel):
152
+ model_config = ConfigDict(
153
+ extra='forbid',
154
+ )
155
+ assets: Annotated[
156
+ list[Asset] | None,
157
+ Field(
158
+ description='Brand asset library with explicit assets and tags. Assets are referenced inline with URLs pointing to CDN-hosted files.'
159
+ ),
160
+ ] = None
161
+ colors: Annotated[Colors | None, Field(description='Brand color palette')] = None
162
+ contact: Annotated[Contact | None, Field(description='Brand contact information')] = None
163
+ disclaimers: Annotated[
164
+ list[Disclaimer] | None,
165
+ Field(description='Legal disclaimers or required text that must appear in creatives'),
166
+ ] = None
167
+ fonts: Annotated[Fonts | None, Field(description='Brand typography guidelines')] = None
168
+ industry: Annotated[
169
+ str | None,
170
+ Field(
171
+ description="Industry or vertical (e.g., 'retail', 'automotive', 'finance', 'healthcare')"
172
+ ),
173
+ ] = None
174
+ logos: Annotated[
175
+ list[Logo] | None,
176
+ Field(description='Brand logo assets with semantic tags for different use cases'),
177
+ ] = None
178
+ metadata: Annotated[Metadata | None, Field(description='Additional brand metadata')] = None
179
+ name: Annotated[str, Field(description='Brand or business name')]
180
+ product_catalog: Annotated[
181
+ ProductCatalog | None,
182
+ Field(
183
+ description='Product catalog information for e-commerce advertisers. Enables SKU-level creative generation and product selection.'
184
+ ),
185
+ ] = None
186
+ tagline: Annotated[str | None, Field(description='Brand tagline or slogan')] = None
187
+ target_audience: Annotated[
188
+ str | None, Field(description='Primary target audience description')
189
+ ] = None
190
+ tone: Annotated[
191
+ str | None,
192
+ Field(
193
+ description="Brand voice and messaging tone (e.g., 'professional', 'casual', 'humorous', 'trustworthy', 'innovative')"
194
+ ),
195
+ ] = None
196
+ url: Annotated[
197
+ AnyUrl | None,
198
+ Field(
199
+ description='Primary brand URL for context and asset discovery. Creative agents can infer brand information from this URL.'
200
+ ),
201
+ ] = None
@@ -0,0 +1,15 @@
1
+ # generated by datamodel-codegen:
2
+ # filename: core/context.json
3
+ # timestamp: 2025-11-22T15:23:24+00:00
4
+
5
+ from __future__ import annotations
6
+
7
+ from adcp.types.base import AdCPBaseModel
8
+ from pydantic import ConfigDict
9
+
10
+
11
+ class ContextObject(AdCPBaseModel):
12
+ pass
13
+ model_config = ConfigDict(
14
+ extra='allow',
15
+ )
@@ -0,0 +1,102 @@
1
+ # generated by datamodel-codegen:
2
+ # filename: core/creative_asset.json
3
+ # timestamp: 2025-11-22T19:54:03+00:00
4
+
5
+ from __future__ import annotations
6
+
7
+ from typing import Annotated
8
+
9
+ from adcp.types.base import AdCPBaseModel
10
+ from pydantic import ConfigDict, Field
11
+
12
+ from . import format_id as format_id_1
13
+ from . import promoted_offerings
14
+ from .assets import (
15
+ audio_asset,
16
+ css_asset,
17
+ daast_asset,
18
+ html_asset,
19
+ image_asset,
20
+ javascript_asset,
21
+ text_asset,
22
+ url_asset,
23
+ vast_asset,
24
+ video_asset,
25
+ )
26
+
27
+
28
+ class Input(AdCPBaseModel):
29
+ model_config = ConfigDict(
30
+ extra='forbid',
31
+ )
32
+ context_description: Annotated[
33
+ str | None,
34
+ Field(description='Natural language description of the context for AI-generated content'),
35
+ ] = None
36
+ macros: Annotated[
37
+ dict[str, str] | None, Field(description='Macro values to apply for this preview')
38
+ ] = None
39
+ name: Annotated[str, Field(description='Human-readable name for this preview variant')]
40
+
41
+
42
+ class CreativeAsset(AdCPBaseModel):
43
+ model_config = ConfigDict(
44
+ extra='forbid',
45
+ )
46
+ approved: Annotated[
47
+ bool | None,
48
+ Field(
49
+ description='For generative creatives: set to true to approve and finalize, false to request regeneration with updated assets/message. Omit for non-generative creatives.'
50
+ ),
51
+ ] = None
52
+ assets: Annotated[
53
+ dict[
54
+ str,
55
+ image_asset.ImageAsset
56
+ | video_asset.VideoAsset
57
+ | audio_asset.AudioAsset
58
+ | text_asset.TextAsset
59
+ | html_asset.HtmlAsset
60
+ | css_asset.CssAsset
61
+ | javascript_asset.JavascriptAsset
62
+ | promoted_offerings.PromotedOfferings
63
+ | url_asset.UrlAsset
64
+ | vast_asset.VastAsset1
65
+ | vast_asset.VastAsset2
66
+ | daast_asset.DaastAsset1
67
+ | daast_asset.DaastAsset2,
68
+ ],
69
+ Field(description='Assets required by the format, keyed by asset_role'),
70
+ ]
71
+ creative_id: Annotated[str, Field(description='Unique identifier for the creative')]
72
+ format_id: Annotated[
73
+ format_id_1.FormatId,
74
+ Field(
75
+ description='Format identifier specifying which format this creative conforms to. Can be: (1) concrete format_id referencing a format with fixed dimensions, (2) template format_id referencing a template format, or (3) parameterized format_id with dimensions/duration parameters for template formats.'
76
+ ),
77
+ ]
78
+ inputs: Annotated[
79
+ list[Input] | None,
80
+ Field(
81
+ description='Preview contexts for generative formats - defines what scenarios to generate previews for'
82
+ ),
83
+ ] = None
84
+ name: Annotated[str, Field(description='Human-readable creative name')]
85
+ placement_ids: Annotated[
86
+ list[str] | None,
87
+ Field(
88
+ description="Optional array of placement IDs where this creative should run when uploading via create_media_buy or update_media_buy. References placement_id values from the product's placements array. If omitted, creative runs on all placements. Only used during upload to media buy - not stored in creative library.",
89
+ min_length=1,
90
+ ),
91
+ ] = None
92
+ tags: Annotated[
93
+ list[str] | None, Field(description='User-defined tags for organization and searchability')
94
+ ] = None
95
+ weight: Annotated[
96
+ float | None,
97
+ Field(
98
+ description='Optional delivery weight for creative rotation when uploading via create_media_buy or update_media_buy (0-100). If omitted, platform determines rotation. Only used during upload to media buy - not stored in creative library.',
99
+ ge=0.0,
100
+ le=100.0,
101
+ ),
102
+ ] = None