adcp 1.6.1__py3-none-any.whl → 2.1.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 +110 -189
- adcp/adagents.py +11 -12
- adcp/client.py +16 -11
- adcp/py.typed +0 -0
- adcp/types/aliases.py +209 -0
- adcp/types/generated.py +540 -1134
- adcp/types/generated_poc/__init__.py +3 -0
- adcp/types/generated_poc/activate_signal_request.py +34 -0
- adcp/types/generated_poc/activate_signal_response.py +57 -0
- adcp/types/generated_poc/activation_key.py +30 -0
- adcp/types/generated_poc/adagents.py +266 -0
- adcp/types/generated_poc/asset_type.py +100 -0
- adcp/types/generated_poc/audio_asset.py +26 -0
- adcp/types/generated_poc/brand_manifest.py +260 -0
- adcp/types/generated_poc/brand_manifest_ref.py +361 -0
- adcp/types/generated_poc/build_creative_request.py +43 -0
- adcp/types/generated_poc/build_creative_response.py +57 -0
- adcp/types/generated_poc/channels.py +19 -0
- adcp/types/generated_poc/cpc_option.py +39 -0
- adcp/types/generated_poc/cpcv_option.py +41 -0
- adcp/types/generated_poc/cpm_auction_option.py +54 -0
- adcp/types/generated_poc/cpm_fixed_option.py +39 -0
- adcp/types/generated_poc/cpp_option.py +60 -0
- adcp/types/generated_poc/cpv_option.py +73 -0
- adcp/types/generated_poc/create_media_buy_request.py +96 -0
- adcp/types/generated_poc/create_media_buy_response.py +66 -0
- adcp/types/generated_poc/creative_asset.py +83 -0
- adcp/types/generated_poc/creative_assignment.py +27 -0
- adcp/types/generated_poc/creative_manifest.py +61 -0
- adcp/types/generated_poc/creative_policy.py +34 -0
- adcp/types/generated_poc/creative_status.py +14 -0
- adcp/types/generated_poc/css_asset.py +20 -0
- adcp/types/generated_poc/daast_asset.py +76 -0
- adcp/types/generated_poc/delivery_metrics.py +111 -0
- adcp/types/generated_poc/delivery_type.py +12 -0
- adcp/types/generated_poc/deployment.py +78 -0
- adcp/types/generated_poc/destination.py +43 -0
- adcp/types/generated_poc/error.py +29 -0
- adcp/types/generated_poc/flat_rate_option.py +93 -0
- adcp/types/generated_poc/format.py +260 -0
- adcp/types/generated_poc/format_id.py +29 -0
- adcp/types/generated_poc/frequency_cap.py +19 -0
- adcp/types/generated_poc/frequency_cap_scope.py +16 -0
- adcp/types/generated_poc/get_media_buy_delivery_request.py +65 -0
- adcp/types/generated_poc/get_media_buy_delivery_response.py +220 -0
- adcp/types/generated_poc/get_products_request.py +83 -0
- adcp/types/generated_poc/get_products_response.py +29 -0
- adcp/types/generated_poc/get_signals_request.py +77 -0
- adcp/types/generated_poc/get_signals_response.py +65 -0
- adcp/types/generated_poc/html_asset.py +18 -0
- adcp/types/generated_poc/identifier_types.py +29 -0
- adcp/types/generated_poc/image_asset.py +23 -0
- adcp/types/generated_poc/index.py +17 -0
- adcp/types/generated_poc/javascript_asset.py +25 -0
- adcp/types/generated_poc/list_authorized_properties_request.py +39 -0
- adcp/types/generated_poc/list_authorized_properties_response.py +85 -0
- adcp/types/generated_poc/list_creative_formats_request.py +93 -0
- adcp/types/generated_poc/list_creative_formats_response.py +63 -0
- adcp/types/generated_poc/list_creatives_request.py +154 -0
- adcp/types/generated_poc/list_creatives_response.py +234 -0
- adcp/types/generated_poc/markdown_asset.py +43 -0
- adcp/types/generated_poc/measurement.py +40 -0
- adcp/types/generated_poc/media_buy.py +37 -0
- adcp/types/generated_poc/media_buy_status.py +14 -0
- adcp/types/generated_poc/pacing.py +13 -0
- adcp/types/generated_poc/package.py +61 -0
- adcp/types/generated_poc/package_request.py +61 -0
- adcp/types/generated_poc/package_status.py +14 -0
- adcp/types/generated_poc/performance_feedback.py +89 -0
- adcp/types/generated_poc/placement.py +37 -0
- adcp/types/generated_poc/preview_creative_request.py +163 -0
- adcp/types/generated_poc/preview_creative_response.py +175 -0
- adcp/types/generated_poc/preview_render.py +144 -0
- adcp/types/generated_poc/pricing_model.py +17 -0
- adcp/types/generated_poc/pricing_option.py +365 -0
- adcp/types/generated_poc/product.py +211 -0
- adcp/types/generated_poc/promoted_offerings.py +102 -0
- adcp/types/generated_poc/promoted_products.py +38 -0
- adcp/types/generated_poc/property.py +79 -0
- adcp/types/generated_poc/protocol_envelope.py +61 -0
- adcp/types/generated_poc/provide_performance_feedback_request.py +85 -0
- adcp/types/generated_poc/provide_performance_feedback_response.py +59 -0
- adcp/types/generated_poc/publisher_identifier_types.py +15 -0
- adcp/types/generated_poc/push_notification_config.py +55 -0
- adcp/types/generated_poc/reporting_capabilities.py +68 -0
- adcp/types/generated_poc/response.py +24 -0
- adcp/types/generated_poc/standard_format_ids.py +45 -0
- adcp/types/generated_poc/start_timing.py +13 -0
- adcp/types/generated_poc/sub_asset.py +55 -0
- adcp/types/generated_poc/sync_creatives_request.py +69 -0
- adcp/types/generated_poc/sync_creatives_response.py +117 -0
- adcp/types/generated_poc/targeting.py +53 -0
- adcp/types/generated_poc/task_status.py +19 -0
- adcp/types/generated_poc/task_type.py +15 -0
- adcp/types/generated_poc/tasks_get_request.py +29 -0
- adcp/types/generated_poc/tasks_get_response.py +112 -0
- adcp/types/generated_poc/tasks_list_request.py +121 -0
- adcp/types/generated_poc/tasks_list_response.py +122 -0
- adcp/types/generated_poc/text_asset.py +20 -0
- adcp/types/generated_poc/update_media_buy_request.py +160 -0
- adcp/types/generated_poc/update_media_buy_response.py +67 -0
- adcp/types/generated_poc/url_asset.py +33 -0
- adcp/types/generated_poc/vast_asset.py +86 -0
- adcp/types/generated_poc/vcpm_auction_option.py +57 -0
- adcp/types/generated_poc/vcpm_fixed_option.py +43 -0
- adcp/types/generated_poc/video_asset.py +28 -0
- adcp/types/generated_poc/webhook_asset.py +65 -0
- adcp/types/generated_poc/webhook_payload.py +102 -0
- adcp/utils/preview_cache.py +54 -41
- adcp/validation.py +172 -0
- {adcp-1.6.1.dist-info → adcp-2.1.0.dist-info}/METADATA +42 -3
- adcp-2.1.0.dist-info/RECORD +132 -0
- adcp/types/tasks.py +0 -511
- adcp-1.6.1.dist-info/RECORD +0 -28
- {adcp-1.6.1.dist-info → adcp-2.1.0.dist-info}/WHEEL +0 -0
- {adcp-1.6.1.dist-info → adcp-2.1.0.dist-info}/entry_points.txt +0 -0
- {adcp-1.6.1.dist-info → adcp-2.1.0.dist-info}/licenses/LICENSE +0 -0
- {adcp-1.6.1.dist-info → adcp-2.1.0.dist-info}/top_level.txt +0 -0
adcp/utils/preview_cache.py
CHANGED
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
"""Helper utilities for generating creative preview URLs for grid rendering."""
|
|
2
2
|
|
|
3
|
+
# mypy: disable-error-code="arg-type,attr-defined,call-arg,unused-ignore,union-attr"
|
|
4
|
+
|
|
3
5
|
from __future__ import annotations
|
|
4
6
|
|
|
5
7
|
import hashlib
|
|
@@ -65,7 +67,7 @@ class PreviewURLGenerator:
|
|
|
65
67
|
Returns:
|
|
66
68
|
Preview data with preview_url and metadata, or None if generation fails
|
|
67
69
|
"""
|
|
68
|
-
from adcp.types.generated import
|
|
70
|
+
from adcp.types.generated import PreviewCreativeRequest1
|
|
69
71
|
|
|
70
72
|
cache_key = _make_manifest_cache_key(format_id, manifest.model_dump(exclude_none=True))
|
|
71
73
|
|
|
@@ -73,31 +75,31 @@ class PreviewURLGenerator:
|
|
|
73
75
|
return self._preview_cache[cache_key]
|
|
74
76
|
|
|
75
77
|
try:
|
|
76
|
-
request =
|
|
78
|
+
request = PreviewCreativeRequest1(
|
|
79
|
+
request_type="single",
|
|
77
80
|
format_id=format_id,
|
|
78
81
|
creative_manifest=manifest,
|
|
79
|
-
inputs=None,
|
|
80
|
-
template_id=None,
|
|
81
|
-
context=None
|
|
82
82
|
)
|
|
83
83
|
result = await self.creative_agent_client.preview_creative(request)
|
|
84
84
|
|
|
85
85
|
if result.success and result.data and result.data.previews:
|
|
86
86
|
preview = result.data.previews[0]
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
87
|
+
first_render = preview.renders[0] if preview.renders else None
|
|
88
|
+
|
|
89
|
+
if first_render:
|
|
90
|
+
has_url = hasattr(first_render, "preview_url")
|
|
91
|
+
preview_url = str(first_render.preview_url) if has_url else None
|
|
92
|
+
preview_data = {
|
|
93
|
+
"preview_id": preview.preview_id,
|
|
94
|
+
"preview_url": preview_url,
|
|
95
|
+
"preview_html": getattr(first_render, "preview_html", None),
|
|
96
|
+
"render_id": first_render.render_id,
|
|
97
|
+
"input": preview.input.model_dump(),
|
|
98
|
+
"expires_at": str(result.data.expires_at),
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
self._preview_cache[cache_key] = preview_data
|
|
102
|
+
return preview_data
|
|
101
103
|
|
|
102
104
|
except Exception as e:
|
|
103
105
|
logger.warning(f"Failed to generate preview for format {format_id}: {e}", exc_info=True)
|
|
@@ -142,15 +144,13 @@ class PreviewURLGenerator:
|
|
|
142
144
|
results[idx] = self._preview_cache[cache_key]
|
|
143
145
|
else:
|
|
144
146
|
uncached_indices.append(idx)
|
|
145
|
-
fid_dict = (
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
147
|
+
fid_dict = format_id.model_dump() if hasattr(format_id, "model_dump") else format_id
|
|
148
|
+
uncached_requests.append(
|
|
149
|
+
{
|
|
150
|
+
"format_id": fid_dict,
|
|
151
|
+
"creative_manifest": manifest.model_dump(exclude_none=True),
|
|
152
|
+
}
|
|
149
153
|
)
|
|
150
|
-
uncached_requests.append({
|
|
151
|
-
"format_id": fid_dict,
|
|
152
|
-
"creative_manifest": manifest.model_dump(exclude_none=True),
|
|
153
|
-
})
|
|
154
154
|
|
|
155
155
|
# If everything was cached, return early
|
|
156
156
|
if not uncached_requests:
|
|
@@ -376,9 +376,7 @@ async def add_preview_urls_to_products(
|
|
|
376
376
|
|
|
377
377
|
format_tasks = [process_format(fid) for fid in product.format_ids]
|
|
378
378
|
format_results = await asyncio.gather(*format_tasks)
|
|
379
|
-
format_previews = {
|
|
380
|
-
fid: data for fid, data in format_results if data is not None
|
|
381
|
-
}
|
|
379
|
+
format_previews = {fid: data for fid, data in format_results if data is not None}
|
|
382
380
|
|
|
383
381
|
if format_previews:
|
|
384
382
|
product_dict["format_previews"] = format_previews
|
|
@@ -408,10 +406,16 @@ def _create_sample_manifest_for_format(fmt: Format) -> CreativeManifest | None:
|
|
|
408
406
|
for asset in fmt.assets_required:
|
|
409
407
|
if isinstance(asset, dict):
|
|
410
408
|
asset_id = asset.get("asset_id")
|
|
411
|
-
asset_type = asset.get("
|
|
409
|
+
asset_type = asset.get("asset_type")
|
|
412
410
|
|
|
413
411
|
if asset_id:
|
|
414
412
|
assets[asset_id] = _create_sample_asset(asset_type)
|
|
413
|
+
else:
|
|
414
|
+
# Handle Pydantic model
|
|
415
|
+
asset_id = asset.asset_id
|
|
416
|
+
has_value = hasattr(asset.asset_type, "value")
|
|
417
|
+
asset_type = asset.asset_type.value if has_value else str(asset.asset_type)
|
|
418
|
+
assets[asset_id] = _create_sample_asset(asset_type)
|
|
415
419
|
|
|
416
420
|
if not assets:
|
|
417
421
|
return None
|
|
@@ -432,11 +436,11 @@ def _create_sample_manifest_for_format_id(
|
|
|
432
436
|
Returns:
|
|
433
437
|
Sample CreativeManifest with placeholder assets
|
|
434
438
|
"""
|
|
435
|
-
from adcp.types.generated import CreativeManifest
|
|
439
|
+
from adcp.types.generated import CreativeManifest, ImageAsset, UrlAsset
|
|
436
440
|
|
|
437
441
|
assets = {
|
|
438
|
-
"primary_asset": "https://example.com/sample-image.jpg",
|
|
439
|
-
"clickthrough_url": "https://example.com",
|
|
442
|
+
"primary_asset": ImageAsset(url="https://example.com/sample-image.jpg"),
|
|
443
|
+
"clickthrough_url": UrlAsset(url="https://example.com"),
|
|
440
444
|
}
|
|
441
445
|
|
|
442
446
|
return CreativeManifest(format_id=format_id, promoted_offering=product.name, assets=assets)
|
|
@@ -450,17 +454,26 @@ def _create_sample_asset(asset_type: str | None) -> Any:
|
|
|
450
454
|
asset_type: Type of asset (image, video, text, url, etc.)
|
|
451
455
|
|
|
452
456
|
Returns:
|
|
453
|
-
Sample asset
|
|
457
|
+
Sample asset object (Pydantic model)
|
|
454
458
|
"""
|
|
459
|
+
from adcp.types.generated import (
|
|
460
|
+
HtmlAsset,
|
|
461
|
+
ImageAsset,
|
|
462
|
+
TextAsset,
|
|
463
|
+
UrlAsset,
|
|
464
|
+
VideoAsset,
|
|
465
|
+
)
|
|
466
|
+
|
|
455
467
|
if asset_type == "image":
|
|
456
|
-
return "https://via.placeholder.com/300x250.png"
|
|
468
|
+
return ImageAsset(url="https://via.placeholder.com/300x250.png")
|
|
457
469
|
elif asset_type == "video":
|
|
458
|
-
return "https://example.com/sample-video.mp4"
|
|
470
|
+
return VideoAsset(url="https://example.com/sample-video.mp4")
|
|
459
471
|
elif asset_type == "text":
|
|
460
|
-
return "Sample advertising text"
|
|
472
|
+
return TextAsset(content="Sample advertising text")
|
|
461
473
|
elif asset_type == "url":
|
|
462
|
-
return "https://example.com"
|
|
474
|
+
return UrlAsset(url="https://example.com")
|
|
463
475
|
elif asset_type == "html":
|
|
464
|
-
return "<div>Sample HTML</div>"
|
|
476
|
+
return HtmlAsset(content="<div>Sample HTML</div>")
|
|
465
477
|
else:
|
|
466
|
-
|
|
478
|
+
# Default to URL asset for unknown types
|
|
479
|
+
return UrlAsset(url="https://example.com/sample-asset")
|
adcp/validation.py
ADDED
|
@@ -0,0 +1,172 @@
|
|
|
1
|
+
"""Runtime validation for AdCP data structures.
|
|
2
|
+
|
|
3
|
+
This module provides runtime validation that complements schema validation:
|
|
4
|
+
|
|
5
|
+
1. **For adagents.json (v2.4.0+)**: Validates discriminated union structure
|
|
6
|
+
- Checks for proper authorization_type discriminator
|
|
7
|
+
- Validates publisher_properties selection_type discriminator
|
|
8
|
+
- These constraints ARE enforced in upstream schemas via oneOf + discriminators
|
|
9
|
+
|
|
10
|
+
2. **For product.json**: Validates mutual exclusivity constraints
|
|
11
|
+
- publisher_properties must have either property_ids OR property_tags
|
|
12
|
+
- These constraints are NOT yet enforced in upstream schemas (pending fix)
|
|
13
|
+
|
|
14
|
+
Note: When using Pydantic models directly, discriminated union validation happens
|
|
15
|
+
automatically during model construction. This module is for validating raw dict data
|
|
16
|
+
before Pydantic parsing (e.g., in fetch_adagents()).
|
|
17
|
+
"""
|
|
18
|
+
|
|
19
|
+
from __future__ import annotations
|
|
20
|
+
|
|
21
|
+
from typing import Any
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
class ValidationError(ValueError):
|
|
25
|
+
"""Raised when runtime validation fails."""
|
|
26
|
+
|
|
27
|
+
pass
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
def validate_publisher_properties_item(item: dict[str, Any]) -> None:
|
|
31
|
+
"""Validate publisher_properties item discriminated union.
|
|
32
|
+
|
|
33
|
+
AdCP v2.4.0+ uses discriminated unions with selection_type discriminator:
|
|
34
|
+
- selection_type: "by_id" requires property_ids
|
|
35
|
+
- selection_type: "by_tag" requires property_tags
|
|
36
|
+
|
|
37
|
+
For backward compatibility, also validates the old mutual exclusivity constraint.
|
|
38
|
+
|
|
39
|
+
Args:
|
|
40
|
+
item: A single item from publisher_properties array
|
|
41
|
+
|
|
42
|
+
Raises:
|
|
43
|
+
ValidationError: If discriminator or field constraints are violated
|
|
44
|
+
"""
|
|
45
|
+
selection_type = item.get("selection_type")
|
|
46
|
+
has_property_ids = "property_ids" in item and item["property_ids"] is not None
|
|
47
|
+
has_property_tags = "property_tags" in item and item["property_tags"] is not None
|
|
48
|
+
|
|
49
|
+
# If selection_type discriminator is present, validate discriminated union
|
|
50
|
+
if selection_type:
|
|
51
|
+
if selection_type == "by_id" and not has_property_ids:
|
|
52
|
+
raise ValidationError(
|
|
53
|
+
"publisher_properties item with selection_type='by_id' must have property_ids"
|
|
54
|
+
)
|
|
55
|
+
elif selection_type == "by_tag" and not has_property_tags:
|
|
56
|
+
raise ValidationError(
|
|
57
|
+
"publisher_properties item with selection_type='by_tag' must have property_tags"
|
|
58
|
+
)
|
|
59
|
+
elif selection_type not in ("by_id", "by_tag"):
|
|
60
|
+
raise ValidationError(
|
|
61
|
+
f"publisher_properties item has invalid selection_type: {selection_type}"
|
|
62
|
+
)
|
|
63
|
+
|
|
64
|
+
# Validate mutual exclusivity (for both old and new formats)
|
|
65
|
+
if has_property_ids and has_property_tags:
|
|
66
|
+
raise ValidationError(
|
|
67
|
+
"publisher_properties item cannot have both property_ids and property_tags. "
|
|
68
|
+
"These fields are mutually exclusive."
|
|
69
|
+
)
|
|
70
|
+
|
|
71
|
+
if not has_property_ids and not has_property_tags:
|
|
72
|
+
raise ValidationError(
|
|
73
|
+
"publisher_properties item must have either property_ids or property_tags. "
|
|
74
|
+
"At least one is required."
|
|
75
|
+
)
|
|
76
|
+
|
|
77
|
+
|
|
78
|
+
def validate_agent_authorization(agent: dict[str, Any]) -> None:
|
|
79
|
+
"""Validate agent authorization discriminated union.
|
|
80
|
+
|
|
81
|
+
AdCP v2.4.0+ uses discriminated unions with authorization_type discriminator:
|
|
82
|
+
- authorization_type: "property_ids" requires property_ids
|
|
83
|
+
- authorization_type: "property_tags" requires property_tags
|
|
84
|
+
- authorization_type: "inline_properties" requires properties
|
|
85
|
+
- authorization_type: "publisher_properties" requires publisher_properties
|
|
86
|
+
|
|
87
|
+
For backward compatibility, also validates the old mutual exclusivity constraint.
|
|
88
|
+
|
|
89
|
+
Args:
|
|
90
|
+
agent: An agent dict from adagents.json
|
|
91
|
+
|
|
92
|
+
Raises:
|
|
93
|
+
ValidationError: If discriminator or field constraints are violated
|
|
94
|
+
"""
|
|
95
|
+
authorization_type = agent.get("authorization_type")
|
|
96
|
+
auth_fields = ["properties", "property_ids", "property_tags", "publisher_properties"]
|
|
97
|
+
present_fields = [field for field in auth_fields if field in agent and agent[field] is not None]
|
|
98
|
+
|
|
99
|
+
# If authorization_type discriminator is present, validate discriminated union
|
|
100
|
+
if authorization_type:
|
|
101
|
+
if authorization_type == "property_ids" and "property_ids" not in present_fields:
|
|
102
|
+
raise ValidationError(
|
|
103
|
+
"Agent with authorization_type='property_ids' must have property_ids"
|
|
104
|
+
)
|
|
105
|
+
elif authorization_type == "property_tags" and "property_tags" not in present_fields:
|
|
106
|
+
raise ValidationError(
|
|
107
|
+
"Agent with authorization_type='property_tags' must have property_tags"
|
|
108
|
+
)
|
|
109
|
+
elif authorization_type == "inline_properties" and "properties" not in present_fields:
|
|
110
|
+
raise ValidationError(
|
|
111
|
+
"Agent with authorization_type='inline_properties' must have properties"
|
|
112
|
+
)
|
|
113
|
+
elif (
|
|
114
|
+
authorization_type == "publisher_properties"
|
|
115
|
+
and "publisher_properties" not in present_fields
|
|
116
|
+
):
|
|
117
|
+
raise ValidationError(
|
|
118
|
+
"Agent with authorization_type='publisher_properties' "
|
|
119
|
+
"must have publisher_properties"
|
|
120
|
+
)
|
|
121
|
+
elif authorization_type not in (
|
|
122
|
+
"property_ids",
|
|
123
|
+
"property_tags",
|
|
124
|
+
"inline_properties",
|
|
125
|
+
"publisher_properties",
|
|
126
|
+
):
|
|
127
|
+
raise ValidationError(f"Agent has invalid authorization_type: {authorization_type}")
|
|
128
|
+
|
|
129
|
+
# Validate mutual exclusivity (for both old and new formats)
|
|
130
|
+
if len(present_fields) > 1:
|
|
131
|
+
raise ValidationError(
|
|
132
|
+
f"Agent authorization cannot have multiple fields: {', '.join(present_fields)}. "
|
|
133
|
+
f"Only one of {', '.join(auth_fields)} is allowed."
|
|
134
|
+
)
|
|
135
|
+
|
|
136
|
+
if len(present_fields) == 0:
|
|
137
|
+
raise ValidationError(
|
|
138
|
+
f"Agent authorization must have exactly one of: {', '.join(auth_fields)}."
|
|
139
|
+
)
|
|
140
|
+
|
|
141
|
+
# If using publisher_properties, validate each item
|
|
142
|
+
if "publisher_properties" in present_fields:
|
|
143
|
+
for pub_prop in agent["publisher_properties"]:
|
|
144
|
+
validate_publisher_properties_item(pub_prop)
|
|
145
|
+
|
|
146
|
+
|
|
147
|
+
def validate_product(product: dict[str, Any]) -> None:
|
|
148
|
+
"""Validate a Product object.
|
|
149
|
+
|
|
150
|
+
Args:
|
|
151
|
+
product: Product dict
|
|
152
|
+
|
|
153
|
+
Raises:
|
|
154
|
+
ValidationError: If validation fails
|
|
155
|
+
"""
|
|
156
|
+
if "publisher_properties" in product and product["publisher_properties"]:
|
|
157
|
+
for item in product["publisher_properties"]:
|
|
158
|
+
validate_publisher_properties_item(item)
|
|
159
|
+
|
|
160
|
+
|
|
161
|
+
def validate_adagents(adagents: dict[str, Any]) -> None:
|
|
162
|
+
"""Validate an adagents.json structure.
|
|
163
|
+
|
|
164
|
+
Args:
|
|
165
|
+
adagents: The adagents.json dict
|
|
166
|
+
|
|
167
|
+
Raises:
|
|
168
|
+
ValidationError: If validation fails
|
|
169
|
+
"""
|
|
170
|
+
if "agents" in adagents:
|
|
171
|
+
for agent in adagents["agents"]:
|
|
172
|
+
validate_agent_authorization(agent)
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: adcp
|
|
3
|
-
Version: 1.
|
|
3
|
+
Version: 2.1.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
|
|
@@ -33,6 +33,8 @@ Requires-Dist: pytest-cov>=4.0.0; extra == "dev"
|
|
|
33
33
|
Requires-Dist: mypy>=1.0.0; extra == "dev"
|
|
34
34
|
Requires-Dist: black>=23.0.0; extra == "dev"
|
|
35
35
|
Requires-Dist: ruff>=0.1.0; extra == "dev"
|
|
36
|
+
Requires-Dist: datamodel-code-generator[http]>=0.35.0; extra == "dev"
|
|
37
|
+
Requires-Dist: email-validator>=2.0.0; extra == "dev"
|
|
36
38
|
Dynamic: license-file
|
|
37
39
|
|
|
38
40
|
# adcp - Python Client for Ad Context Protocol
|
|
@@ -92,7 +94,7 @@ print(products.products[0].name)
|
|
|
92
94
|
**Standard API** (`client.*`) - Recommended for production:
|
|
93
95
|
```python
|
|
94
96
|
from adcp.testing import test_agent
|
|
95
|
-
from adcp
|
|
97
|
+
from adcp import GetProductsRequest
|
|
96
98
|
|
|
97
99
|
# Explicit request objects and TaskResult wrapper
|
|
98
100
|
request = GetProductsRequest(brief='Coffee brands')
|
|
@@ -122,6 +124,8 @@ Pre-configured agents (all include `.simple` accessor):
|
|
|
122
124
|
|
|
123
125
|
See [examples/simple_api_demo.py](examples/simple_api_demo.py) for a complete comparison.
|
|
124
126
|
|
|
127
|
+
> **Tip**: Import types from the main `adcp` package (e.g., `from adcp import GetProductsRequest`) rather than `adcp.types.generated` for better API stability.
|
|
128
|
+
|
|
125
129
|
## Quick Start: Distributed Operations
|
|
126
130
|
|
|
127
131
|
For production use, configure your own agents:
|
|
@@ -185,7 +189,7 @@ from adcp.testing import (
|
|
|
185
189
|
test_agent_no_auth, test_agent_a2a_no_auth,
|
|
186
190
|
creative_agent, test_agent_client, create_test_agent
|
|
187
191
|
)
|
|
188
|
-
from adcp
|
|
192
|
+
from adcp import GetProductsRequest, PreviewCreativeRequest
|
|
189
193
|
|
|
190
194
|
# 1. Single agent with authentication (MCP)
|
|
191
195
|
result = await test_agent.get_products(
|
|
@@ -241,6 +245,7 @@ client = ADCPClient(config)
|
|
|
241
245
|
- **Auto-detection**: Automatically detect which protocol an agent uses
|
|
242
246
|
|
|
243
247
|
### Type Safety
|
|
248
|
+
|
|
244
249
|
Full type hints with Pydantic validation and auto-generated types from the AdCP spec:
|
|
245
250
|
|
|
246
251
|
```python
|
|
@@ -256,6 +261,40 @@ if result.success:
|
|
|
256
261
|
print(product.name, product.pricing_options) # Full IDE autocomplete!
|
|
257
262
|
```
|
|
258
263
|
|
|
264
|
+
#### Semantic Type Aliases
|
|
265
|
+
|
|
266
|
+
For discriminated union types (success/error responses), use semantic aliases for clearer code:
|
|
267
|
+
|
|
268
|
+
```python
|
|
269
|
+
from adcp import (
|
|
270
|
+
CreateMediaBuySuccessResponse, # Clear: this is the success case
|
|
271
|
+
CreateMediaBuyErrorResponse, # Clear: this is the error case
|
|
272
|
+
)
|
|
273
|
+
|
|
274
|
+
def handle_response(
|
|
275
|
+
response: CreateMediaBuySuccessResponse | CreateMediaBuyErrorResponse
|
|
276
|
+
) -> None:
|
|
277
|
+
if isinstance(response, CreateMediaBuySuccessResponse):
|
|
278
|
+
print(f"✅ Media buy created: {response.media_buy_id}")
|
|
279
|
+
else:
|
|
280
|
+
print(f"❌ Errors: {response.errors}")
|
|
281
|
+
```
|
|
282
|
+
|
|
283
|
+
**Available semantic aliases:**
|
|
284
|
+
- Response types: `*SuccessResponse` / `*ErrorResponse` (e.g., `CreateMediaBuySuccessResponse`)
|
|
285
|
+
- Request variants: `*FormatRequest` / `*ManifestRequest` (e.g., `PreviewCreativeFormatRequest`)
|
|
286
|
+
- Preview renders: `PreviewRenderImage` / `PreviewRenderHtml` / `PreviewRenderIframe`
|
|
287
|
+
- Activation keys: `PropertyIdActivationKey` / `PropertyTagActivationKey`
|
|
288
|
+
|
|
289
|
+
See `examples/type_aliases_demo.py` for more examples.
|
|
290
|
+
|
|
291
|
+
**Import guidelines:**
|
|
292
|
+
- ✅ **DO**: Import from main package: `from adcp import GetProductsRequest`
|
|
293
|
+
- ✅ **DO**: Use semantic aliases: `from adcp import CreateMediaBuySuccessResponse`
|
|
294
|
+
- ⚠️ **AVOID**: Import from internal modules: `from adcp.types.generated import CreateMediaBuyResponse1`
|
|
295
|
+
|
|
296
|
+
The main package exports provide a stable API while internal generated types may change.
|
|
297
|
+
|
|
259
298
|
### Multi-Agent Operations
|
|
260
299
|
Execute across multiple agents simultaneously:
|
|
261
300
|
|
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
adcp/__init__.py,sha256=lbYHt11mytsQ0zVHUqa2UKMGGc8uW0_6c55svUrN6So,6868
|
|
2
|
+
adcp/__main__.py,sha256=Avy_C71rruh2lOuojvuXDj09tkFOaek74nJ-dbx25Sw,12838
|
|
3
|
+
adcp/adagents.py,sha256=NjtK_3FmvikG4vlCGPxQwFYl-iOML09uIdtqT2lAWEA,17669
|
|
4
|
+
adcp/client.py,sha256=KFsNaHNYuapMLpjfqMbycDkEc147gEpxpwXzVuZ1y2o,28802
|
|
5
|
+
adcp/config.py,sha256=Vsy7ZPOI8G3fB_i5Nk-CHbC7wdasCUWuKlos0fwA0kY,2017
|
|
6
|
+
adcp/exceptions.py,sha256=1aZEWpaM92OxD2jl9yKsqJp5ReSWaj0S0DFhxChhLlA,6732
|
|
7
|
+
adcp/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
8
|
+
adcp/simple.py,sha256=FgPYWT32BNXkQz07r2x2gXgOmOikWLi88SzN5UIVSiU,10440
|
|
9
|
+
adcp/validation.py,sha256=NsTwTQbLmd1Z1bMcztR1llJB21ai1xuw5aVrca7LoE8,6793
|
|
10
|
+
adcp/protocols/__init__.py,sha256=6UFwACQ0QadBUzy17wUROHqsJDp8ztPW2jzyl53Zh_g,262
|
|
11
|
+
adcp/protocols/a2a.py,sha256=FHgc6G_eU2qD0vH7_RyS1eZvUFSb2j3-EsceoHPi384,12467
|
|
12
|
+
adcp/protocols/base.py,sha256=vBHD23Fzl_CCk_Gy9nvSbBYopcJlYkYyzoz-rhI8wHg,5214
|
|
13
|
+
adcp/protocols/mcp.py,sha256=d9uSpGd0BKvQ0JxztkfDvHwoDrDYhuiw5oivpYOAbmM,16647
|
|
14
|
+
adcp/testing/__init__.py,sha256=ZWp_floWjVZfy8RBG5v_FUXQ8YbN7xjXvVcX-_zl_HU,1416
|
|
15
|
+
adcp/testing/test_helpers.py,sha256=4n8fZYy1cVpjZpFW2SxBzpC8fmY-MBFrzY4tIPqe4rQ,10028
|
|
16
|
+
adcp/types/__init__.py,sha256=FXm4210pkzOIQQEgpe-EeLLd7mxofzEgKLGl1r8fj4o,465
|
|
17
|
+
adcp/types/aliases.py,sha256=U3-QMWcnif9BXjB6tmM3xFL2q0BiiDFtKgqw3Zixbzo,7561
|
|
18
|
+
adcp/types/base.py,sha256=QoEuVfI4yzefup0dc2KN11AcJTbcGxRep7xOw5hXfs8,837
|
|
19
|
+
adcp/types/core.py,sha256=RXkKCWCXS9BVJTNpe3Opm5O1I_LaQPMUuVwa-ipvS1Q,4839
|
|
20
|
+
adcp/types/generated.py,sha256=EGwfnyTr5bgLGRS0TAdsoipX__BPMEwPfxto8quPbYw,17218
|
|
21
|
+
adcp/types/generated_poc/__init__.py,sha256=d6d0uXG6VkArqJj_sd6XpUMDcHU6-ARk210TCDKeQD4,103
|
|
22
|
+
adcp/types/generated_poc/activate_signal_request.py,sha256=8zlkyPJampuGplIXKhPaLf_hgv5_cqGyHNVP8u5lyMs,1188
|
|
23
|
+
adcp/types/generated_poc/activate_signal_response.py,sha256=4R_MXLmzDaPARAlmSptaEqwzHfLiL6WgF5IYKDE0TBY,2015
|
|
24
|
+
adcp/types/generated_poc/activation_key.py,sha256=JFRWrPF4moOCm_Sfo12qORPTl3_gkWSuzbrSQyBgSRc,952
|
|
25
|
+
adcp/types/generated_poc/adagents.py,sha256=9nLxI7O8JVKuwEBmsllGNPI4D7YhXX_k2U67Tzku4Jg,8490
|
|
26
|
+
adcp/types/generated_poc/asset_type.py,sha256=bZhN1MEgPsK4YIuth-SybBm-OcqSqsEdmEeK273JJr4,3169
|
|
27
|
+
adcp/types/generated_poc/audio_asset.py,sha256=kFhVjowYVtgJVYcGVBSjQmj_jVMVfdY9tzDnSY649mA,795
|
|
28
|
+
adcp/types/generated_poc/brand_manifest.py,sha256=qQ6dpC2QQgzesRg6-kISaEoZi7MjlpxhJdKA6-MCP1U,9723
|
|
29
|
+
adcp/types/generated_poc/brand_manifest_ref.py,sha256=OfCcjNqgs2P6Zlgzpdk5y-hvWh71XCN67NIYXgaJmRY,15468
|
|
30
|
+
adcp/types/generated_poc/build_creative_request.py,sha256=KliEQyTg-66E-mUTL5fJFd8mzVAkS6P3EU2l1_KF_wI,1726
|
|
31
|
+
adcp/types/generated_poc/build_creative_response.py,sha256=T3wtqoPBGJZDQEucvHGgtlIfHRihsqL3n2tsSnbYaNI,1926
|
|
32
|
+
adcp/types/generated_poc/channels.py,sha256=YU9Q-jcthLFBLDW-vM6QVmzvtHghka9FwZGNVlM1-w8,386
|
|
33
|
+
adcp/types/generated_poc/cpc_option.py,sha256=7FRVzMjOciFBlUVyrNUHWZj15ZXr-_pPwaCcJsnPYQg,1168
|
|
34
|
+
adcp/types/generated_poc/cpcv_option.py,sha256=m8RQCA5nn6bEcjL64PZ3Vzt5fW3bnDFlwhEMvhIhBzI,1229
|
|
35
|
+
adcp/types/generated_poc/cpm_auction_option.py,sha256=_lD5RRE28yqnRFQKoAd8PWfYyrtp6UF2doPmFxRTwAY,1832
|
|
36
|
+
adcp/types/generated_poc/cpm_fixed_option.py,sha256=GgNFIAqg0FJHWTvHfEo8g8k-PaLKYwI5ep69_7wOkuI,1212
|
|
37
|
+
adcp/types/generated_poc/cpp_option.py,sha256=1_w6clFqWxrYOXN-ibJndcI-jSNOYZQOX_qLrpClPLU,1924
|
|
38
|
+
adcp/types/generated_poc/cpv_option.py,sha256=QU-RiZ27TgPDBLSeJs5uJ0TdHuayvIGkkAdkQcED5No,2028
|
|
39
|
+
adcp/types/generated_poc/create_media_buy_request.py,sha256=ImuhW7tcDi4O67do6WaqxlXHRxZm3ZUnkK_uHT0CMco,3533
|
|
40
|
+
adcp/types/generated_poc/create_media_buy_response.py,sha256=enfFSm4vYJdh75xLTu4SLGPX55_nAR9ZmBb_l-NSbc8,2469
|
|
41
|
+
adcp/types/generated_poc/creative_asset.py,sha256=0QFKsEIVQzcGKTR5EnNVVT9jKvyPBYY1YvIXzwOPiM0,2663
|
|
42
|
+
adcp/types/generated_poc/creative_assignment.py,sha256=RfuYwkhkMcTypU1_adE6O2ngLChcFpnRyDn5pGdmYAU,933
|
|
43
|
+
adcp/types/generated_poc/creative_manifest.py,sha256=tcIeqkHqybljVFVta5hfsNggcvV_doJ5gfGq73lHz3Q,2155
|
|
44
|
+
adcp/types/generated_poc/creative_policy.py,sha256=JSCEiQNw09m_HDkHkh8V5xR_XLuax_p0V_8xclcFtGU,909
|
|
45
|
+
adcp/types/generated_poc/creative_status.py,sha256=yADbaEynrN7rotbZ7AU8QzRQOCms7diHNcoVoi_mT6M,320
|
|
46
|
+
adcp/types/generated_poc/css_asset.py,sha256=XeUrBwfaqChrKT2KxxMuGSAKR5ZpY1a5iCsphH5HCp8,535
|
|
47
|
+
adcp/types/generated_poc/daast_asset.py,sha256=iYi6KpCP8x4Eyl66DL_UiK1MwN365YIoMY8j6cSwl9o,2401
|
|
48
|
+
adcp/types/generated_poc/delivery_metrics.py,sha256=uJR7ydkE8BEL-QR7jg1op4d6jbkr9HHHATph4QB2QNc,4468
|
|
49
|
+
adcp/types/generated_poc/delivery_type.py,sha256=QHnUetxoVtXIz46ATnL6Y0eClhUfqG-GiFUeoi55dz4,264
|
|
50
|
+
adcp/types/generated_poc/deployment.py,sha256=jLXbyT0CjGSa2LIdAVzhi5rnc1gaB1qMDkLzNTmdbLY,2866
|
|
51
|
+
adcp/types/generated_poc/destination.py,sha256=ImO_5RywSilO2nOi62g5C2Tp1A8Cghhh6_rBHS3XIc8,1278
|
|
52
|
+
adcp/types/generated_poc/error.py,sha256=EFwRojmMLJzuTa3Bq705-R07h3k0aUO0LtvvNPCvBSs,1014
|
|
53
|
+
adcp/types/generated_poc/flat_rate_option.py,sha256=SrWw8GDckretlNsGruidlSY6AssJYaOGWgnxbnY6aKM,2967
|
|
54
|
+
adcp/types/generated_poc/format.py,sha256=oElkmwngTCy9M8FpYUInWRgKgb0wdrNj94AzkNHOtuE,9440
|
|
55
|
+
adcp/types/generated_poc/format_id.py,sha256=XEZJQ2UlH-WoIn6XKHHEfXfhDPW9JctO2eMyNHp-SHs,864
|
|
56
|
+
adcp/types/generated_poc/frequency_cap.py,sha256=pCLC16QBlGY5asJ3L5Zipdspl7wBNuTPKwCGSlPCewI,475
|
|
57
|
+
adcp/types/generated_poc/frequency_cap_scope.py,sha256=kzcqOAE39TMaaBxJyIZqiBVnAtCcSvJvcwQAE52enEM,437
|
|
58
|
+
adcp/types/generated_poc/get_media_buy_delivery_request.py,sha256=tv2fFJFwhuGvw-6vEu_a-81tGnwFRzTJSas26Mt02_w,1933
|
|
59
|
+
adcp/types/generated_poc/get_media_buy_delivery_response.py,sha256=Tkc9zgbLJQUU7DzcaZEcx7BZfMaFElmKYRZK8gn0b7U,8164
|
|
60
|
+
adcp/types/generated_poc/get_products_request.py,sha256=PfradwAXM42m3XV1K-VUkEcetCbBleRhC1Q_R0qfB5E,2920
|
|
61
|
+
adcp/types/generated_poc/get_products_response.py,sha256=7dpIW73iejDMJggGt5iya7_eNQT2LmGSlEonyRcqhyw,934
|
|
62
|
+
adcp/types/generated_poc/get_signals_request.py,sha256=etn_7H0Hn9-mA7WjeEyKPDc-LCCJbBbEiuFZzmsOdzw,2558
|
|
63
|
+
adcp/types/generated_poc/get_signals_response.py,sha256=8kz9ycKDgRGmaQPLNnxdq0Kby1yuLyJ8KO58xgmOrxQ,2211
|
|
64
|
+
adcp/types/generated_poc/html_asset.py,sha256=1bMlSgeO-g8ePRgTgq64MqRr5QFNO4QAS3VXJvWzEos,505
|
|
65
|
+
adcp/types/generated_poc/identifier_types.py,sha256=bmT7o_KQOiYt3_lsxwaGjMaNQzsOt2QYlLaWq_Jgyf4,860
|
|
66
|
+
adcp/types/generated_poc/image_asset.py,sha256=7Yoa5K93H3p8n0_epJ8uM1G_TYTaSdOVzXbyqHZu20I,836
|
|
67
|
+
adcp/types/generated_poc/index.py,sha256=bNMI2MCYUahcUoWf3JJOES1mhp0Cnz_ZFuo61Ax6bLU,560
|
|
68
|
+
adcp/types/generated_poc/javascript_asset.py,sha256=HnPD0p8_CcNf9ELZ8RWJMsrSjHKKieqspEUcrFn9CHA,640
|
|
69
|
+
adcp/types/generated_poc/list_authorized_properties_request.py,sha256=TwSZznEBL15GUNlVfgXBNktXaEWZFuH2Mrhtand0uA4,1283
|
|
70
|
+
adcp/types/generated_poc/list_authorized_properties_response.py,sha256=y6kxZDvjPu31c8j5KUR_0a_gJhmI0XTZPvFFG2h9_50,3260
|
|
71
|
+
adcp/types/generated_poc/list_creative_formats_request.py,sha256=0TC38knPXV-hZmFd33JMqlxNR-qT2eueu88ASwx56-8,3088
|
|
72
|
+
adcp/types/generated_poc/list_creative_formats_response.py,sha256=3sl540GPgFrCRkApLacjpqphNdSos5DMmUfEJ_1_Tgo,2136
|
|
73
|
+
adcp/types/generated_poc/list_creatives_request.py,sha256=Ke5bxN5EubDvMEYtvpd2ZSSANwa82Jh52OSGOKej8h0,5319
|
|
74
|
+
adcp/types/generated_poc/list_creatives_response.py,sha256=T1VyU1gYyBzLrTQNOA5Pf89zTXftoOCD3R4GUE6xgQw,8088
|
|
75
|
+
adcp/types/generated_poc/markdown_asset.py,sha256=OYN2frFau32Cu3GlfCnFWHdfYGUvnJ6l8clWjLtCJVg,1215
|
|
76
|
+
adcp/types/generated_poc/measurement.py,sha256=3cxg9O2LZbiv7KjTubU0PNA4MugogPy-1sh0Gc46tZ4,1051
|
|
77
|
+
adcp/types/generated_poc/media_buy.py,sha256=rsaNF7Bi-fICdDLwF_uaAeX8Zi57VN2IhzcfCLmM5ak,1368
|
|
78
|
+
adcp/types/generated_poc/media_buy_status.py,sha256=y6j7Clpnn9sZsDX3iL1G7LQfh-LaSjcKtJA3IT_GpKY,319
|
|
79
|
+
adcp/types/generated_poc/pacing.py,sha256=BgDmzHA3ynqArDEbW2pq9A80_B3QAskb01AW2GS5glM,253
|
|
80
|
+
adcp/types/generated_poc/package.py,sha256=lOPnovO9IzKv3DAk1cGNiZH2FWfuHlerkSx4uGc-w1s,2074
|
|
81
|
+
adcp/types/generated_poc/package_request.py,sha256=u_25V3vrInReg80qHbjlbHTxV3v61-OYqNt3R5HoPH8,2171
|
|
82
|
+
adcp/types/generated_poc/package_status.py,sha256=6ZYBdKqYle7QSL0ni3ZwHqmLTIJxHfZL8WQh5bIBhjo,290
|
|
83
|
+
adcp/types/generated_poc/performance_feedback.py,sha256=CI601JYkllL5n82OayYGbOyureJ3MaswDTVSQ55uFoc,2923
|
|
84
|
+
adcp/types/generated_poc/placement.py,sha256=LvdAVR2HN1nZMsoEkLha3AKt2aczt41-dO08Fr2typM,1052
|
|
85
|
+
adcp/types/generated_poc/preview_creative_request.py,sha256=MA885DHNKBlVRI473aE2sBnfDdhbmSQxpno4bXd5cGk,6059
|
|
86
|
+
adcp/types/generated_poc/preview_creative_response.py,sha256=EAPDyMCYpVC8pbIlpHkrTJlHESTJlHReewTJtTv7O7M,6140
|
|
87
|
+
adcp/types/generated_poc/preview_render.py,sha256=ryBJsjSy7yS_1V9hcYu2mRgK5apAYgi2kYQ7zAycWuE,5024
|
|
88
|
+
adcp/types/generated_poc/pricing_model.py,sha256=ktmIGrqCigaC6S5ctSIj401DUbxcpWEsayejhtg1yz8,324
|
|
89
|
+
adcp/types/generated_poc/pricing_option.py,sha256=W3Paxdxqij2x5mlQlXLhI5u1aXDiEZ2GPP8_NWJdOB4,12447
|
|
90
|
+
adcp/types/generated_poc/product.py,sha256=Lrpwv-acTONRL82dt1SEI-g43XfkJ-16kLtsqEYWIXU,7639
|
|
91
|
+
adcp/types/generated_poc/promoted_offerings.py,sha256=QhjwUEMrKikE50u-98EJ_ZihVKTj_rU0AfR6X3QEkYI,3227
|
|
92
|
+
adcp/types/generated_poc/promoted_products.py,sha256=wXeuc2Sf7nhSmiarPHDZ3gPPdp0zS0rkEHFG2N3Sejo,1252
|
|
93
|
+
adcp/types/generated_poc/property.py,sha256=Di-jsdwpl44-CGk3Zk8OBUwb8kbmClBhq2DxxPJSTbg,2563
|
|
94
|
+
adcp/types/generated_poc/protocol_envelope.py,sha256=7Cb7UddkRcZaFsNpX-3YLV4GhvIhxst2xxrsqlo9fIc,2715
|
|
95
|
+
adcp/types/generated_poc/provide_performance_feedback_request.py,sha256=js69ABROv1bjwnIOqYzRHFA17j6t3nH_f6vTmfH4brY,2820
|
|
96
|
+
adcp/types/generated_poc/provide_performance_feedback_response.py,sha256=V2d1s2jTdsqjGpceQnf1ZgBEbRRCePAXwIpsur-nzjA,1973
|
|
97
|
+
adcp/types/generated_poc/publisher_identifier_types.py,sha256=MGPR-RjZ9y_dZOen95Zchu_kP3MCc1EmpDWRuzbA4kE,321
|
|
98
|
+
adcp/types/generated_poc/push_notification_config.py,sha256=S9d4el3u1JDwGAk4NriGDZlXGzheuizsrsB2iymwFDw,1732
|
|
99
|
+
adcp/types/generated_poc/reporting_capabilities.py,sha256=ii2aLVOxi9URkAViqrSPDFBCXXqwODlXuxojZ2zqSRo,2107
|
|
100
|
+
adcp/types/generated_poc/response.py,sha256=IvTnxhwrfrPWZnmlcpvWN_cgkJQcjq_biW5Q5LW9geY,707
|
|
101
|
+
adcp/types/generated_poc/standard_format_ids.py,sha256=CZ4pRNkUREPXv-opgDT_L_R4LxsAUDDnbMOCYY50Ct4,1921
|
|
102
|
+
adcp/types/generated_poc/start_timing.py,sha256=PEedDJUtaYg9WMA8A_USadYGZduTjXtZRaDwcdQvkPs,397
|
|
103
|
+
adcp/types/generated_poc/sub_asset.py,sha256=RHYmabfVPVcChJ0hEiE7DLnSCwL5-NutncZ_lfk4De0,1666
|
|
104
|
+
adcp/types/generated_poc/sync_creatives_request.py,sha256=uNZtnLocfqNZwbCYOZCd8qdAiC04pKTR-QIUzMGf_gs,2563
|
|
105
|
+
adcp/types/generated_poc/sync_creatives_response.py,sha256=rRjP2f84Cd1JpyPRW4vYINvEluq1eabUOUERbGGFbLI,4096
|
|
106
|
+
adcp/types/generated_poc/targeting.py,sha256=-KBOizlTIhROQkk1Rt8-3i3vb5hixM7moHTfP5LxWuw,1743
|
|
107
|
+
adcp/types/generated_poc/task_status.py,sha256=jqXuwlkMwFoJaVZthrP1PpQ1kOsiKrRTcTjwo7R49II,444
|
|
108
|
+
adcp/types/generated_poc/task_type.py,sha256=wFanzM0Lib8i8v7PXoO-gUBM8igynCfP86p99m1E8fA,382
|
|
109
|
+
adcp/types/generated_poc/tasks_get_request.py,sha256=enkox69QoUQSINQZ9ckdlgmli-kx1V-jpCgJnmohBAI,973
|
|
110
|
+
adcp/types/generated_poc/tasks_get_response.py,sha256=KLlliUYMdOsOEzzEHiJkQJ9fdMFo-MD_e0wCG3oXkn8,3988
|
|
111
|
+
adcp/types/generated_poc/tasks_list_request.py,sha256=wjH8sV_msjjI7aosk8gI6Ape1xzrNcpUZ-9Dx4yzGhQ,4083
|
|
112
|
+
adcp/types/generated_poc/tasks_list_response.py,sha256=qhKzICjB8sMHWRXhNFV-c6S1LODjx7usCTPpF62G7jU,4063
|
|
113
|
+
adcp/types/generated_poc/text_asset.py,sha256=dY9kYUNlXzyjTVDQQvOr9ZdjrmpMYsqfM5DFQUWLJTY,532
|
|
114
|
+
adcp/types/generated_poc/update_media_buy_request.py,sha256=Wkb0N3SMybofpTP5ktrJeZe8-K1YjKozQu7tf_r2aP8,6071
|
|
115
|
+
adcp/types/generated_poc/update_media_buy_response.py,sha256=srFXZTZOmMXx8pBKnh4d0e0haJMiOQD3RnzNUmzRMeA,2506
|
|
116
|
+
adcp/types/generated_poc/url_asset.py,sha256=b9VxwAvvGCcYREwYlbgj47j8tZI9DZNFA39TYNovIps,1114
|
|
117
|
+
adcp/types/generated_poc/vast_asset.py,sha256=2fOBI-Go9HRVt2GHNop7w25wpNxCrmhEOF21cbY5X_4,2679
|
|
118
|
+
adcp/types/generated_poc/vcpm_auction_option.py,sha256=cTtK61hUcCC0PERql660qApTDjtT2Du4f9z6mfs_xWQ,1866
|
|
119
|
+
adcp/types/generated_poc/vcpm_fixed_option.py,sha256=Thc3RTo7_jaOHrqeQzxup0n8ibK7xg0zVM7bJbzH2HI,1278
|
|
120
|
+
adcp/types/generated_poc/video_asset.py,sha256=Nfj-ea5C8yRuVFBSOw9wW2vG2diIJTYn4zRw42lFoKY,978
|
|
121
|
+
adcp/types/generated_poc/webhook_asset.py,sha256=urQuXkPe0nzo7ZXovijSH-kGmVZI5HUkTkDfqBdFK7w,1935
|
|
122
|
+
adcp/types/generated_poc/webhook_payload.py,sha256=8VFvROPthmK4tYT2ELXm1trRFH-_ioE2fn7JfkDJ86U,3563
|
|
123
|
+
adcp/utils/__init__.py,sha256=uetvSJB19CjQbtwEYZiTnumJG11GsafQmXm5eR3hL7E,153
|
|
124
|
+
adcp/utils/operation_id.py,sha256=wQX9Bb5epXzRq23xoeYPTqzu5yLuhshg7lKJZihcM2k,294
|
|
125
|
+
adcp/utils/preview_cache.py,sha256=HbYgHMLIvDddFD6HSupGUze9YLsNOBPlbwlyogUOMcs,18498
|
|
126
|
+
adcp/utils/response_parser.py,sha256=uPk2vIH-RYZmq7y3i8lC4HTMQ3FfKdlgXKTjgJ1955M,6253
|
|
127
|
+
adcp-2.1.0.dist-info/licenses/LICENSE,sha256=PF39NR3Ae8PLgBhg3Uxw6ju7iGVIf8hfv9LRWQdii_U,629
|
|
128
|
+
adcp-2.1.0.dist-info/METADATA,sha256=pnih_Vvk8NMhChX8PXduKloMPSU2E-lqsbubUX5_xJ8,23017
|
|
129
|
+
adcp-2.1.0.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
|
130
|
+
adcp-2.1.0.dist-info/entry_points.txt,sha256=DQKpcGsJX8DtVI_SGApQ7tNvqUB4zkTLaTAEpFgmi3U,44
|
|
131
|
+
adcp-2.1.0.dist-info/top_level.txt,sha256=T1_NF0GefncFU9v_k56oDwKSJREyCqIM8lAwNZf0EOs,5
|
|
132
|
+
adcp-2.1.0.dist-info/RECORD,,
|