adcp 2.1.0__tar.gz → 2.2.0__tar.gz

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 (150) hide show
  1. {adcp-2.1.0/src/adcp.egg-info → adcp-2.2.0}/PKG-INFO +1 -1
  2. {adcp-2.1.0 → adcp-2.2.0}/pyproject.toml +1 -1
  3. {adcp-2.1.0 → adcp-2.2.0}/src/adcp/__init__.py +25 -13
  4. adcp-2.2.0/src/adcp/types/__init__.py +48 -0
  5. {adcp-2.1.0 → adcp-2.2.0}/src/adcp/types/aliases.py +51 -11
  6. {adcp-2.1.0 → adcp-2.2.0/src/adcp.egg-info}/PKG-INFO +1 -1
  7. {adcp-2.1.0 → adcp-2.2.0}/tests/test_discriminated_unions.py +260 -0
  8. {adcp-2.1.0 → adcp-2.2.0}/tests/test_type_aliases.py +108 -3
  9. adcp-2.1.0/src/adcp/types/__init__.py +0 -27
  10. {adcp-2.1.0 → adcp-2.2.0}/LICENSE +0 -0
  11. {adcp-2.1.0 → adcp-2.2.0}/README.md +0 -0
  12. {adcp-2.1.0 → adcp-2.2.0}/setup.cfg +0 -0
  13. {adcp-2.1.0 → adcp-2.2.0}/src/adcp/__main__.py +0 -0
  14. {adcp-2.1.0 → adcp-2.2.0}/src/adcp/adagents.py +0 -0
  15. {adcp-2.1.0 → adcp-2.2.0}/src/adcp/client.py +0 -0
  16. {adcp-2.1.0 → adcp-2.2.0}/src/adcp/config.py +0 -0
  17. {adcp-2.1.0 → adcp-2.2.0}/src/adcp/exceptions.py +0 -0
  18. {adcp-2.1.0 → adcp-2.2.0}/src/adcp/protocols/__init__.py +0 -0
  19. {adcp-2.1.0 → adcp-2.2.0}/src/adcp/protocols/a2a.py +0 -0
  20. {adcp-2.1.0 → adcp-2.2.0}/src/adcp/protocols/base.py +0 -0
  21. {adcp-2.1.0 → adcp-2.2.0}/src/adcp/protocols/mcp.py +0 -0
  22. {adcp-2.1.0 → adcp-2.2.0}/src/adcp/py.typed +0 -0
  23. {adcp-2.1.0 → adcp-2.2.0}/src/adcp/simple.py +0 -0
  24. {adcp-2.1.0 → adcp-2.2.0}/src/adcp/testing/__init__.py +0 -0
  25. {adcp-2.1.0 → adcp-2.2.0}/src/adcp/testing/test_helpers.py +0 -0
  26. {adcp-2.1.0 → adcp-2.2.0}/src/adcp/types/base.py +0 -0
  27. {adcp-2.1.0 → adcp-2.2.0}/src/adcp/types/core.py +0 -0
  28. {adcp-2.1.0 → adcp-2.2.0}/src/adcp/types/generated.py +0 -0
  29. {adcp-2.1.0 → adcp-2.2.0}/src/adcp/types/generated_poc/__init__.py +0 -0
  30. {adcp-2.1.0 → adcp-2.2.0}/src/adcp/types/generated_poc/activate_signal_request.py +0 -0
  31. {adcp-2.1.0 → adcp-2.2.0}/src/adcp/types/generated_poc/activate_signal_response.py +0 -0
  32. {adcp-2.1.0 → adcp-2.2.0}/src/adcp/types/generated_poc/activation_key.py +0 -0
  33. {adcp-2.1.0 → adcp-2.2.0}/src/adcp/types/generated_poc/adagents.py +0 -0
  34. {adcp-2.1.0 → adcp-2.2.0}/src/adcp/types/generated_poc/asset_type.py +0 -0
  35. {adcp-2.1.0 → adcp-2.2.0}/src/adcp/types/generated_poc/audio_asset.py +0 -0
  36. {adcp-2.1.0 → adcp-2.2.0}/src/adcp/types/generated_poc/brand_manifest.py +0 -0
  37. {adcp-2.1.0 → adcp-2.2.0}/src/adcp/types/generated_poc/brand_manifest_ref.py +0 -0
  38. {adcp-2.1.0 → adcp-2.2.0}/src/adcp/types/generated_poc/build_creative_request.py +0 -0
  39. {adcp-2.1.0 → adcp-2.2.0}/src/adcp/types/generated_poc/build_creative_response.py +0 -0
  40. {adcp-2.1.0 → adcp-2.2.0}/src/adcp/types/generated_poc/channels.py +0 -0
  41. {adcp-2.1.0 → adcp-2.2.0}/src/adcp/types/generated_poc/cpc_option.py +0 -0
  42. {adcp-2.1.0 → adcp-2.2.0}/src/adcp/types/generated_poc/cpcv_option.py +0 -0
  43. {adcp-2.1.0 → adcp-2.2.0}/src/adcp/types/generated_poc/cpm_auction_option.py +0 -0
  44. {adcp-2.1.0 → adcp-2.2.0}/src/adcp/types/generated_poc/cpm_fixed_option.py +0 -0
  45. {adcp-2.1.0 → adcp-2.2.0}/src/adcp/types/generated_poc/cpp_option.py +0 -0
  46. {adcp-2.1.0 → adcp-2.2.0}/src/adcp/types/generated_poc/cpv_option.py +0 -0
  47. {adcp-2.1.0 → adcp-2.2.0}/src/adcp/types/generated_poc/create_media_buy_request.py +0 -0
  48. {adcp-2.1.0 → adcp-2.2.0}/src/adcp/types/generated_poc/create_media_buy_response.py +0 -0
  49. {adcp-2.1.0 → adcp-2.2.0}/src/adcp/types/generated_poc/creative_asset.py +0 -0
  50. {adcp-2.1.0 → adcp-2.2.0}/src/adcp/types/generated_poc/creative_assignment.py +0 -0
  51. {adcp-2.1.0 → adcp-2.2.0}/src/adcp/types/generated_poc/creative_manifest.py +0 -0
  52. {adcp-2.1.0 → adcp-2.2.0}/src/adcp/types/generated_poc/creative_policy.py +0 -0
  53. {adcp-2.1.0 → adcp-2.2.0}/src/adcp/types/generated_poc/creative_status.py +0 -0
  54. {adcp-2.1.0 → adcp-2.2.0}/src/adcp/types/generated_poc/css_asset.py +0 -0
  55. {adcp-2.1.0 → adcp-2.2.0}/src/adcp/types/generated_poc/daast_asset.py +0 -0
  56. {adcp-2.1.0 → adcp-2.2.0}/src/adcp/types/generated_poc/delivery_metrics.py +0 -0
  57. {adcp-2.1.0 → adcp-2.2.0}/src/adcp/types/generated_poc/delivery_type.py +0 -0
  58. {adcp-2.1.0 → adcp-2.2.0}/src/adcp/types/generated_poc/deployment.py +0 -0
  59. {adcp-2.1.0 → adcp-2.2.0}/src/adcp/types/generated_poc/destination.py +0 -0
  60. {adcp-2.1.0 → adcp-2.2.0}/src/adcp/types/generated_poc/error.py +0 -0
  61. {adcp-2.1.0 → adcp-2.2.0}/src/adcp/types/generated_poc/flat_rate_option.py +0 -0
  62. {adcp-2.1.0 → adcp-2.2.0}/src/adcp/types/generated_poc/format.py +0 -0
  63. {adcp-2.1.0 → adcp-2.2.0}/src/adcp/types/generated_poc/format_id.py +0 -0
  64. {adcp-2.1.0 → adcp-2.2.0}/src/adcp/types/generated_poc/frequency_cap.py +0 -0
  65. {adcp-2.1.0 → adcp-2.2.0}/src/adcp/types/generated_poc/frequency_cap_scope.py +0 -0
  66. {adcp-2.1.0 → adcp-2.2.0}/src/adcp/types/generated_poc/get_media_buy_delivery_request.py +0 -0
  67. {adcp-2.1.0 → adcp-2.2.0}/src/adcp/types/generated_poc/get_media_buy_delivery_response.py +0 -0
  68. {adcp-2.1.0 → adcp-2.2.0}/src/adcp/types/generated_poc/get_products_request.py +0 -0
  69. {adcp-2.1.0 → adcp-2.2.0}/src/adcp/types/generated_poc/get_products_response.py +0 -0
  70. {adcp-2.1.0 → adcp-2.2.0}/src/adcp/types/generated_poc/get_signals_request.py +0 -0
  71. {adcp-2.1.0 → adcp-2.2.0}/src/adcp/types/generated_poc/get_signals_response.py +0 -0
  72. {adcp-2.1.0 → adcp-2.2.0}/src/adcp/types/generated_poc/html_asset.py +0 -0
  73. {adcp-2.1.0 → adcp-2.2.0}/src/adcp/types/generated_poc/identifier_types.py +0 -0
  74. {adcp-2.1.0 → adcp-2.2.0}/src/adcp/types/generated_poc/image_asset.py +0 -0
  75. {adcp-2.1.0 → adcp-2.2.0}/src/adcp/types/generated_poc/index.py +0 -0
  76. {adcp-2.1.0 → adcp-2.2.0}/src/adcp/types/generated_poc/javascript_asset.py +0 -0
  77. {adcp-2.1.0 → adcp-2.2.0}/src/adcp/types/generated_poc/list_authorized_properties_request.py +0 -0
  78. {adcp-2.1.0 → adcp-2.2.0}/src/adcp/types/generated_poc/list_authorized_properties_response.py +0 -0
  79. {adcp-2.1.0 → adcp-2.2.0}/src/adcp/types/generated_poc/list_creative_formats_request.py +0 -0
  80. {adcp-2.1.0 → adcp-2.2.0}/src/adcp/types/generated_poc/list_creative_formats_response.py +0 -0
  81. {adcp-2.1.0 → adcp-2.2.0}/src/adcp/types/generated_poc/list_creatives_request.py +0 -0
  82. {adcp-2.1.0 → adcp-2.2.0}/src/adcp/types/generated_poc/list_creatives_response.py +0 -0
  83. {adcp-2.1.0 → adcp-2.2.0}/src/adcp/types/generated_poc/markdown_asset.py +0 -0
  84. {adcp-2.1.0 → adcp-2.2.0}/src/adcp/types/generated_poc/measurement.py +0 -0
  85. {adcp-2.1.0 → adcp-2.2.0}/src/adcp/types/generated_poc/media_buy.py +0 -0
  86. {adcp-2.1.0 → adcp-2.2.0}/src/adcp/types/generated_poc/media_buy_status.py +0 -0
  87. {adcp-2.1.0 → adcp-2.2.0}/src/adcp/types/generated_poc/pacing.py +0 -0
  88. {adcp-2.1.0 → adcp-2.2.0}/src/adcp/types/generated_poc/package.py +0 -0
  89. {adcp-2.1.0 → adcp-2.2.0}/src/adcp/types/generated_poc/package_request.py +0 -0
  90. {adcp-2.1.0 → adcp-2.2.0}/src/adcp/types/generated_poc/package_status.py +0 -0
  91. {adcp-2.1.0 → adcp-2.2.0}/src/adcp/types/generated_poc/performance_feedback.py +0 -0
  92. {adcp-2.1.0 → adcp-2.2.0}/src/adcp/types/generated_poc/placement.py +0 -0
  93. {adcp-2.1.0 → adcp-2.2.0}/src/adcp/types/generated_poc/preview_creative_request.py +0 -0
  94. {adcp-2.1.0 → adcp-2.2.0}/src/adcp/types/generated_poc/preview_creative_response.py +0 -0
  95. {adcp-2.1.0 → adcp-2.2.0}/src/adcp/types/generated_poc/preview_render.py +0 -0
  96. {adcp-2.1.0 → adcp-2.2.0}/src/adcp/types/generated_poc/pricing_model.py +0 -0
  97. {adcp-2.1.0 → adcp-2.2.0}/src/adcp/types/generated_poc/pricing_option.py +0 -0
  98. {adcp-2.1.0 → adcp-2.2.0}/src/adcp/types/generated_poc/product.py +0 -0
  99. {adcp-2.1.0 → adcp-2.2.0}/src/adcp/types/generated_poc/promoted_offerings.py +0 -0
  100. {adcp-2.1.0 → adcp-2.2.0}/src/adcp/types/generated_poc/promoted_products.py +0 -0
  101. {adcp-2.1.0 → adcp-2.2.0}/src/adcp/types/generated_poc/property.py +0 -0
  102. {adcp-2.1.0 → adcp-2.2.0}/src/adcp/types/generated_poc/protocol_envelope.py +0 -0
  103. {adcp-2.1.0 → adcp-2.2.0}/src/adcp/types/generated_poc/provide_performance_feedback_request.py +0 -0
  104. {adcp-2.1.0 → adcp-2.2.0}/src/adcp/types/generated_poc/provide_performance_feedback_response.py +0 -0
  105. {adcp-2.1.0 → adcp-2.2.0}/src/adcp/types/generated_poc/publisher_identifier_types.py +0 -0
  106. {adcp-2.1.0 → adcp-2.2.0}/src/adcp/types/generated_poc/push_notification_config.py +0 -0
  107. {adcp-2.1.0 → adcp-2.2.0}/src/adcp/types/generated_poc/reporting_capabilities.py +0 -0
  108. {adcp-2.1.0 → adcp-2.2.0}/src/adcp/types/generated_poc/response.py +0 -0
  109. {adcp-2.1.0 → adcp-2.2.0}/src/adcp/types/generated_poc/standard_format_ids.py +0 -0
  110. {adcp-2.1.0 → adcp-2.2.0}/src/adcp/types/generated_poc/start_timing.py +0 -0
  111. {adcp-2.1.0 → adcp-2.2.0}/src/adcp/types/generated_poc/sub_asset.py +0 -0
  112. {adcp-2.1.0 → adcp-2.2.0}/src/adcp/types/generated_poc/sync_creatives_request.py +0 -0
  113. {adcp-2.1.0 → adcp-2.2.0}/src/adcp/types/generated_poc/sync_creatives_response.py +0 -0
  114. {adcp-2.1.0 → adcp-2.2.0}/src/adcp/types/generated_poc/targeting.py +0 -0
  115. {adcp-2.1.0 → adcp-2.2.0}/src/adcp/types/generated_poc/task_status.py +0 -0
  116. {adcp-2.1.0 → adcp-2.2.0}/src/adcp/types/generated_poc/task_type.py +0 -0
  117. {adcp-2.1.0 → adcp-2.2.0}/src/adcp/types/generated_poc/tasks_get_request.py +0 -0
  118. {adcp-2.1.0 → adcp-2.2.0}/src/adcp/types/generated_poc/tasks_get_response.py +0 -0
  119. {adcp-2.1.0 → adcp-2.2.0}/src/adcp/types/generated_poc/tasks_list_request.py +0 -0
  120. {adcp-2.1.0 → adcp-2.2.0}/src/adcp/types/generated_poc/tasks_list_response.py +0 -0
  121. {adcp-2.1.0 → adcp-2.2.0}/src/adcp/types/generated_poc/text_asset.py +0 -0
  122. {adcp-2.1.0 → adcp-2.2.0}/src/adcp/types/generated_poc/update_media_buy_request.py +0 -0
  123. {adcp-2.1.0 → adcp-2.2.0}/src/adcp/types/generated_poc/update_media_buy_response.py +0 -0
  124. {adcp-2.1.0 → adcp-2.2.0}/src/adcp/types/generated_poc/url_asset.py +0 -0
  125. {adcp-2.1.0 → adcp-2.2.0}/src/adcp/types/generated_poc/vast_asset.py +0 -0
  126. {adcp-2.1.0 → adcp-2.2.0}/src/adcp/types/generated_poc/vcpm_auction_option.py +0 -0
  127. {adcp-2.1.0 → adcp-2.2.0}/src/adcp/types/generated_poc/vcpm_fixed_option.py +0 -0
  128. {adcp-2.1.0 → adcp-2.2.0}/src/adcp/types/generated_poc/video_asset.py +0 -0
  129. {adcp-2.1.0 → adcp-2.2.0}/src/adcp/types/generated_poc/webhook_asset.py +0 -0
  130. {adcp-2.1.0 → adcp-2.2.0}/src/adcp/types/generated_poc/webhook_payload.py +0 -0
  131. {adcp-2.1.0 → adcp-2.2.0}/src/adcp/utils/__init__.py +0 -0
  132. {adcp-2.1.0 → adcp-2.2.0}/src/adcp/utils/operation_id.py +0 -0
  133. {adcp-2.1.0 → adcp-2.2.0}/src/adcp/utils/preview_cache.py +0 -0
  134. {adcp-2.1.0 → adcp-2.2.0}/src/adcp/utils/response_parser.py +0 -0
  135. {adcp-2.1.0 → adcp-2.2.0}/src/adcp/validation.py +0 -0
  136. {adcp-2.1.0 → adcp-2.2.0}/src/adcp.egg-info/SOURCES.txt +0 -0
  137. {adcp-2.1.0 → adcp-2.2.0}/src/adcp.egg-info/dependency_links.txt +0 -0
  138. {adcp-2.1.0 → adcp-2.2.0}/src/adcp.egg-info/entry_points.txt +0 -0
  139. {adcp-2.1.0 → adcp-2.2.0}/src/adcp.egg-info/requires.txt +0 -0
  140. {adcp-2.1.0 → adcp-2.2.0}/src/adcp.egg-info/top_level.txt +0 -0
  141. {adcp-2.1.0 → adcp-2.2.0}/tests/test_adagents.py +0 -0
  142. {adcp-2.1.0 → adcp-2.2.0}/tests/test_cli.py +0 -0
  143. {adcp-2.1.0 → adcp-2.2.0}/tests/test_client.py +0 -0
  144. {adcp-2.1.0 → adcp-2.2.0}/tests/test_code_generation.py +0 -0
  145. {adcp-2.1.0 → adcp-2.2.0}/tests/test_format_id_validation.py +0 -0
  146. {adcp-2.1.0 → adcp-2.2.0}/tests/test_helpers.py +0 -0
  147. {adcp-2.1.0 → adcp-2.2.0}/tests/test_preview_html.py +0 -0
  148. {adcp-2.1.0 → adcp-2.2.0}/tests/test_protocols.py +0 -0
  149. {adcp-2.1.0 → adcp-2.2.0}/tests/test_response_parser.py +0 -0
  150. {adcp-2.1.0 → adcp-2.2.0}/tests/test_simple_api.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: adcp
3
- Version: 2.1.0
3
+ Version: 2.2.0
4
4
  Summary: Official Python client for the Ad Context Protocol (AdCP)
5
5
  Author-email: AdCP Community <maintainers@adcontextprotocol.org>
6
6
  License: Apache-2.0
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "adcp"
7
- version = "2.1.0"
7
+ version = "2.2.0"
8
8
  description = "Official Python client for the Ad Context Protocol (AdCP)"
9
9
  authors = [
10
10
  {name = "AdCP Community", email = "maintainers@adcontextprotocol.org"}
@@ -56,27 +56,33 @@ from adcp.types import aliases, generated
56
56
  from adcp.types.aliases import (
57
57
  ActivateSignalErrorResponse,
58
58
  ActivateSignalSuccessResponse,
59
+ BothPreviewRender,
59
60
  BuildCreativeErrorResponse,
60
61
  BuildCreativeSuccessResponse,
61
62
  CreateMediaBuyErrorResponse,
62
63
  CreateMediaBuySuccessResponse,
64
+ HtmlPreviewRender,
65
+ InlineDaastAsset,
66
+ InlineVastAsset,
67
+ MediaSubAsset,
63
68
  PreviewCreativeFormatRequest,
64
69
  PreviewCreativeInteractiveResponse,
65
70
  PreviewCreativeManifestRequest,
66
71
  PreviewCreativeStaticResponse,
67
- PreviewRenderHtml,
68
- PreviewRenderIframe,
69
- PreviewRenderImage,
70
72
  PropertyIdActivationKey,
71
73
  PropertyTagActivationKey,
72
74
  ProvidePerformanceFeedbackErrorResponse,
73
75
  ProvidePerformanceFeedbackSuccessResponse,
74
76
  SyncCreativesErrorResponse,
75
77
  SyncCreativesSuccessResponse,
78
+ TextSubAsset,
76
79
  UpdateMediaBuyErrorResponse,
77
80
  UpdateMediaBuyPackagesRequest,
78
81
  UpdateMediaBuyPropertiesRequest,
79
82
  UpdateMediaBuySuccessResponse,
83
+ UrlDaastAsset,
84
+ UrlPreviewRender,
85
+ UrlVastAsset,
80
86
  )
81
87
  from adcp.types.core import AgentConfig, Protocol, TaskResult, TaskStatus, WebhookMetadata
82
88
 
@@ -128,7 +134,7 @@ from adcp.validation import (
128
134
  validate_publisher_properties_item,
129
135
  )
130
136
 
131
- __version__ = "2.1.0"
137
+ __version__ = "2.2.0"
132
138
 
133
139
  __all__ = [
134
140
  # Client classes
@@ -219,25 +225,31 @@ __all__ = [
219
225
  # Semantic type aliases (for better API ergonomics)
220
226
  "ActivateSignalSuccessResponse",
221
227
  "ActivateSignalErrorResponse",
228
+ "BothPreviewRender",
222
229
  "BuildCreativeSuccessResponse",
223
230
  "BuildCreativeErrorResponse",
224
231
  "CreateMediaBuySuccessResponse",
225
232
  "CreateMediaBuyErrorResponse",
226
- "ProvidePerformanceFeedbackSuccessResponse",
227
- "ProvidePerformanceFeedbackErrorResponse",
228
- "SyncCreativesSuccessResponse",
229
- "SyncCreativesErrorResponse",
230
- "UpdateMediaBuySuccessResponse",
231
- "UpdateMediaBuyErrorResponse",
233
+ "HtmlPreviewRender",
234
+ "InlineDaastAsset",
235
+ "InlineVastAsset",
236
+ "MediaSubAsset",
232
237
  "PreviewCreativeFormatRequest",
233
238
  "PreviewCreativeManifestRequest",
234
239
  "PreviewCreativeStaticResponse",
235
240
  "PreviewCreativeInteractiveResponse",
236
- "PreviewRenderImage",
237
- "PreviewRenderHtml",
238
- "PreviewRenderIframe",
239
241
  "PropertyIdActivationKey",
240
242
  "PropertyTagActivationKey",
243
+ "ProvidePerformanceFeedbackSuccessResponse",
244
+ "ProvidePerformanceFeedbackErrorResponse",
245
+ "SyncCreativesSuccessResponse",
246
+ "SyncCreativesErrorResponse",
247
+ "TextSubAsset",
248
+ "UpdateMediaBuySuccessResponse",
249
+ "UpdateMediaBuyErrorResponse",
241
250
  "UpdateMediaBuyPackagesRequest",
242
251
  "UpdateMediaBuyPropertiesRequest",
252
+ "UrlDaastAsset",
253
+ "UrlPreviewRender",
254
+ "UrlVastAsset",
243
255
  ]
@@ -0,0 +1,48 @@
1
+ from __future__ import annotations
2
+
3
+ """Type definitions for AdCP client."""
4
+
5
+ from adcp.types.aliases import (
6
+ BothPreviewRender,
7
+ HtmlPreviewRender,
8
+ InlineDaastAsset,
9
+ InlineVastAsset,
10
+ MediaSubAsset,
11
+ TextSubAsset,
12
+ UrlDaastAsset,
13
+ UrlPreviewRender,
14
+ UrlVastAsset,
15
+ )
16
+ from adcp.types.base import AdCPBaseModel
17
+ from adcp.types.core import (
18
+ Activity,
19
+ ActivityType,
20
+ AgentConfig,
21
+ DebugInfo,
22
+ Protocol,
23
+ TaskResult,
24
+ TaskStatus,
25
+ WebhookMetadata,
26
+ )
27
+
28
+ __all__ = [
29
+ "AdCPBaseModel",
30
+ "AgentConfig",
31
+ "Protocol",
32
+ "TaskResult",
33
+ "TaskStatus",
34
+ "WebhookMetadata",
35
+ "Activity",
36
+ "ActivityType",
37
+ "DebugInfo",
38
+ # Semantic aliases for discriminated unions
39
+ "BothPreviewRender",
40
+ "HtmlPreviewRender",
41
+ "InlineDaastAsset",
42
+ "InlineVastAsset",
43
+ "MediaSubAsset",
44
+ "TextSubAsset",
45
+ "UrlDaastAsset",
46
+ "UrlPreviewRender",
47
+ "UrlVastAsset",
48
+ ]
@@ -45,6 +45,9 @@ from adcp.types.generated import (
45
45
  # Create media buy responses
46
46
  CreateMediaBuyResponse1,
47
47
  CreateMediaBuyResponse2,
48
+ # DAAST assets
49
+ DaastAsset1,
50
+ DaastAsset2,
48
51
  # Preview creative requests
49
52
  PreviewCreativeRequest1,
50
53
  PreviewCreativeRequest2,
@@ -58,6 +61,9 @@ from adcp.types.generated import (
58
61
  # Performance feedback responses
59
62
  ProvidePerformanceFeedbackResponse1,
60
63
  ProvidePerformanceFeedbackResponse2,
64
+ # SubAssets
65
+ SubAsset1,
66
+ SubAsset2,
61
67
  # Sync creatives responses
62
68
  SyncCreativesResponse1,
63
69
  SyncCreativesResponse2,
@@ -67,6 +73,9 @@ from adcp.types.generated import (
67
73
  # Update media buy responses
68
74
  UpdateMediaBuyResponse1,
69
75
  UpdateMediaBuyResponse2,
76
+ # VAST assets
77
+ VastAsset1,
78
+ VastAsset2,
70
79
  )
71
80
 
72
81
  # ============================================================================
@@ -157,15 +166,40 @@ PreviewCreativeStaticResponse = PreviewCreativeResponse1
157
166
  PreviewCreativeInteractiveResponse = PreviewCreativeResponse2
158
167
  """Preview response with interactive renders (iframe embedding)."""
159
168
 
160
- # Preview Render Variants
161
- PreviewRenderImage = PreviewRender1
162
- """Image-based preview render (PNG/JPEG)."""
169
+ # Preview Render Variants (discriminated by output_format)
170
+ UrlPreviewRender = PreviewRender1
171
+ """Preview render with output_format='url' - provides preview_url for iframe embedding."""
163
172
 
164
- PreviewRenderHtml = PreviewRender2
165
- """HTML-based preview render (static markup)."""
173
+ HtmlPreviewRender = PreviewRender2
174
+ """Preview render with output_format='html' - provides preview_html for direct embedding."""
166
175
 
167
- PreviewRenderIframe = PreviewRender3
168
- """Interactive iframe-based preview render."""
176
+ BothPreviewRender = PreviewRender3
177
+ """Preview render with output_format='both' - provides both preview_url and preview_html."""
178
+
179
+ # ============================================================================
180
+ # ASSET TYPE ALIASES - Delivery & Kind Discriminated Unions
181
+ # ============================================================================
182
+
183
+ # VAST Asset Variants (discriminated by delivery_type)
184
+ UrlVastAsset = VastAsset1
185
+ """VAST asset delivered via URL endpoint - delivery_type='url'."""
186
+
187
+ InlineVastAsset = VastAsset2
188
+ """VAST asset with inline XML content - delivery_type='inline'."""
189
+
190
+ # DAAST Asset Variants (discriminated by delivery_type)
191
+ UrlDaastAsset = DaastAsset1
192
+ """DAAST asset delivered via URL endpoint - delivery_type='url'."""
193
+
194
+ InlineDaastAsset = DaastAsset2
195
+ """DAAST asset with inline XML content - delivery_type='inline'."""
196
+
197
+ # SubAsset Variants (discriminated by asset_kind)
198
+ MediaSubAsset = SubAsset1
199
+ """SubAsset for media content (images, videos) - asset_kind='media', provides content_uri."""
200
+
201
+ TextSubAsset = SubAsset2
202
+ """SubAsset for text content (headlines, body text) - asset_kind='text', provides content."""
169
203
 
170
204
  # ============================================================================
171
205
  # EXPORTS
@@ -178,6 +212,16 @@ __all__ = [
178
212
  # Activation keys
179
213
  "PropertyIdActivationKey",
180
214
  "PropertyTagActivationKey",
215
+ # Asset type aliases
216
+ "BothPreviewRender",
217
+ "HtmlPreviewRender",
218
+ "InlineDaastAsset",
219
+ "InlineVastAsset",
220
+ "MediaSubAsset",
221
+ "TextSubAsset",
222
+ "UrlDaastAsset",
223
+ "UrlPreviewRender",
224
+ "UrlVastAsset",
181
225
  # Build creative responses
182
226
  "BuildCreativeSuccessResponse",
183
227
  "BuildCreativeErrorResponse",
@@ -193,10 +237,6 @@ __all__ = [
193
237
  # Preview creative responses
194
238
  "PreviewCreativeStaticResponse",
195
239
  "PreviewCreativeInteractiveResponse",
196
- # Preview renders
197
- "PreviewRenderImage",
198
- "PreviewRenderHtml",
199
- "PreviewRenderIframe",
200
240
  # Sync creatives responses
201
241
  "SyncCreativesSuccessResponse",
202
242
  "SyncCreativesErrorResponse",
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: adcp
3
- Version: 2.1.0
3
+ Version: 2.2.0
4
4
  Summary: Official Python client for the Ad Context Protocol (AdCP)
5
5
  Author-email: AdCP Community <maintainers@adcontextprotocol.org>
6
6
  License: Apache-2.0
@@ -9,8 +9,17 @@ from pydantic import ValidationError
9
9
  from adcp import (
10
10
  ActivateSignalErrorResponse,
11
11
  ActivateSignalSuccessResponse,
12
+ BothPreviewRender,
12
13
  CreateMediaBuyErrorResponse,
13
14
  CreateMediaBuySuccessResponse,
15
+ HtmlPreviewRender,
16
+ InlineDaastAsset,
17
+ InlineVastAsset,
18
+ MediaSubAsset,
19
+ TextSubAsset,
20
+ UrlDaastAsset,
21
+ UrlPreviewRender,
22
+ UrlVastAsset,
14
23
  )
15
24
 
16
25
  # Keep using generated names for authorization/deployment/destination variants
@@ -448,3 +457,254 @@ class TestProductValidation:
448
457
  assert len(mixed_props) == 2
449
458
  assert mixed_props[0].selection_type == "by_id"
450
459
  assert mixed_props[1].selection_type == "by_tag"
460
+
461
+
462
+ class TestPreviewRenderDiscriminators:
463
+ """Test PreviewRender discriminator field values match semantic aliases."""
464
+
465
+ def test_url_preview_render_has_url_discriminator(self):
466
+ """UrlPreviewRender has output_format='url'."""
467
+ render = UrlPreviewRender(
468
+ render_id="render_1",
469
+ role="primary",
470
+ output_format="url",
471
+ preview_url="https://preview.example.com/creative",
472
+ )
473
+ assert render.output_format == "url"
474
+ assert hasattr(render, "preview_url")
475
+ assert not hasattr(render, "preview_html")
476
+
477
+ def test_html_preview_render_has_html_discriminator(self):
478
+ """HtmlPreviewRender has output_format='html'."""
479
+ render = HtmlPreviewRender(
480
+ render_id="render_1",
481
+ role="primary",
482
+ output_format="html",
483
+ preview_html="<div>Preview HTML</div>",
484
+ )
485
+ assert render.output_format == "html"
486
+ assert hasattr(render, "preview_html")
487
+ assert not hasattr(render, "preview_url")
488
+
489
+ def test_both_preview_render_has_both_discriminator(self):
490
+ """BothPreviewRender has output_format='both'."""
491
+ render = BothPreviewRender(
492
+ render_id="render_1",
493
+ role="primary",
494
+ output_format="both",
495
+ preview_url="https://preview.example.com/creative",
496
+ preview_html="<div>Preview HTML</div>",
497
+ )
498
+ assert render.output_format == "both"
499
+ assert hasattr(render, "preview_url")
500
+ assert hasattr(render, "preview_html")
501
+
502
+ def test_url_preview_render_rejects_wrong_discriminator(self):
503
+ """UrlPreviewRender rejects output_format='html'."""
504
+ with pytest.raises(ValidationError) as exc_info:
505
+ UrlPreviewRender(
506
+ render_id="render_1",
507
+ role="primary",
508
+ output_format="html", # Wrong discriminator value
509
+ preview_url="https://preview.example.com/creative",
510
+ )
511
+ assert "output_format" in str(exc_info.value).lower()
512
+
513
+ def test_html_preview_render_rejects_wrong_discriminator(self):
514
+ """HtmlPreviewRender rejects output_format='url'."""
515
+ with pytest.raises(ValidationError) as exc_info:
516
+ HtmlPreviewRender(
517
+ render_id="render_1",
518
+ role="primary",
519
+ output_format="url", # Wrong discriminator value
520
+ preview_html="<div>Preview HTML</div>",
521
+ )
522
+ assert "output_format" in str(exc_info.value).lower()
523
+
524
+
525
+ class TestVastAssetDiscriminators:
526
+ """Test VastAsset discriminator field values match semantic aliases."""
527
+
528
+ def test_url_vast_asset_has_url_discriminator(self):
529
+ """UrlVastAsset has delivery_type='url'."""
530
+ asset = UrlVastAsset(
531
+ delivery_type="url",
532
+ url="https://vast.example.com/ad.xml",
533
+ )
534
+ assert asset.delivery_type == "url"
535
+ assert hasattr(asset, "url")
536
+ assert not hasattr(asset, "vast_xml")
537
+
538
+ def test_inline_vast_asset_has_inline_discriminator(self):
539
+ """InlineVastAsset has delivery_type='inline'."""
540
+ asset = InlineVastAsset(
541
+ delivery_type="inline",
542
+ content="<VAST>...</VAST>",
543
+ )
544
+ assert asset.delivery_type == "inline"
545
+ assert hasattr(asset, "content")
546
+ assert not hasattr(asset, "url")
547
+
548
+ def test_url_vast_asset_rejects_wrong_discriminator(self):
549
+ """UrlVastAsset rejects delivery_type='inline'."""
550
+ with pytest.raises(ValidationError) as exc_info:
551
+ UrlVastAsset(
552
+ delivery_type="inline", # Wrong discriminator value
553
+ url="https://vast.example.com/ad.xml",
554
+ )
555
+ assert "delivery_type" in str(exc_info.value).lower()
556
+
557
+ def test_inline_vast_asset_rejects_wrong_discriminator(self):
558
+ """InlineVastAsset rejects delivery_type='url'."""
559
+ with pytest.raises(ValidationError) as exc_info:
560
+ InlineVastAsset(
561
+ delivery_type="url", # Wrong discriminator value
562
+ content="<VAST>...</VAST>",
563
+ )
564
+ assert "delivery_type" in str(exc_info.value).lower()
565
+
566
+
567
+ class TestDaastAssetDiscriminators:
568
+ """Test DaastAsset discriminator field values match semantic aliases."""
569
+
570
+ def test_url_daast_asset_has_url_discriminator(self):
571
+ """UrlDaastAsset has delivery_type='url'."""
572
+ asset = UrlDaastAsset(
573
+ delivery_type="url",
574
+ url="https://daast.example.com/ad.xml",
575
+ )
576
+ assert asset.delivery_type == "url"
577
+ assert hasattr(asset, "url")
578
+ assert not hasattr(asset, "content")
579
+
580
+ def test_inline_daast_asset_has_inline_discriminator(self):
581
+ """InlineDaastAsset has delivery_type='inline'."""
582
+ asset = InlineDaastAsset(
583
+ delivery_type="inline",
584
+ content="<DAAST>...</DAAST>",
585
+ )
586
+ assert asset.delivery_type == "inline"
587
+ assert hasattr(asset, "content")
588
+ assert not hasattr(asset, "url")
589
+
590
+ def test_url_daast_asset_rejects_wrong_discriminator(self):
591
+ """UrlDaastAsset rejects delivery_type='inline'."""
592
+ with pytest.raises(ValidationError) as exc_info:
593
+ UrlDaastAsset(
594
+ delivery_type="inline", # Wrong discriminator value
595
+ url="https://daast.example.com/ad.xml",
596
+ )
597
+ assert "delivery_type" in str(exc_info.value).lower()
598
+
599
+ def test_inline_daast_asset_rejects_wrong_discriminator(self):
600
+ """InlineDaastAsset rejects delivery_type='url'."""
601
+ with pytest.raises(ValidationError) as exc_info:
602
+ InlineDaastAsset(
603
+ delivery_type="url", # Wrong discriminator value
604
+ content="<DAAST>...</DAAST>",
605
+ )
606
+ assert "delivery_type" in str(exc_info.value).lower()
607
+
608
+
609
+ class TestSubAssetDiscriminators:
610
+ """Test SubAsset discriminator field values match semantic aliases."""
611
+
612
+ def test_media_sub_asset_has_media_discriminator(self):
613
+ """MediaSubAsset has asset_kind='media'."""
614
+ asset = MediaSubAsset(
615
+ asset_id="asset_1",
616
+ asset_type="logo",
617
+ asset_kind="media",
618
+ content_uri="https://cdn.example.com/logo.png",
619
+ )
620
+ assert asset.asset_kind == "media"
621
+ assert hasattr(asset, "content_uri")
622
+ assert not hasattr(asset, "content")
623
+
624
+ def test_text_sub_asset_has_text_discriminator(self):
625
+ """TextSubAsset has asset_kind='text'."""
626
+ asset = TextSubAsset(
627
+ asset_id="asset_2",
628
+ asset_type="headline",
629
+ asset_kind="text",
630
+ content="Buy Now!",
631
+ )
632
+ assert asset.asset_kind == "text"
633
+ assert hasattr(asset, "content")
634
+ assert not hasattr(asset, "content_uri")
635
+
636
+ def test_media_sub_asset_rejects_wrong_discriminator(self):
637
+ """MediaSubAsset rejects asset_kind='text'."""
638
+ with pytest.raises(ValidationError) as exc_info:
639
+ MediaSubAsset(
640
+ asset_id="asset_1",
641
+ asset_type="logo",
642
+ asset_kind="text", # Wrong discriminator value
643
+ content_uri="https://cdn.example.com/logo.png",
644
+ )
645
+ assert "asset_kind" in str(exc_info.value).lower()
646
+
647
+ def test_text_sub_asset_rejects_wrong_discriminator(self):
648
+ """TextSubAsset rejects asset_kind='media'."""
649
+ with pytest.raises(ValidationError) as exc_info:
650
+ TextSubAsset(
651
+ asset_id="asset_2",
652
+ asset_type="headline",
653
+ asset_kind="media", # Wrong discriminator value
654
+ content="Buy Now!",
655
+ )
656
+ assert "asset_kind" in str(exc_info.value).lower()
657
+
658
+
659
+ class TestSemanticAliasDiscriminatorRoundtrips:
660
+ """Test that semantic aliases serialize/deserialize with correct discriminators."""
661
+
662
+ def test_url_preview_render_roundtrip(self):
663
+ """UrlPreviewRender roundtrips with output_format='url'."""
664
+ original = UrlPreviewRender(
665
+ render_id="render_1",
666
+ role="primary",
667
+ output_format="url",
668
+ preview_url="https://preview.example.com/creative",
669
+ )
670
+ json_str = original.model_dump_json()
671
+ parsed = UrlPreviewRender.model_validate_json(json_str)
672
+ assert parsed.output_format == "url"
673
+ assert parsed.preview_url == original.preview_url
674
+
675
+ def test_url_vast_asset_roundtrip(self):
676
+ """UrlVastAsset roundtrips with delivery_type='url'."""
677
+ original = UrlVastAsset(
678
+ delivery_type="url",
679
+ url="https://vast.example.com/ad.xml",
680
+ )
681
+ json_str = original.model_dump_json()
682
+ parsed = UrlVastAsset.model_validate_json(json_str)
683
+ assert parsed.delivery_type == "url"
684
+ assert parsed.url == original.url
685
+
686
+ def test_media_sub_asset_roundtrip(self):
687
+ """MediaSubAsset roundtrips with asset_kind='media'."""
688
+ original = MediaSubAsset(
689
+ asset_id="asset_1",
690
+ asset_type="logo",
691
+ asset_kind="media",
692
+ content_uri="https://cdn.example.com/logo.png",
693
+ )
694
+ json_str = original.model_dump_json()
695
+ parsed = MediaSubAsset.model_validate_json(json_str)
696
+ assert parsed.asset_kind == "media"
697
+ assert parsed.content_uri == original.content_uri
698
+
699
+ def test_text_sub_asset_roundtrip(self):
700
+ """TextSubAsset roundtrips with asset_kind='text'."""
701
+ original = TextSubAsset(
702
+ asset_id="asset_2",
703
+ asset_type="headline",
704
+ asset_kind="text",
705
+ content="Buy Now!",
706
+ )
707
+ json_str = original.model_dump_json()
708
+ parsed = TextSubAsset.model_validate_json(json_str)
709
+ assert parsed.asset_kind == "text"
710
+ assert parsed.content == original.content
@@ -12,10 +12,19 @@ from __future__ import annotations
12
12
  from adcp import (
13
13
  ActivateSignalErrorResponse,
14
14
  ActivateSignalSuccessResponse,
15
+ BothPreviewRender,
15
16
  BuildCreativeErrorResponse,
16
17
  BuildCreativeSuccessResponse,
17
18
  CreateMediaBuyErrorResponse,
18
19
  CreateMediaBuySuccessResponse,
20
+ HtmlPreviewRender,
21
+ InlineDaastAsset,
22
+ InlineVastAsset,
23
+ MediaSubAsset,
24
+ TextSubAsset,
25
+ UrlDaastAsset,
26
+ UrlPreviewRender,
27
+ UrlVastAsset,
19
28
  )
20
29
 
21
30
  # Test that aliases can also be imported from the aliases module
@@ -165,11 +174,12 @@ def test_all_activation_key_aliases_exported():
165
174
  def test_all_preview_render_aliases_exported():
166
175
  """Test that all preview render aliases are exported."""
167
176
  expected_aliases = [
168
- "PreviewRenderImage",
169
- "PreviewRenderHtml",
170
- "PreviewRenderIframe",
171
177
  "PreviewCreativeStaticResponse",
172
178
  "PreviewCreativeInteractiveResponse",
179
+ # Semantic aliases based on output_format discriminator
180
+ "UrlPreviewRender",
181
+ "HtmlPreviewRender",
182
+ "BothPreviewRender",
173
183
  ]
174
184
 
175
185
  import adcp.types.aliases as aliases_module
@@ -177,3 +187,98 @@ def test_all_preview_render_aliases_exported():
177
187
  for alias in expected_aliases:
178
188
  assert hasattr(aliases_module, alias), f"Missing alias: {alias}"
179
189
  assert alias in aliases_module.__all__, f"Alias not in __all__: {alias}"
190
+
191
+
192
+ def test_all_asset_type_aliases_exported():
193
+ """Test that all asset type aliases are exported."""
194
+ expected_aliases = [
195
+ # VAST assets
196
+ "UrlVastAsset",
197
+ "InlineVastAsset",
198
+ # DAAST assets
199
+ "UrlDaastAsset",
200
+ "InlineDaastAsset",
201
+ # SubAssets
202
+ "MediaSubAsset",
203
+ "TextSubAsset",
204
+ ]
205
+
206
+ import adcp.types.aliases as aliases_module
207
+
208
+ for alias in expected_aliases:
209
+ assert hasattr(aliases_module, alias), f"Missing alias: {alias}"
210
+ assert alias in aliases_module.__all__, f"Alias not in __all__: {alias}"
211
+
212
+
213
+ def test_discriminated_union_aliases_point_to_correct_types():
214
+ """Test that discriminated union aliases point to the correct generated types."""
215
+ from adcp.types.generated import (
216
+ DaastAsset1,
217
+ DaastAsset2,
218
+ PreviewRender1,
219
+ PreviewRender2,
220
+ PreviewRender3,
221
+ SubAsset1,
222
+ SubAsset2,
223
+ VastAsset1,
224
+ VastAsset2,
225
+ )
226
+
227
+ # Preview renders
228
+ assert UrlPreviewRender is PreviewRender1
229
+ assert HtmlPreviewRender is PreviewRender2
230
+ assert BothPreviewRender is PreviewRender3
231
+
232
+ # VAST assets
233
+ assert UrlVastAsset is VastAsset1
234
+ assert InlineVastAsset is VastAsset2
235
+
236
+ # DAAST assets
237
+ assert UrlDaastAsset is DaastAsset1
238
+ assert InlineDaastAsset is DaastAsset2
239
+
240
+ # SubAssets
241
+ assert MediaSubAsset is SubAsset1
242
+ assert TextSubAsset is SubAsset2
243
+
244
+
245
+ def test_semantic_aliases_can_be_imported_from_main_package():
246
+ """Test that new semantic aliases can be imported from the main adcp package."""
247
+ from adcp import (
248
+ BothPreviewRender as MainBothPreviewRender,
249
+ )
250
+ from adcp import (
251
+ HtmlPreviewRender as MainHtmlPreviewRender,
252
+ )
253
+ from adcp import (
254
+ InlineDaastAsset as MainInlineDaastAsset,
255
+ )
256
+ from adcp import (
257
+ InlineVastAsset as MainInlineVastAsset,
258
+ )
259
+ from adcp import (
260
+ MediaSubAsset as MainMediaSubAsset,
261
+ )
262
+ from adcp import (
263
+ TextSubAsset as MainTextSubAsset,
264
+ )
265
+ from adcp import (
266
+ UrlDaastAsset as MainUrlDaastAsset,
267
+ )
268
+ from adcp import (
269
+ UrlPreviewRender as MainUrlPreviewRender,
270
+ )
271
+ from adcp import (
272
+ UrlVastAsset as MainUrlVastAsset,
273
+ )
274
+
275
+ # Verify they match the aliases module exports
276
+ assert MainUrlPreviewRender is UrlPreviewRender
277
+ assert MainHtmlPreviewRender is HtmlPreviewRender
278
+ assert MainBothPreviewRender is BothPreviewRender
279
+ assert MainUrlVastAsset is UrlVastAsset
280
+ assert MainInlineVastAsset is InlineVastAsset
281
+ assert MainUrlDaastAsset is UrlDaastAsset
282
+ assert MainInlineDaastAsset is InlineDaastAsset
283
+ assert MainMediaSubAsset is MediaSubAsset
284
+ assert MainTextSubAsset is TextSubAsset