adcp 1.2.0__py3-none-any.whl → 1.3.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.
- adcp/__init__.py +210 -17
- adcp/client.py +12 -5
- adcp/protocols/base.py +5 -2
- adcp/testing/__init__.py +38 -0
- adcp/testing/test_helpers.py +311 -0
- adcp/types/generated.py +464 -55
- adcp/utils/response_parser.py +64 -15
- {adcp-1.2.0.dist-info → adcp-1.3.0.dist-info}/METADATA +138 -1
- {adcp-1.2.0.dist-info → adcp-1.3.0.dist-info}/RECORD +13 -11
- {adcp-1.2.0.dist-info → adcp-1.3.0.dist-info}/WHEEL +0 -0
- {adcp-1.2.0.dist-info → adcp-1.3.0.dist-info}/entry_points.txt +0 -0
- {adcp-1.2.0.dist-info → adcp-1.3.0.dist-info}/licenses/LICENSE +0 -0
- {adcp-1.2.0.dist-info → adcp-1.3.0.dist-info}/top_level.txt +0 -0
adcp/__init__.py
CHANGED
|
@@ -18,35 +18,135 @@ from adcp.exceptions import (
|
|
|
18
18
|
ADCPWebhookError,
|
|
19
19
|
ADCPWebhookSignatureError,
|
|
20
20
|
)
|
|
21
|
+
|
|
22
|
+
# Test helpers
|
|
23
|
+
from adcp.testing import (
|
|
24
|
+
CREATIVE_AGENT_CONFIG,
|
|
25
|
+
TEST_AGENT_A2A_CONFIG,
|
|
26
|
+
TEST_AGENT_MCP_CONFIG,
|
|
27
|
+
TEST_AGENT_TOKEN,
|
|
28
|
+
create_test_agent,
|
|
29
|
+
creative_agent,
|
|
30
|
+
test_agent,
|
|
31
|
+
test_agent_a2a,
|
|
32
|
+
test_agent_client,
|
|
33
|
+
)
|
|
21
34
|
from adcp.types.core import AgentConfig, Protocol, TaskResult, TaskStatus, WebhookMetadata
|
|
22
35
|
from adcp.types.generated import (
|
|
36
|
+
ActivateSignalError,
|
|
37
|
+
# Request/Response types
|
|
23
38
|
ActivateSignalRequest,
|
|
24
39
|
ActivateSignalResponse,
|
|
40
|
+
ActivateSignalSuccess,
|
|
41
|
+
ActivationKey,
|
|
42
|
+
AgentDeployment,
|
|
43
|
+
AgentDestination,
|
|
44
|
+
BothPreviewRender,
|
|
45
|
+
# Brand types
|
|
46
|
+
BrandManifest,
|
|
47
|
+
BrandManifestRef,
|
|
48
|
+
BuildCreativeRequest,
|
|
49
|
+
BuildCreativeResponse,
|
|
50
|
+
# Channel types
|
|
51
|
+
Channels,
|
|
52
|
+
CreateMediaBuyError,
|
|
25
53
|
CreateMediaBuyRequest,
|
|
26
54
|
CreateMediaBuyResponse,
|
|
55
|
+
CreateMediaBuySuccess,
|
|
56
|
+
# Creative types
|
|
57
|
+
CreativeAsset,
|
|
58
|
+
CreativeAssignment,
|
|
59
|
+
CreativeManifest,
|
|
60
|
+
CreativePolicy,
|
|
61
|
+
DaastAsset,
|
|
62
|
+
# Metrics types
|
|
63
|
+
DeliveryMetrics,
|
|
64
|
+
# Delivery types
|
|
65
|
+
DeliveryType,
|
|
66
|
+
Deployment,
|
|
67
|
+
# Deployment types
|
|
68
|
+
Destination,
|
|
69
|
+
Error,
|
|
70
|
+
Format,
|
|
71
|
+
FormatId,
|
|
72
|
+
FrequencyCap,
|
|
27
73
|
GetMediaBuyDeliveryRequest,
|
|
28
74
|
GetMediaBuyDeliveryResponse,
|
|
29
75
|
GetProductsRequest,
|
|
30
76
|
GetProductsResponse,
|
|
31
77
|
GetSignalsRequest,
|
|
32
78
|
GetSignalsResponse,
|
|
79
|
+
HtmlPreviewRender,
|
|
80
|
+
InlineDaastAsset,
|
|
81
|
+
InlineVastAsset,
|
|
82
|
+
Key_valueActivationKey,
|
|
33
83
|
ListAuthorizedPropertiesRequest,
|
|
34
84
|
ListAuthorizedPropertiesResponse,
|
|
35
85
|
ListCreativeFormatsRequest,
|
|
36
86
|
ListCreativeFormatsResponse,
|
|
37
87
|
ListCreativesRequest,
|
|
38
88
|
ListCreativesResponse,
|
|
89
|
+
Measurement,
|
|
90
|
+
# Core domain types
|
|
39
91
|
MediaBuy,
|
|
92
|
+
# Status enums
|
|
93
|
+
MediaBuyStatus,
|
|
94
|
+
# Sub-asset types
|
|
95
|
+
MediaSubAsset,
|
|
96
|
+
Pacing,
|
|
97
|
+
Package,
|
|
98
|
+
PackageStatus,
|
|
99
|
+
PerformanceFeedback,
|
|
100
|
+
Placement,
|
|
101
|
+
PlatformDeployment,
|
|
102
|
+
PlatformDestination,
|
|
103
|
+
PreviewCreativeRequest,
|
|
104
|
+
PreviewCreativeResponse,
|
|
105
|
+
# Preview render types
|
|
106
|
+
PreviewRender,
|
|
107
|
+
PricingModel,
|
|
108
|
+
# Pricing types
|
|
109
|
+
PricingOption,
|
|
40
110
|
Product,
|
|
111
|
+
PromotedProducts,
|
|
112
|
+
# Property and placement types
|
|
113
|
+
Property,
|
|
114
|
+
ProtocolEnvelope,
|
|
41
115
|
ProvidePerformanceFeedbackRequest,
|
|
42
116
|
ProvidePerformanceFeedbackResponse,
|
|
117
|
+
PushNotificationConfig,
|
|
118
|
+
ReportingCapabilities,
|
|
119
|
+
Response,
|
|
120
|
+
Segment_idActivationKey,
|
|
121
|
+
StandardFormatIds,
|
|
122
|
+
StartTiming,
|
|
123
|
+
SubAsset,
|
|
124
|
+
SyncCreativesError,
|
|
43
125
|
SyncCreativesRequest,
|
|
44
126
|
SyncCreativesResponse,
|
|
127
|
+
SyncCreativesSuccess,
|
|
128
|
+
# Targeting types
|
|
129
|
+
Targeting,
|
|
130
|
+
# Task types
|
|
131
|
+
TaskType,
|
|
132
|
+
TextSubAsset,
|
|
133
|
+
UpdateMediaBuyError,
|
|
45
134
|
UpdateMediaBuyRequest,
|
|
46
135
|
UpdateMediaBuyResponse,
|
|
136
|
+
UpdateMediaBuySuccess,
|
|
137
|
+
UrlDaastAsset,
|
|
138
|
+
UrlPreviewRender,
|
|
139
|
+
UrlVastAsset,
|
|
140
|
+
# Asset delivery types (VAST/DAAST)
|
|
141
|
+
VastAsset,
|
|
142
|
+
# Protocol types
|
|
143
|
+
WebhookPayload,
|
|
144
|
+
)
|
|
145
|
+
from adcp.types.generated import (
|
|
146
|
+
TaskStatus as GeneratedTaskStatus,
|
|
47
147
|
)
|
|
48
148
|
|
|
49
|
-
__version__ = "1.
|
|
149
|
+
__version__ = "1.3.0"
|
|
50
150
|
|
|
51
151
|
__all__ = [
|
|
52
152
|
# Client classes
|
|
@@ -58,6 +158,16 @@ __all__ = [
|
|
|
58
158
|
"TaskResult",
|
|
59
159
|
"TaskStatus",
|
|
60
160
|
"WebhookMetadata",
|
|
161
|
+
# Test helpers
|
|
162
|
+
"test_agent",
|
|
163
|
+
"test_agent_a2a",
|
|
164
|
+
"creative_agent",
|
|
165
|
+
"test_agent_client",
|
|
166
|
+
"create_test_agent",
|
|
167
|
+
"TEST_AGENT_TOKEN",
|
|
168
|
+
"TEST_AGENT_MCP_CONFIG",
|
|
169
|
+
"TEST_AGENT_A2A_CONFIG",
|
|
170
|
+
"CREATIVE_AGENT_CONFIG",
|
|
61
171
|
# Exceptions
|
|
62
172
|
"ADCPError",
|
|
63
173
|
"ADCPConnectionError",
|
|
@@ -67,30 +177,113 @@ __all__ = [
|
|
|
67
177
|
"ADCPToolNotFoundError",
|
|
68
178
|
"ADCPWebhookError",
|
|
69
179
|
"ADCPWebhookSignatureError",
|
|
70
|
-
#
|
|
71
|
-
"
|
|
72
|
-
"
|
|
180
|
+
# Request/Response types
|
|
181
|
+
"ActivateSignalRequest",
|
|
182
|
+
"ActivateSignalResponse",
|
|
183
|
+
"ActivateSignalSuccess",
|
|
184
|
+
"ActivateSignalError",
|
|
185
|
+
"ActivationKey",
|
|
186
|
+
"Segment_idActivationKey",
|
|
187
|
+
"Key_valueActivationKey",
|
|
188
|
+
"BuildCreativeRequest",
|
|
189
|
+
"BuildCreativeResponse",
|
|
73
190
|
"CreateMediaBuyRequest",
|
|
74
191
|
"CreateMediaBuyResponse",
|
|
75
|
-
"
|
|
76
|
-
"
|
|
77
|
-
"SyncCreativesRequest",
|
|
78
|
-
"SyncCreativesResponse",
|
|
79
|
-
"ListCreativesRequest",
|
|
80
|
-
"ListCreativesResponse",
|
|
81
|
-
"ListCreativeFormatsRequest",
|
|
82
|
-
"ListCreativeFormatsResponse",
|
|
192
|
+
"CreateMediaBuySuccess",
|
|
193
|
+
"CreateMediaBuyError",
|
|
83
194
|
"GetMediaBuyDeliveryRequest",
|
|
84
195
|
"GetMediaBuyDeliveryResponse",
|
|
85
|
-
"
|
|
86
|
-
"
|
|
196
|
+
"GetProductsRequest",
|
|
197
|
+
"GetProductsResponse",
|
|
87
198
|
"GetSignalsRequest",
|
|
88
199
|
"GetSignalsResponse",
|
|
89
|
-
"
|
|
90
|
-
"
|
|
200
|
+
"ListAuthorizedPropertiesRequest",
|
|
201
|
+
"ListAuthorizedPropertiesResponse",
|
|
202
|
+
"ListCreativeFormatsRequest",
|
|
203
|
+
"ListCreativeFormatsResponse",
|
|
204
|
+
"ListCreativesRequest",
|
|
205
|
+
"ListCreativesResponse",
|
|
206
|
+
"PreviewCreativeRequest",
|
|
207
|
+
"PreviewCreativeResponse",
|
|
91
208
|
"ProvidePerformanceFeedbackRequest",
|
|
92
209
|
"ProvidePerformanceFeedbackResponse",
|
|
210
|
+
"SyncCreativesRequest",
|
|
211
|
+
"SyncCreativesResponse",
|
|
212
|
+
"SyncCreativesSuccess",
|
|
213
|
+
"SyncCreativesError",
|
|
214
|
+
"UpdateMediaBuyRequest",
|
|
215
|
+
"UpdateMediaBuyResponse",
|
|
216
|
+
"UpdateMediaBuySuccess",
|
|
217
|
+
"UpdateMediaBuyError",
|
|
93
218
|
# Core domain types
|
|
94
|
-
"Product",
|
|
95
219
|
"MediaBuy",
|
|
220
|
+
"Product",
|
|
221
|
+
"Package",
|
|
222
|
+
"Error",
|
|
223
|
+
# Creative types
|
|
224
|
+
"CreativeAsset",
|
|
225
|
+
"CreativeManifest",
|
|
226
|
+
"CreativeAssignment",
|
|
227
|
+
"CreativePolicy",
|
|
228
|
+
"Format",
|
|
229
|
+
"FormatId",
|
|
230
|
+
# Property and placement types
|
|
231
|
+
"Property",
|
|
232
|
+
"Placement",
|
|
233
|
+
# Targeting types
|
|
234
|
+
"Targeting",
|
|
235
|
+
"FrequencyCap",
|
|
236
|
+
"Pacing",
|
|
237
|
+
# Brand types
|
|
238
|
+
"BrandManifest",
|
|
239
|
+
"BrandManifestRef",
|
|
240
|
+
# Metrics types
|
|
241
|
+
"DeliveryMetrics",
|
|
242
|
+
"Measurement",
|
|
243
|
+
"PerformanceFeedback",
|
|
244
|
+
# Status enums
|
|
245
|
+
"MediaBuyStatus",
|
|
246
|
+
"PackageStatus",
|
|
247
|
+
# Pricing types
|
|
248
|
+
"PricingOption",
|
|
249
|
+
"PricingModel",
|
|
250
|
+
# Delivery types
|
|
251
|
+
"DeliveryType",
|
|
252
|
+
"StartTiming",
|
|
253
|
+
# Channel types
|
|
254
|
+
"Channels",
|
|
255
|
+
"StandardFormatIds",
|
|
256
|
+
# Protocol types
|
|
257
|
+
"WebhookPayload",
|
|
258
|
+
"ProtocolEnvelope",
|
|
259
|
+
"Response",
|
|
260
|
+
"PromotedProducts",
|
|
261
|
+
"PushNotificationConfig",
|
|
262
|
+
"ReportingCapabilities",
|
|
263
|
+
# Deployment types
|
|
264
|
+
"Destination",
|
|
265
|
+
"Deployment",
|
|
266
|
+
"PlatformDestination",
|
|
267
|
+
"AgentDestination",
|
|
268
|
+
"PlatformDeployment",
|
|
269
|
+
"AgentDeployment",
|
|
270
|
+
# Sub-asset types
|
|
271
|
+
"MediaSubAsset",
|
|
272
|
+
"SubAsset",
|
|
273
|
+
"TextSubAsset",
|
|
274
|
+
# Asset delivery types (VAST/DAAST)
|
|
275
|
+
"VastAsset",
|
|
276
|
+
"UrlVastAsset",
|
|
277
|
+
"InlineVastAsset",
|
|
278
|
+
"DaastAsset",
|
|
279
|
+
"UrlDaastAsset",
|
|
280
|
+
"InlineDaastAsset",
|
|
281
|
+
# Preview render types
|
|
282
|
+
"PreviewRender",
|
|
283
|
+
"UrlPreviewRender",
|
|
284
|
+
"HtmlPreviewRender",
|
|
285
|
+
"BothPreviewRender",
|
|
286
|
+
# Task types
|
|
287
|
+
"TaskType",
|
|
288
|
+
"GeneratedTaskStatus",
|
|
96
289
|
]
|
adcp/client.py
CHANGED
|
@@ -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(
|
|
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(
|
|
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
|
-
|
|
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
|
|
adcp/protocols/base.py
CHANGED
|
@@ -30,15 +30,18 @@ class ProtocolAdapter(ABC):
|
|
|
30
30
|
# Helper methods for response parsing
|
|
31
31
|
# ========================================================================
|
|
32
32
|
|
|
33
|
-
def _parse_response(
|
|
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
|
adcp/testing/__init__.py
ADDED
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
"""Test helpers for AdCP client library.
|
|
2
|
+
|
|
3
|
+
Provides pre-configured test agents for examples and quick testing.
|
|
4
|
+
"""
|
|
5
|
+
|
|
6
|
+
from __future__ import annotations
|
|
7
|
+
|
|
8
|
+
from adcp.testing.test_helpers import (
|
|
9
|
+
CREATIVE_AGENT_CONFIG,
|
|
10
|
+
TEST_AGENT_A2A_CONFIG,
|
|
11
|
+
TEST_AGENT_A2A_NO_AUTH_CONFIG,
|
|
12
|
+
TEST_AGENT_MCP_CONFIG,
|
|
13
|
+
TEST_AGENT_MCP_NO_AUTH_CONFIG,
|
|
14
|
+
TEST_AGENT_TOKEN,
|
|
15
|
+
create_test_agent,
|
|
16
|
+
creative_agent,
|
|
17
|
+
test_agent,
|
|
18
|
+
test_agent_a2a,
|
|
19
|
+
test_agent_a2a_no_auth,
|
|
20
|
+
test_agent_client,
|
|
21
|
+
test_agent_no_auth,
|
|
22
|
+
)
|
|
23
|
+
|
|
24
|
+
__all__ = [
|
|
25
|
+
"test_agent",
|
|
26
|
+
"test_agent_a2a",
|
|
27
|
+
"test_agent_no_auth",
|
|
28
|
+
"test_agent_a2a_no_auth",
|
|
29
|
+
"creative_agent",
|
|
30
|
+
"test_agent_client",
|
|
31
|
+
"create_test_agent",
|
|
32
|
+
"TEST_AGENT_TOKEN",
|
|
33
|
+
"TEST_AGENT_MCP_CONFIG",
|
|
34
|
+
"TEST_AGENT_A2A_CONFIG",
|
|
35
|
+
"TEST_AGENT_MCP_NO_AUTH_CONFIG",
|
|
36
|
+
"TEST_AGENT_A2A_NO_AUTH_CONFIG",
|
|
37
|
+
"CREATIVE_AGENT_CONFIG",
|
|
38
|
+
]
|
|
@@ -0,0 +1,311 @@
|
|
|
1
|
+
"""Test agent helpers for easy examples and quick testing.
|
|
2
|
+
|
|
3
|
+
These provide pre-configured access to AdCP's public test agent.
|
|
4
|
+
"""
|
|
5
|
+
|
|
6
|
+
from __future__ import annotations
|
|
7
|
+
|
|
8
|
+
from typing import Any
|
|
9
|
+
|
|
10
|
+
from adcp.client import ADCPClient, ADCPMultiAgentClient
|
|
11
|
+
from adcp.types.core import AgentConfig, Protocol
|
|
12
|
+
|
|
13
|
+
# Public test agent auth token
|
|
14
|
+
# This token is public and rate-limited, for testing/examples only.
|
|
15
|
+
TEST_AGENT_TOKEN = "1v8tAhASaUYYp4odoQ1PnMpdqNaMiTrCRqYo9OJp6IQ"
|
|
16
|
+
|
|
17
|
+
# Public test agent configuration - MCP protocol
|
|
18
|
+
TEST_AGENT_MCP_CONFIG = AgentConfig(
|
|
19
|
+
id="test-agent-mcp",
|
|
20
|
+
agent_uri="https://test-agent.adcontextprotocol.org/mcp/",
|
|
21
|
+
protocol=Protocol.MCP,
|
|
22
|
+
auth_token=TEST_AGENT_TOKEN,
|
|
23
|
+
)
|
|
24
|
+
|
|
25
|
+
# Public test agent configuration - A2A protocol
|
|
26
|
+
TEST_AGENT_A2A_CONFIG = AgentConfig(
|
|
27
|
+
id="test-agent-a2a",
|
|
28
|
+
agent_uri="https://test-agent.adcontextprotocol.org",
|
|
29
|
+
protocol=Protocol.A2A,
|
|
30
|
+
auth_token=TEST_AGENT_TOKEN,
|
|
31
|
+
)
|
|
32
|
+
|
|
33
|
+
# Public test agent configuration (no auth) - MCP protocol
|
|
34
|
+
TEST_AGENT_MCP_NO_AUTH_CONFIG = AgentConfig(
|
|
35
|
+
id="test-agent-mcp-no-auth",
|
|
36
|
+
agent_uri="https://test-agent.adcontextprotocol.org/mcp/",
|
|
37
|
+
protocol=Protocol.MCP,
|
|
38
|
+
)
|
|
39
|
+
|
|
40
|
+
# Public test agent configuration (no auth) - A2A protocol
|
|
41
|
+
TEST_AGENT_A2A_NO_AUTH_CONFIG = AgentConfig(
|
|
42
|
+
id="test-agent-a2a-no-auth",
|
|
43
|
+
agent_uri="https://test-agent.adcontextprotocol.org",
|
|
44
|
+
protocol=Protocol.A2A,
|
|
45
|
+
)
|
|
46
|
+
|
|
47
|
+
# Reference creative agent configuration - MCP protocol
|
|
48
|
+
# No authentication required for the reference creative agent
|
|
49
|
+
CREATIVE_AGENT_CONFIG = AgentConfig(
|
|
50
|
+
id="creative-agent",
|
|
51
|
+
agent_uri="https://creative.adcontextprotocol.org/mcp",
|
|
52
|
+
protocol=Protocol.MCP,
|
|
53
|
+
)
|
|
54
|
+
|
|
55
|
+
|
|
56
|
+
def _create_test_agent_client() -> ADCPClient:
|
|
57
|
+
"""Create pre-configured test agent client using MCP protocol.
|
|
58
|
+
|
|
59
|
+
Returns:
|
|
60
|
+
ADCPClient instance configured for the public test agent
|
|
61
|
+
|
|
62
|
+
Note:
|
|
63
|
+
This agent is rate-limited and intended for testing/examples only.
|
|
64
|
+
The auth token is public and may be rotated without notice.
|
|
65
|
+
DO NOT use in production applications.
|
|
66
|
+
"""
|
|
67
|
+
return ADCPClient(TEST_AGENT_MCP_CONFIG)
|
|
68
|
+
|
|
69
|
+
|
|
70
|
+
def _create_test_agent_a2a_client() -> ADCPClient:
|
|
71
|
+
"""Create pre-configured test agent client using A2A protocol.
|
|
72
|
+
|
|
73
|
+
Returns:
|
|
74
|
+
ADCPClient instance configured for the public test agent
|
|
75
|
+
|
|
76
|
+
Note:
|
|
77
|
+
This agent is rate-limited and intended for testing/examples only.
|
|
78
|
+
The auth token is public and may be rotated without notice.
|
|
79
|
+
DO NOT use in production applications.
|
|
80
|
+
"""
|
|
81
|
+
return ADCPClient(TEST_AGENT_A2A_CONFIG)
|
|
82
|
+
|
|
83
|
+
|
|
84
|
+
def _create_test_agent_no_auth_client() -> ADCPClient:
|
|
85
|
+
"""Create pre-configured test agent client (no auth) using MCP protocol.
|
|
86
|
+
|
|
87
|
+
Returns:
|
|
88
|
+
ADCPClient instance configured for the public test agent without authentication
|
|
89
|
+
|
|
90
|
+
Note:
|
|
91
|
+
This agent is rate-limited and intended for testing scenarios where no auth is provided.
|
|
92
|
+
Useful for testing behavior differences between authenticated and unauthenticated requests.
|
|
93
|
+
DO NOT use in production applications.
|
|
94
|
+
"""
|
|
95
|
+
return ADCPClient(TEST_AGENT_MCP_NO_AUTH_CONFIG)
|
|
96
|
+
|
|
97
|
+
|
|
98
|
+
def _create_test_agent_a2a_no_auth_client() -> ADCPClient:
|
|
99
|
+
"""Create pre-configured test agent client (no auth) using A2A protocol.
|
|
100
|
+
|
|
101
|
+
Returns:
|
|
102
|
+
ADCPClient instance configured for the public test agent without authentication
|
|
103
|
+
|
|
104
|
+
Note:
|
|
105
|
+
This agent is rate-limited and intended for testing scenarios where no auth is provided.
|
|
106
|
+
Useful for testing behavior differences between authenticated and unauthenticated requests.
|
|
107
|
+
DO NOT use in production applications.
|
|
108
|
+
"""
|
|
109
|
+
return ADCPClient(TEST_AGENT_A2A_NO_AUTH_CONFIG)
|
|
110
|
+
|
|
111
|
+
|
|
112
|
+
def _create_creative_agent_client() -> ADCPClient:
|
|
113
|
+
"""Create pre-configured creative agent client.
|
|
114
|
+
|
|
115
|
+
Returns:
|
|
116
|
+
ADCPClient instance configured for the reference creative agent
|
|
117
|
+
|
|
118
|
+
Note:
|
|
119
|
+
The reference creative agent is public and requires no authentication.
|
|
120
|
+
It provides creative preview functionality for testing and examples.
|
|
121
|
+
"""
|
|
122
|
+
return ADCPClient(CREATIVE_AGENT_CONFIG)
|
|
123
|
+
|
|
124
|
+
|
|
125
|
+
def _create_test_multi_agent_client() -> ADCPMultiAgentClient:
|
|
126
|
+
"""Create multi-agent client with both test agents configured.
|
|
127
|
+
|
|
128
|
+
Returns:
|
|
129
|
+
ADCPMultiAgentClient with both MCP and A2A test agents
|
|
130
|
+
|
|
131
|
+
Note:
|
|
132
|
+
This client is rate-limited and intended for testing/examples only.
|
|
133
|
+
DO NOT use in production applications.
|
|
134
|
+
"""
|
|
135
|
+
return ADCPMultiAgentClient([TEST_AGENT_MCP_CONFIG, TEST_AGENT_A2A_CONFIG])
|
|
136
|
+
|
|
137
|
+
|
|
138
|
+
# Pre-configured test agent client using MCP protocol.
|
|
139
|
+
# Ready to use for examples, documentation, and quick testing.
|
|
140
|
+
#
|
|
141
|
+
# Example:
|
|
142
|
+
# ```python
|
|
143
|
+
# from adcp.testing import test_agent
|
|
144
|
+
#
|
|
145
|
+
# # Simple get_products call
|
|
146
|
+
# result = await test_agent.get_products(
|
|
147
|
+
# GetProductsRequest(
|
|
148
|
+
# brief="Coffee subscription service for busy professionals",
|
|
149
|
+
# promoted_offering="Premium monthly coffee deliveries"
|
|
150
|
+
# )
|
|
151
|
+
# )
|
|
152
|
+
#
|
|
153
|
+
# if result.success:
|
|
154
|
+
# print(f"Found {len(result.data.products)} products")
|
|
155
|
+
# ```
|
|
156
|
+
#
|
|
157
|
+
# Note:
|
|
158
|
+
# This agent is rate-limited and intended for testing/examples only.
|
|
159
|
+
# The auth token is public and may be rotated without notice.
|
|
160
|
+
# DO NOT use in production applications.
|
|
161
|
+
test_agent: ADCPClient = _create_test_agent_client()
|
|
162
|
+
|
|
163
|
+
# Pre-configured test agent client using A2A protocol.
|
|
164
|
+
# Identical functionality to test_agent but uses A2A instead of MCP.
|
|
165
|
+
#
|
|
166
|
+
# Example:
|
|
167
|
+
# ```python
|
|
168
|
+
# from adcp.testing import test_agent_a2a
|
|
169
|
+
#
|
|
170
|
+
# result = await test_agent_a2a.get_products(
|
|
171
|
+
# GetProductsRequest(
|
|
172
|
+
# brief="Sustainable fashion brands",
|
|
173
|
+
# promoted_offering="Eco-friendly clothing"
|
|
174
|
+
# )
|
|
175
|
+
# )
|
|
176
|
+
# ```
|
|
177
|
+
#
|
|
178
|
+
# Note:
|
|
179
|
+
# This agent is rate-limited and intended for testing/examples only.
|
|
180
|
+
# The auth token is public and may be rotated without notice.
|
|
181
|
+
# DO NOT use in production applications.
|
|
182
|
+
test_agent_a2a: ADCPClient = _create_test_agent_a2a_client()
|
|
183
|
+
|
|
184
|
+
# Pre-configured test agent client (no auth) using MCP protocol.
|
|
185
|
+
# Useful for testing scenarios where authentication is not provided,
|
|
186
|
+
# such as testing how agents handle unauthenticated requests or
|
|
187
|
+
# comparing behavior between authenticated and unauthenticated calls.
|
|
188
|
+
#
|
|
189
|
+
# Example:
|
|
190
|
+
# ```python
|
|
191
|
+
# from adcp.testing import test_agent_no_auth
|
|
192
|
+
#
|
|
193
|
+
# # Test behavior without authentication
|
|
194
|
+
# result = await test_agent_no_auth.get_products(
|
|
195
|
+
# GetProductsRequest(
|
|
196
|
+
# brief="Coffee subscription service",
|
|
197
|
+
# promoted_offering="Premium monthly coffee"
|
|
198
|
+
# )
|
|
199
|
+
# )
|
|
200
|
+
# ```
|
|
201
|
+
#
|
|
202
|
+
# Note:
|
|
203
|
+
# This agent is rate-limited and intended for testing/examples only.
|
|
204
|
+
# DO NOT use in production applications.
|
|
205
|
+
test_agent_no_auth: ADCPClient = _create_test_agent_no_auth_client()
|
|
206
|
+
|
|
207
|
+
# Pre-configured test agent client (no auth) using A2A protocol.
|
|
208
|
+
# Identical functionality to test_agent_no_auth but uses A2A instead of MCP.
|
|
209
|
+
#
|
|
210
|
+
# Example:
|
|
211
|
+
# ```python
|
|
212
|
+
# from adcp.testing import test_agent_a2a_no_auth
|
|
213
|
+
#
|
|
214
|
+
# # Test A2A behavior without authentication
|
|
215
|
+
# result = await test_agent_a2a_no_auth.get_products(
|
|
216
|
+
# GetProductsRequest(
|
|
217
|
+
# brief="Sustainable fashion brands",
|
|
218
|
+
# promoted_offering="Eco-friendly clothing"
|
|
219
|
+
# )
|
|
220
|
+
# )
|
|
221
|
+
# ```
|
|
222
|
+
#
|
|
223
|
+
# Note:
|
|
224
|
+
# This agent is rate-limited and intended for testing/examples only.
|
|
225
|
+
# DO NOT use in production applications.
|
|
226
|
+
test_agent_a2a_no_auth: ADCPClient = _create_test_agent_a2a_no_auth_client()
|
|
227
|
+
|
|
228
|
+
# Pre-configured reference creative agent.
|
|
229
|
+
# Provides creative preview functionality without authentication.
|
|
230
|
+
#
|
|
231
|
+
# Example:
|
|
232
|
+
# ```python
|
|
233
|
+
# from adcp.testing import creative_agent
|
|
234
|
+
# from adcp.types.generated import PreviewCreativeRequest
|
|
235
|
+
#
|
|
236
|
+
# result = await creative_agent.preview_creative(
|
|
237
|
+
# PreviewCreativeRequest(
|
|
238
|
+
# manifest={
|
|
239
|
+
# "format_id": "banner_300x250",
|
|
240
|
+
# "assets": {...}
|
|
241
|
+
# }
|
|
242
|
+
# )
|
|
243
|
+
# )
|
|
244
|
+
# ```
|
|
245
|
+
#
|
|
246
|
+
# Note:
|
|
247
|
+
# The reference creative agent is public and requires no authentication.
|
|
248
|
+
# Perfect for testing creative rendering and preview functionality.
|
|
249
|
+
creative_agent: ADCPClient = _create_creative_agent_client()
|
|
250
|
+
|
|
251
|
+
# Multi-agent client with both test agents configured.
|
|
252
|
+
# Useful for testing multi-agent patterns and protocol comparisons.
|
|
253
|
+
#
|
|
254
|
+
# Example:
|
|
255
|
+
# ```python
|
|
256
|
+
# from adcp.testing import test_agent_client
|
|
257
|
+
#
|
|
258
|
+
# # Access individual agents
|
|
259
|
+
# mcp_agent = test_agent_client.agent("test-agent-mcp")
|
|
260
|
+
# a2a_agent = test_agent_client.agent("test-agent-a2a")
|
|
261
|
+
#
|
|
262
|
+
# # Use for parallel operations
|
|
263
|
+
# results = await test_agent_client.get_products(
|
|
264
|
+
# GetProductsRequest(
|
|
265
|
+
# brief="Premium coffee brands",
|
|
266
|
+
# promoted_offering="Artisan coffee"
|
|
267
|
+
# )
|
|
268
|
+
# )
|
|
269
|
+
# ```
|
|
270
|
+
#
|
|
271
|
+
# Note:
|
|
272
|
+
# This client is rate-limited and intended for testing/examples only.
|
|
273
|
+
# DO NOT use in production applications.
|
|
274
|
+
test_agent_client: ADCPMultiAgentClient = _create_test_multi_agent_client()
|
|
275
|
+
|
|
276
|
+
|
|
277
|
+
def create_test_agent(**overrides: Any) -> AgentConfig:
|
|
278
|
+
"""Create a custom test agent configuration.
|
|
279
|
+
|
|
280
|
+
Useful when you need to modify the default test agent setup.
|
|
281
|
+
|
|
282
|
+
Args:
|
|
283
|
+
**overrides: Keyword arguments to override default config values
|
|
284
|
+
|
|
285
|
+
Returns:
|
|
286
|
+
Complete agent configuration
|
|
287
|
+
|
|
288
|
+
Example:
|
|
289
|
+
```python
|
|
290
|
+
from adcp.testing import create_test_agent
|
|
291
|
+
from adcp.client import ADCPClient
|
|
292
|
+
|
|
293
|
+
# Use default test agent with custom ID
|
|
294
|
+
config = create_test_agent(id="my-test-agent")
|
|
295
|
+
client = ADCPClient(config)
|
|
296
|
+
```
|
|
297
|
+
|
|
298
|
+
Example:
|
|
299
|
+
```python
|
|
300
|
+
# Use A2A protocol instead of MCP
|
|
301
|
+
from adcp.types.core import Protocol
|
|
302
|
+
|
|
303
|
+
config = create_test_agent(
|
|
304
|
+
protocol=Protocol.A2A,
|
|
305
|
+
agent_uri="https://test-agent.adcontextprotocol.org"
|
|
306
|
+
)
|
|
307
|
+
```
|
|
308
|
+
"""
|
|
309
|
+
base_config = TEST_AGENT_MCP_CONFIG.model_dump()
|
|
310
|
+
base_config.update(overrides)
|
|
311
|
+
return AgentConfig(**base_config)
|