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
adcp/simple.py ADDED
@@ -0,0 +1,451 @@
1
+ """Simplified API accessor for ADCPClient.
2
+
3
+ Provides an ergonomic API with:
4
+ - Kwargs instead of request objects
5
+ - Direct return values (no TaskResult unwrapping)
6
+ - Raises exceptions on errors
7
+
8
+ Usage:
9
+ client = ADCPClient(config)
10
+
11
+ # Standard API: full control
12
+ result = await client.get_products(GetProductsRequest(brief="Coffee"))
13
+ if result.success:
14
+ print(result.data.products)
15
+
16
+ # Simple API: ergonomic
17
+ products = await client.simple.get_products(brief="Coffee")
18
+ print(products.products)
19
+ """
20
+
21
+ from __future__ import annotations
22
+
23
+ from typing import TYPE_CHECKING, Any
24
+
25
+ from adcp.exceptions import ADCPSimpleAPIError
26
+ from adcp.types import (
27
+ ActivateSignalRequest,
28
+ ActivateSignalResponse,
29
+ BuildCreativeRequest,
30
+ BuildCreativeResponse,
31
+ CreateMediaBuyRequest,
32
+ CreateMediaBuyResponse,
33
+ GetMediaBuyDeliveryRequest,
34
+ GetMediaBuyDeliveryResponse,
35
+ GetProductsRequest,
36
+ GetProductsResponse,
37
+ GetSignalsRequest,
38
+ GetSignalsResponse,
39
+ ListAuthorizedPropertiesRequest,
40
+ ListAuthorizedPropertiesResponse,
41
+ ListCreativeFormatsRequest,
42
+ ListCreativeFormatsResponse,
43
+ ListCreativesRequest,
44
+ ListCreativesResponse,
45
+ PreviewCreativeRequest,
46
+ PreviewCreativeResponse,
47
+ ProvidePerformanceFeedbackRequest,
48
+ ProvidePerformanceFeedbackResponse,
49
+ SyncCreativesRequest,
50
+ SyncCreativesResponse,
51
+ UpdateMediaBuyRequest,
52
+ UpdateMediaBuyResponse,
53
+ )
54
+
55
+ if TYPE_CHECKING:
56
+ from adcp.client import ADCPClient
57
+
58
+
59
+ class SimpleAPI:
60
+ """Simplified API accessor for ergonomic usage.
61
+
62
+ Provides kwargs-based methods that return unwrapped response data
63
+ and raise exceptions on errors.
64
+
65
+ This is intended for:
66
+ - Quick prototyping and testing
67
+ - Documentation and examples
68
+ - Simple scripts and notebooks
69
+
70
+ For production code with complex error handling, use the standard
71
+ client API which returns TaskResult wrappers.
72
+ """
73
+
74
+ def __init__(self, client: ADCPClient):
75
+ """Initialize simple API accessor.
76
+
77
+ Args:
78
+ client: The ADCPClient instance to wrap
79
+ """
80
+ self._client = client
81
+
82
+ async def get_products(
83
+ self,
84
+ **kwargs: Any,
85
+ ) -> GetProductsResponse:
86
+ """Get advertising products (simplified).
87
+
88
+ This is a convenience wrapper around client.get_products() that:
89
+ - Accepts kwargs instead of GetProductsRequest
90
+ - Returns unwrapped GetProductsResponse
91
+ - Raises ADCPSimpleAPIError on failures
92
+
93
+ For full control over error handling, use client.get_products() instead.
94
+
95
+ Args:
96
+ **kwargs: Arguments for GetProductsRequest (brief, brand_manifest, etc.)
97
+
98
+ Returns:
99
+ GetProductsResponse directly (no TaskResult wrapper)
100
+
101
+ Raises:
102
+ ADCPSimpleAPIError: If request fails. Use standard API for detailed error handling.
103
+
104
+ Example:
105
+ products = await client.simple.get_products(
106
+ brief='Coffee subscription service'
107
+ )
108
+ print(f"Found {len(products.products)} products")
109
+ """
110
+ request = GetProductsRequest(**kwargs)
111
+ result = await self._client.get_products(request)
112
+ if not result.success or not result.data:
113
+ raise ADCPSimpleAPIError(
114
+ operation="get_products",
115
+ error_message=result.error,
116
+ agent_id=self._client.agent_config.id,
117
+ )
118
+ return result.data
119
+
120
+ async def list_creative_formats(
121
+ self,
122
+ **kwargs: Any,
123
+ ) -> ListCreativeFormatsResponse:
124
+ """List supported creative formats.
125
+
126
+ Args:
127
+ **kwargs: Arguments passed to ListCreativeFormatsRequest
128
+
129
+ Returns:
130
+ ListCreativeFormatsResponse with formats list
131
+
132
+ Raises:
133
+ Exception: If the request fails
134
+
135
+ Example:
136
+ formats = await client.simple.list_creative_formats()
137
+ print(f"Found {len(formats.formats)} formats")
138
+ """
139
+ request = ListCreativeFormatsRequest(**kwargs)
140
+ result = await self._client.list_creative_formats(request)
141
+ if not result.success or not result.data:
142
+ raise ADCPSimpleAPIError(
143
+ operation="list_creative_formats",
144
+ error_message=result.error,
145
+ agent_id=self._client.agent_config.id,
146
+ )
147
+ return result.data
148
+
149
+ async def preview_creative(
150
+ self,
151
+ **kwargs: Any,
152
+ ) -> PreviewCreativeResponse:
153
+ """Preview creative manifest.
154
+
155
+ Args:
156
+ **kwargs: Arguments passed to PreviewCreativeRequest
157
+
158
+ Returns:
159
+ PreviewCreativeResponse with preview data
160
+
161
+ Raises:
162
+ Exception: If the request fails
163
+
164
+ Example:
165
+ preview = await client.simple.preview_creative(
166
+ manifest={'format_id': 'banner_300x250', 'assets': {...}}
167
+ )
168
+ print(f"Preview: {preview.previews[0]}")
169
+ """
170
+ request = PreviewCreativeRequest(**kwargs)
171
+ result = await self._client.preview_creative(request)
172
+ if not result.success or not result.data:
173
+ raise ADCPSimpleAPIError(
174
+ operation="preview_creative",
175
+ error_message=result.error,
176
+ agent_id=self._client.agent_config.id,
177
+ )
178
+ return result.data
179
+
180
+ async def sync_creatives(
181
+ self,
182
+ **kwargs: Any,
183
+ ) -> SyncCreativesResponse:
184
+ """Sync creatives.
185
+
186
+ Args:
187
+ **kwargs: Arguments passed to SyncCreativesRequest
188
+
189
+ Returns:
190
+ SyncCreativesResponse
191
+
192
+ Raises:
193
+ Exception: If the request fails
194
+ """
195
+ request = SyncCreativesRequest(**kwargs)
196
+ result = await self._client.sync_creatives(request)
197
+ if not result.success or not result.data:
198
+ raise ADCPSimpleAPIError(
199
+ operation="sync_creatives",
200
+ error_message=result.error,
201
+ agent_id=self._client.agent_config.id,
202
+ )
203
+ return result.data
204
+
205
+ async def list_creatives(
206
+ self,
207
+ **kwargs: Any,
208
+ ) -> ListCreativesResponse:
209
+ """List creatives.
210
+
211
+ Args:
212
+ **kwargs: Arguments passed to ListCreativesRequest
213
+
214
+ Returns:
215
+ ListCreativesResponse
216
+
217
+ Raises:
218
+ Exception: If the request fails
219
+ """
220
+ request = ListCreativesRequest(**kwargs)
221
+ result = await self._client.list_creatives(request)
222
+ if not result.success or not result.data:
223
+ raise ADCPSimpleAPIError(
224
+ operation="list_creatives",
225
+ error_message=result.error,
226
+ agent_id=self._client.agent_config.id,
227
+ )
228
+ return result.data
229
+
230
+ async def get_media_buy_delivery(
231
+ self,
232
+ **kwargs: Any,
233
+ ) -> GetMediaBuyDeliveryResponse:
234
+ """Get media buy delivery.
235
+
236
+ Args:
237
+ **kwargs: Arguments passed to GetMediaBuyDeliveryRequest
238
+
239
+ Returns:
240
+ GetMediaBuyDeliveryResponse
241
+
242
+ Raises:
243
+ Exception: If the request fails
244
+ """
245
+ request = GetMediaBuyDeliveryRequest(**kwargs)
246
+ result = await self._client.get_media_buy_delivery(request)
247
+ if not result.success or not result.data:
248
+ raise ADCPSimpleAPIError(
249
+ operation="get_media_buy_delivery",
250
+ error_message=result.error,
251
+ agent_id=self._client.agent_config.id,
252
+ )
253
+ return result.data
254
+
255
+ async def list_authorized_properties(
256
+ self,
257
+ **kwargs: Any,
258
+ ) -> ListAuthorizedPropertiesResponse:
259
+ """List authorized properties.
260
+
261
+ Args:
262
+ **kwargs: Arguments passed to ListAuthorizedPropertiesRequest
263
+
264
+ Returns:
265
+ ListAuthorizedPropertiesResponse
266
+
267
+ Raises:
268
+ Exception: If the request fails
269
+ """
270
+ request = ListAuthorizedPropertiesRequest(**kwargs)
271
+ result = await self._client.list_authorized_properties(request)
272
+ if not result.success or not result.data:
273
+ raise ADCPSimpleAPIError(
274
+ operation="list_authorized_properties",
275
+ error_message=result.error,
276
+ agent_id=self._client.agent_config.id,
277
+ )
278
+ return result.data
279
+
280
+ async def get_signals(
281
+ self,
282
+ **kwargs: Any,
283
+ ) -> GetSignalsResponse:
284
+ """Get signals.
285
+
286
+ Args:
287
+ **kwargs: Arguments passed to GetSignalsRequest
288
+
289
+ Returns:
290
+ GetSignalsResponse
291
+
292
+ Raises:
293
+ Exception: If the request fails
294
+ """
295
+ request = GetSignalsRequest(**kwargs)
296
+ result = await self._client.get_signals(request)
297
+ if not result.success or not result.data:
298
+ raise ADCPSimpleAPIError(
299
+ operation="get_signals",
300
+ error_message=result.error,
301
+ agent_id=self._client.agent_config.id,
302
+ )
303
+ return result.data
304
+
305
+ async def activate_signal(
306
+ self,
307
+ **kwargs: Any,
308
+ ) -> ActivateSignalResponse:
309
+ """Activate signal.
310
+
311
+ Args:
312
+ **kwargs: Arguments passed to ActivateSignalRequest
313
+
314
+ Returns:
315
+ ActivateSignalResponse
316
+
317
+ Raises:
318
+ Exception: If the request fails
319
+ """
320
+ request = ActivateSignalRequest(**kwargs)
321
+ result = await self._client.activate_signal(request)
322
+ if not result.success or not result.data:
323
+ raise ADCPSimpleAPIError(
324
+ operation="activate_signal",
325
+ error_message=result.error,
326
+ agent_id=self._client.agent_config.id,
327
+ )
328
+ return result.data
329
+
330
+ async def provide_performance_feedback(
331
+ self,
332
+ **kwargs: Any,
333
+ ) -> ProvidePerformanceFeedbackResponse:
334
+ """Provide performance feedback.
335
+
336
+ Args:
337
+ **kwargs: Arguments passed to ProvidePerformanceFeedbackRequest
338
+
339
+ Returns:
340
+ ProvidePerformanceFeedbackResponse
341
+
342
+ Raises:
343
+ Exception: If the request fails
344
+ """
345
+ request = ProvidePerformanceFeedbackRequest(**kwargs)
346
+ result = await self._client.provide_performance_feedback(request)
347
+ if not result.success or not result.data:
348
+ raise ADCPSimpleAPIError(
349
+ operation="provide_performance_feedback",
350
+ error_message=result.error,
351
+ agent_id=self._client.agent_config.id,
352
+ )
353
+ return result.data
354
+
355
+ async def create_media_buy(
356
+ self,
357
+ **kwargs: Any,
358
+ ) -> CreateMediaBuyResponse:
359
+ """Create media buy.
360
+
361
+ Args:
362
+ **kwargs: Arguments passed to CreateMediaBuyRequest
363
+
364
+ Returns:
365
+ CreateMediaBuyResponse
366
+
367
+ Raises:
368
+ Exception: If the request fails
369
+
370
+ Example:
371
+ media_buy = await client.simple.create_media_buy(
372
+ brand_manifest=brand,
373
+ packages=[package_request],
374
+ publisher_properties=properties
375
+ )
376
+ print(f"Created media buy: {media_buy.media_buy_id}")
377
+ """
378
+ request = CreateMediaBuyRequest(**kwargs)
379
+ result = await self._client.create_media_buy(request)
380
+ if not result.success or not result.data:
381
+ raise ADCPSimpleAPIError(
382
+ operation="create_media_buy",
383
+ error_message=result.error,
384
+ agent_id=self._client.agent_config.id,
385
+ )
386
+ return result.data
387
+
388
+ async def update_media_buy(
389
+ self,
390
+ **kwargs: Any,
391
+ ) -> UpdateMediaBuyResponse:
392
+ """Update media buy.
393
+
394
+ Args:
395
+ **kwargs: Arguments passed to UpdateMediaBuyRequest
396
+
397
+ Returns:
398
+ UpdateMediaBuyResponse
399
+
400
+ Raises:
401
+ Exception: If the request fails
402
+
403
+ Example:
404
+ updated = await client.simple.update_media_buy(
405
+ media_buy_id="mb_123",
406
+ packages=[updated_package]
407
+ )
408
+ print(f"Updated media buy: {updated.media_buy_id}")
409
+ """
410
+ request = UpdateMediaBuyRequest(**kwargs)
411
+ result = await self._client.update_media_buy(request)
412
+ if not result.success or not result.data:
413
+ raise ADCPSimpleAPIError(
414
+ operation="update_media_buy",
415
+ error_message=result.error,
416
+ agent_id=self._client.agent_config.id,
417
+ )
418
+ return result.data
419
+
420
+ async def build_creative(
421
+ self,
422
+ **kwargs: Any,
423
+ ) -> BuildCreativeResponse:
424
+ """Build creative.
425
+
426
+ Args:
427
+ **kwargs: Arguments passed to BuildCreativeRequest
428
+
429
+ Returns:
430
+ BuildCreativeResponse
431
+
432
+ Raises:
433
+ Exception: If the request fails
434
+
435
+ Example:
436
+ creative = await client.simple.build_creative(
437
+ manifest=creative_manifest,
438
+ target_format_id="vast_2.0",
439
+ inputs={"duration": 30}
440
+ )
441
+ print(f"Built creative: {creative.assets[0].url}")
442
+ """
443
+ request = BuildCreativeRequest(**kwargs)
444
+ result = await self._client.build_creative(request)
445
+ if not result.success or not result.data:
446
+ raise ADCPSimpleAPIError(
447
+ operation="build_creative",
448
+ error_message=result.error,
449
+ agent_id=self._client.agent_config.id,
450
+ )
451
+ return result.data
@@ -0,0 +1,53 @@
1
+ """Test helpers for AdCP client library.
2
+
3
+ Provides pre-configured test agents for examples and quick testing.
4
+
5
+ All test agents include a `.simple` accessor for ergonomic usage:
6
+
7
+ - **Standard API** (client methods): Full TaskResult with error handling
8
+ - **Simple API** (client.simple methods): Direct returns, raises on error
9
+
10
+ Example:
11
+ # Standard API - explicit control
12
+ result = await test_agent.get_products(GetProductsRequest(brief='Coffee'))
13
+ if result.success:
14
+ print(result.data.products)
15
+
16
+ # Simple API - ergonomic
17
+ products = await test_agent.simple.get_products(brief='Coffee')
18
+ print(products.products)
19
+ """
20
+
21
+ from __future__ import annotations
22
+
23
+ from adcp.testing.test_helpers import (
24
+ CREATIVE_AGENT_CONFIG,
25
+ TEST_AGENT_A2A_CONFIG,
26
+ TEST_AGENT_A2A_NO_AUTH_CONFIG,
27
+ TEST_AGENT_MCP_CONFIG,
28
+ TEST_AGENT_MCP_NO_AUTH_CONFIG,
29
+ TEST_AGENT_TOKEN,
30
+ create_test_agent,
31
+ creative_agent,
32
+ test_agent,
33
+ test_agent_a2a,
34
+ test_agent_a2a_no_auth,
35
+ test_agent_client,
36
+ test_agent_no_auth,
37
+ )
38
+
39
+ __all__ = [
40
+ "test_agent",
41
+ "test_agent_a2a",
42
+ "test_agent_no_auth",
43
+ "test_agent_a2a_no_auth",
44
+ "creative_agent",
45
+ "test_agent_client",
46
+ "create_test_agent",
47
+ "TEST_AGENT_TOKEN",
48
+ "TEST_AGENT_MCP_CONFIG",
49
+ "TEST_AGENT_A2A_CONFIG",
50
+ "TEST_AGENT_MCP_NO_AUTH_CONFIG",
51
+ "TEST_AGENT_A2A_NO_AUTH_CONFIG",
52
+ "CREATIVE_AGENT_CONFIG",
53
+ ]