adcp 1.2.0__tar.gz → 1.2.1__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 (37) hide show
  1. {adcp-1.2.0/src/adcp.egg-info → adcp-1.2.1}/PKG-INFO +3 -1
  2. {adcp-1.2.0 → adcp-1.2.1}/README.md +2 -0
  3. {adcp-1.2.0 → adcp-1.2.1}/pyproject.toml +1 -1
  4. adcp-1.2.1/src/adcp/__init__.py +266 -0
  5. {adcp-1.2.0 → adcp-1.2.1}/src/adcp/client.py +12 -5
  6. {adcp-1.2.0 → adcp-1.2.1}/src/adcp/protocols/base.py +5 -2
  7. {adcp-1.2.0 → adcp-1.2.1}/src/adcp/types/generated.py +464 -55
  8. {adcp-1.2.0 → adcp-1.2.1}/src/adcp/utils/response_parser.py +64 -15
  9. {adcp-1.2.0 → adcp-1.2.1/src/adcp.egg-info}/PKG-INFO +3 -1
  10. {adcp-1.2.0 → adcp-1.2.1}/src/adcp.egg-info/SOURCES.txt +1 -0
  11. {adcp-1.2.0 → adcp-1.2.1}/tests/test_client.py +4 -1
  12. adcp-1.2.1/tests/test_discriminated_unions.py +404 -0
  13. {adcp-1.2.0 → adcp-1.2.1}/tests/test_preview_html.py +38 -13
  14. {adcp-1.2.0 → adcp-1.2.1}/tests/test_protocols.py +0 -1
  15. adcp-1.2.0/src/adcp/__init__.py +0 -96
  16. {adcp-1.2.0 → adcp-1.2.1}/LICENSE +0 -0
  17. {adcp-1.2.0 → adcp-1.2.1}/setup.cfg +0 -0
  18. {adcp-1.2.0 → adcp-1.2.1}/src/adcp/__main__.py +0 -0
  19. {adcp-1.2.0 → adcp-1.2.1}/src/adcp/config.py +0 -0
  20. {adcp-1.2.0 → adcp-1.2.1}/src/adcp/exceptions.py +0 -0
  21. {adcp-1.2.0 → adcp-1.2.1}/src/adcp/protocols/__init__.py +0 -0
  22. {adcp-1.2.0 → adcp-1.2.1}/src/adcp/protocols/a2a.py +0 -0
  23. {adcp-1.2.0 → adcp-1.2.1}/src/adcp/protocols/mcp.py +0 -0
  24. {adcp-1.2.0 → adcp-1.2.1}/src/adcp/types/__init__.py +0 -0
  25. {adcp-1.2.0 → adcp-1.2.1}/src/adcp/types/core.py +0 -0
  26. {adcp-1.2.0 → adcp-1.2.1}/src/adcp/types/tasks.py +0 -0
  27. {adcp-1.2.0 → adcp-1.2.1}/src/adcp/utils/__init__.py +0 -0
  28. {adcp-1.2.0 → adcp-1.2.1}/src/adcp/utils/operation_id.py +0 -0
  29. {adcp-1.2.0 → adcp-1.2.1}/src/adcp/utils/preview_cache.py +0 -0
  30. {adcp-1.2.0 → adcp-1.2.1}/src/adcp.egg-info/dependency_links.txt +0 -0
  31. {adcp-1.2.0 → adcp-1.2.1}/src/adcp.egg-info/entry_points.txt +0 -0
  32. {adcp-1.2.0 → adcp-1.2.1}/src/adcp.egg-info/requires.txt +0 -0
  33. {adcp-1.2.0 → adcp-1.2.1}/src/adcp.egg-info/top_level.txt +0 -0
  34. {adcp-1.2.0 → adcp-1.2.1}/tests/test_cli.py +0 -0
  35. {adcp-1.2.0 → adcp-1.2.1}/tests/test_code_generation.py +0 -0
  36. {adcp-1.2.0 → adcp-1.2.1}/tests/test_format_id_validation.py +0 -0
  37. {adcp-1.2.0 → adcp-1.2.1}/tests/test_response_parser.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: adcp
3
- Version: 1.2.0
3
+ Version: 1.2.1
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
@@ -59,6 +59,8 @@ AdCP operations are **distributed and asynchronous by default**. An agent might:
59
59
  pip install adcp
60
60
  ```
61
61
 
62
+ > **Note**: This client requires Python 3.10 or later and supports both synchronous and asynchronous workflows.
63
+
62
64
  ## Quick Start: Distributed Operations
63
65
 
64
66
  ```python
@@ -22,6 +22,8 @@ AdCP operations are **distributed and asynchronous by default**. An agent might:
22
22
  pip install adcp
23
23
  ```
24
24
 
25
+ > **Note**: This client requires Python 3.10 or later and supports both synchronous and asynchronous workflows.
26
+
25
27
  ## Quick Start: Distributed Operations
26
28
 
27
29
  ```python
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "adcp"
7
- version = "1.2.0"
7
+ version = "1.2.1"
8
8
  description = "Official Python client for the Ad Context Protocol (AdCP)"
9
9
  authors = [
10
10
  {name = "AdCP Community", email = "maintainers@adcontextprotocol.org"}
@@ -0,0 +1,266 @@
1
+ from __future__ import annotations
2
+
3
+ """
4
+ AdCP Python Client Library
5
+
6
+ Official Python client for the Ad Context Protocol (AdCP).
7
+ Supports both A2A and MCP protocols with full type safety.
8
+ """
9
+
10
+ from adcp.client import ADCPClient, ADCPMultiAgentClient
11
+ from adcp.exceptions import (
12
+ ADCPAuthenticationError,
13
+ ADCPConnectionError,
14
+ ADCPError,
15
+ ADCPProtocolError,
16
+ ADCPTimeoutError,
17
+ ADCPToolNotFoundError,
18
+ ADCPWebhookError,
19
+ ADCPWebhookSignatureError,
20
+ )
21
+ from adcp.types.core import AgentConfig, Protocol, TaskResult, TaskStatus, WebhookMetadata
22
+ from adcp.types.generated import (
23
+ ActivateSignalError,
24
+ # Request/Response types
25
+ ActivateSignalRequest,
26
+ ActivateSignalResponse,
27
+ ActivateSignalSuccess,
28
+ ActivationKey,
29
+ AgentDeployment,
30
+ AgentDestination,
31
+ BothPreviewRender,
32
+ # Brand types
33
+ BrandManifest,
34
+ BrandManifestRef,
35
+ BuildCreativeRequest,
36
+ BuildCreativeResponse,
37
+ # Channel types
38
+ Channels,
39
+ CreateMediaBuyError,
40
+ CreateMediaBuyRequest,
41
+ CreateMediaBuyResponse,
42
+ CreateMediaBuySuccess,
43
+ # Creative types
44
+ CreativeAsset,
45
+ CreativeAssignment,
46
+ CreativeManifest,
47
+ CreativePolicy,
48
+ DaastAsset,
49
+ # Metrics types
50
+ DeliveryMetrics,
51
+ # Delivery types
52
+ DeliveryType,
53
+ Deployment,
54
+ # Deployment types
55
+ Destination,
56
+ Error,
57
+ Format,
58
+ FormatId,
59
+ FrequencyCap,
60
+ GetMediaBuyDeliveryRequest,
61
+ GetMediaBuyDeliveryResponse,
62
+ GetProductsRequest,
63
+ GetProductsResponse,
64
+ GetSignalsRequest,
65
+ GetSignalsResponse,
66
+ HtmlPreviewRender,
67
+ InlineDaastAsset,
68
+ InlineVastAsset,
69
+ Key_valueActivationKey,
70
+ ListAuthorizedPropertiesRequest,
71
+ ListAuthorizedPropertiesResponse,
72
+ ListCreativeFormatsRequest,
73
+ ListCreativeFormatsResponse,
74
+ ListCreativesRequest,
75
+ ListCreativesResponse,
76
+ Measurement,
77
+ # Core domain types
78
+ MediaBuy,
79
+ # Status enums
80
+ MediaBuyStatus,
81
+ # Sub-asset types
82
+ MediaSubAsset,
83
+ Pacing,
84
+ Package,
85
+ PackageStatus,
86
+ PerformanceFeedback,
87
+ Placement,
88
+ PlatformDeployment,
89
+ PlatformDestination,
90
+ PreviewCreativeRequest,
91
+ PreviewCreativeResponse,
92
+ # Preview render types
93
+ PreviewRender,
94
+ PricingModel,
95
+ # Pricing types
96
+ PricingOption,
97
+ Product,
98
+ PromotedProducts,
99
+ # Property and placement types
100
+ Property,
101
+ ProtocolEnvelope,
102
+ ProvidePerformanceFeedbackRequest,
103
+ ProvidePerformanceFeedbackResponse,
104
+ PushNotificationConfig,
105
+ ReportingCapabilities,
106
+ Response,
107
+ Segment_idActivationKey,
108
+ StandardFormatIds,
109
+ StartTiming,
110
+ SubAsset,
111
+ SyncCreativesError,
112
+ SyncCreativesRequest,
113
+ SyncCreativesResponse,
114
+ SyncCreativesSuccess,
115
+ # Targeting types
116
+ Targeting,
117
+ # Task types
118
+ TaskType,
119
+ TextSubAsset,
120
+ UpdateMediaBuyError,
121
+ UpdateMediaBuyRequest,
122
+ UpdateMediaBuyResponse,
123
+ UpdateMediaBuySuccess,
124
+ UrlDaastAsset,
125
+ UrlPreviewRender,
126
+ UrlVastAsset,
127
+ # Asset delivery types (VAST/DAAST)
128
+ VastAsset,
129
+ # Protocol types
130
+ WebhookPayload,
131
+ )
132
+ from adcp.types.generated import (
133
+ TaskStatus as GeneratedTaskStatus,
134
+ )
135
+
136
+ __version__ = "1.2.1"
137
+
138
+ __all__ = [
139
+ # Client classes
140
+ "ADCPClient",
141
+ "ADCPMultiAgentClient",
142
+ # Core types
143
+ "AgentConfig",
144
+ "Protocol",
145
+ "TaskResult",
146
+ "TaskStatus",
147
+ "WebhookMetadata",
148
+ # Exceptions
149
+ "ADCPError",
150
+ "ADCPConnectionError",
151
+ "ADCPAuthenticationError",
152
+ "ADCPTimeoutError",
153
+ "ADCPProtocolError",
154
+ "ADCPToolNotFoundError",
155
+ "ADCPWebhookError",
156
+ "ADCPWebhookSignatureError",
157
+ # Request/Response types
158
+ "ActivateSignalRequest",
159
+ "ActivateSignalResponse",
160
+ "ActivateSignalSuccess",
161
+ "ActivateSignalError",
162
+ "ActivationKey",
163
+ "Segment_idActivationKey",
164
+ "Key_valueActivationKey",
165
+ "BuildCreativeRequest",
166
+ "BuildCreativeResponse",
167
+ "CreateMediaBuyRequest",
168
+ "CreateMediaBuyResponse",
169
+ "CreateMediaBuySuccess",
170
+ "CreateMediaBuyError",
171
+ "GetMediaBuyDeliveryRequest",
172
+ "GetMediaBuyDeliveryResponse",
173
+ "GetProductsRequest",
174
+ "GetProductsResponse",
175
+ "GetSignalsRequest",
176
+ "GetSignalsResponse",
177
+ "ListAuthorizedPropertiesRequest",
178
+ "ListAuthorizedPropertiesResponse",
179
+ "ListCreativeFormatsRequest",
180
+ "ListCreativeFormatsResponse",
181
+ "ListCreativesRequest",
182
+ "ListCreativesResponse",
183
+ "PreviewCreativeRequest",
184
+ "PreviewCreativeResponse",
185
+ "ProvidePerformanceFeedbackRequest",
186
+ "ProvidePerformanceFeedbackResponse",
187
+ "SyncCreativesRequest",
188
+ "SyncCreativesResponse",
189
+ "SyncCreativesSuccess",
190
+ "SyncCreativesError",
191
+ "UpdateMediaBuyRequest",
192
+ "UpdateMediaBuyResponse",
193
+ "UpdateMediaBuySuccess",
194
+ "UpdateMediaBuyError",
195
+ # Core domain types
196
+ "MediaBuy",
197
+ "Product",
198
+ "Package",
199
+ "Error",
200
+ # Creative types
201
+ "CreativeAsset",
202
+ "CreativeManifest",
203
+ "CreativeAssignment",
204
+ "CreativePolicy",
205
+ "Format",
206
+ "FormatId",
207
+ # Property and placement types
208
+ "Property",
209
+ "Placement",
210
+ # Targeting types
211
+ "Targeting",
212
+ "FrequencyCap",
213
+ "Pacing",
214
+ # Brand types
215
+ "BrandManifest",
216
+ "BrandManifestRef",
217
+ # Metrics types
218
+ "DeliveryMetrics",
219
+ "Measurement",
220
+ "PerformanceFeedback",
221
+ # Status enums
222
+ "MediaBuyStatus",
223
+ "PackageStatus",
224
+ # Pricing types
225
+ "PricingOption",
226
+ "PricingModel",
227
+ # Delivery types
228
+ "DeliveryType",
229
+ "StartTiming",
230
+ # Channel types
231
+ "Channels",
232
+ "StandardFormatIds",
233
+ # Protocol types
234
+ "WebhookPayload",
235
+ "ProtocolEnvelope",
236
+ "Response",
237
+ "PromotedProducts",
238
+ "PushNotificationConfig",
239
+ "ReportingCapabilities",
240
+ # Deployment types
241
+ "Destination",
242
+ "Deployment",
243
+ "PlatformDestination",
244
+ "AgentDestination",
245
+ "PlatformDeployment",
246
+ "AgentDeployment",
247
+ # Sub-asset types
248
+ "MediaSubAsset",
249
+ "SubAsset",
250
+ "TextSubAsset",
251
+ # Asset delivery types (VAST/DAAST)
252
+ "VastAsset",
253
+ "UrlVastAsset",
254
+ "InlineVastAsset",
255
+ "DaastAsset",
256
+ "UrlDaastAsset",
257
+ "InlineDaastAsset",
258
+ # Preview render types
259
+ "PreviewRender",
260
+ "UrlPreviewRender",
261
+ "HtmlPreviewRender",
262
+ "BothPreviewRender",
263
+ # Task types
264
+ "TaskType",
265
+ "GeneratedTaskStatus",
266
+ ]
@@ -11,6 +11,8 @@ from collections.abc import Callable
11
11
  from datetime import datetime, timezone
12
12
  from typing import Any
13
13
 
14
+ from pydantic import BaseModel
15
+
14
16
  from adcp.exceptions import ADCPWebhookSignatureError
15
17
  from adcp.protocols.a2a import A2AAdapter
16
18
  from adcp.protocols.base import ProtocolAdapter
@@ -154,7 +156,9 @@ class ADCPClient:
154
156
  )
155
157
  )
156
158
 
157
- result = self.adapter._parse_response(raw_result, GetProductsResponse)
159
+ result: TaskResult[GetProductsResponse] = self.adapter._parse_response(
160
+ raw_result, GetProductsResponse
161
+ )
158
162
 
159
163
  if fetch_previews and result.success and result.data and creative_agent_client:
160
164
  from adcp.utils.preview_cache import add_preview_urls_to_products
@@ -215,7 +219,9 @@ class ADCPClient:
215
219
  )
216
220
  )
217
221
 
218
- result = self.adapter._parse_response(raw_result, ListCreativeFormatsResponse)
222
+ result: TaskResult[ListCreativeFormatsResponse] = self.adapter._parse_response(
223
+ raw_result, ListCreativeFormatsResponse
224
+ )
219
225
 
220
226
  if fetch_previews and result.success and result.data:
221
227
  from adcp.utils.preview_cache import add_preview_urls_to_formats
@@ -617,15 +623,16 @@ class ADCPClient:
617
623
  from adcp.utils.response_parser import parse_json_or_text
618
624
 
619
625
  # Map task types to their response types (using string literals, not enum)
620
- response_type_map: dict[str, type] = {
626
+ # Note: Some response types are Union types (e.g., ActivateSignalResponse = Success | Error)
627
+ response_type_map: dict[str, type[BaseModel] | Any] = {
621
628
  "get_products": GetProductsResponse,
622
629
  "list_creative_formats": ListCreativeFormatsResponse,
623
- "sync_creatives": SyncCreativesResponse,
630
+ "sync_creatives": SyncCreativesResponse, # Union type
624
631
  "list_creatives": ListCreativesResponse,
625
632
  "get_media_buy_delivery": GetMediaBuyDeliveryResponse,
626
633
  "list_authorized_properties": ListAuthorizedPropertiesResponse,
627
634
  "get_signals": GetSignalsResponse,
628
- "activate_signal": ActivateSignalResponse,
635
+ "activate_signal": ActivateSignalResponse, # Union type
629
636
  "provide_performance_feedback": ProvidePerformanceFeedbackResponse,
630
637
  }
631
638
 
@@ -30,15 +30,18 @@ class ProtocolAdapter(ABC):
30
30
  # Helper methods for response parsing
31
31
  # ========================================================================
32
32
 
33
- def _parse_response(self, raw_result: TaskResult[Any], response_type: type[T]) -> TaskResult[T]:
33
+ def _parse_response(
34
+ self, raw_result: TaskResult[Any], response_type: type[T] | Any
35
+ ) -> TaskResult[T]:
34
36
  """
35
37
  Parse raw TaskResult into typed TaskResult.
36
38
 
37
39
  Handles both MCP content arrays and A2A dict responses.
40
+ Supports both single types and Union types (for oneOf discriminated unions).
38
41
 
39
42
  Args:
40
43
  raw_result: Raw TaskResult from adapter
41
- response_type: Expected Pydantic response type
44
+ response_type: Expected Pydantic response type (can be a Union type)
42
45
 
43
46
  Returns:
44
47
  Typed TaskResult