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
@@ -0,0 +1,93 @@
1
+ # generated by datamodel-codegen:
2
+ # filename: pricing_options/flat_rate_option.json
3
+ # timestamp: 2025-11-22T15:23:24+00:00
4
+
5
+ from __future__ import annotations
6
+
7
+ from typing import Annotated, Literal
8
+
9
+ from adcp.types.base import AdCPBaseModel
10
+ from pydantic import ConfigDict, Field
11
+
12
+
13
+ class Parameters(AdCPBaseModel):
14
+ model_config = ConfigDict(
15
+ extra='forbid',
16
+ )
17
+ daypart: Annotated[
18
+ str | None,
19
+ Field(
20
+ description="Specific daypart for time-based pricing (e.g., 'morning_commute', 'evening_prime', 'overnight')"
21
+ ),
22
+ ] = None
23
+ duration_hours: Annotated[
24
+ float | None,
25
+ Field(description='Duration in hours for time-based flat rate pricing (DOOH)', ge=0.0),
26
+ ] = None
27
+ estimated_impressions: Annotated[
28
+ int | None,
29
+ Field(
30
+ description='Estimated impressions for this flat rate option (informational, commonly used with SOV or time-based DOOH)',
31
+ ge=0,
32
+ ),
33
+ ] = None
34
+ loop_duration_seconds: Annotated[
35
+ int | None, Field(description='Duration of ad loop rotation in seconds (DOOH)', ge=1)
36
+ ] = None
37
+ min_plays_per_hour: Annotated[
38
+ int | None,
39
+ Field(
40
+ description='Minimum number of times ad plays per hour (DOOH frequency guarantee)', ge=0
41
+ ),
42
+ ] = None
43
+ sov_percentage: Annotated[
44
+ float | None,
45
+ Field(
46
+ description='Guaranteed share of voice as percentage (DOOH, 0-100)', ge=0.0, le=100.0
47
+ ),
48
+ ] = None
49
+ venue_package: Annotated[
50
+ str | None,
51
+ Field(
52
+ description="Named venue package identifier for DOOH (e.g., 'times_square_network', 'airport_terminals')"
53
+ ),
54
+ ] = None
55
+
56
+
57
+ class FlatRatePricingOption(AdCPBaseModel):
58
+ model_config = ConfigDict(
59
+ extra='forbid',
60
+ )
61
+ currency: Annotated[
62
+ str,
63
+ Field(
64
+ description='ISO 4217 currency code',
65
+ examples=['USD', 'EUR', 'GBP', 'JPY'],
66
+ pattern='^[A-Z]{3}$',
67
+ ),
68
+ ]
69
+ is_fixed: Annotated[
70
+ Literal[True],
71
+ Field(description='Whether this is a fixed rate (true) or auction-based (false)'),
72
+ ]
73
+ min_spend_per_package: Annotated[
74
+ float | None,
75
+ Field(
76
+ description='Minimum spend requirement per package using this pricing option, in the specified currency',
77
+ ge=0.0,
78
+ ),
79
+ ] = None
80
+ parameters: Annotated[
81
+ Parameters | None,
82
+ Field(description='Flat rate parameters for DOOH and time-based campaigns'),
83
+ ] = None
84
+ pricing_model: Annotated[
85
+ Literal['flat_rate'], Field(description='Fixed cost regardless of delivery volume')
86
+ ]
87
+ pricing_option_id: Annotated[
88
+ str,
89
+ Field(
90
+ description="Unique identifier for this pricing option within the product (e.g., 'flat_rate_usd_24h_takeover')"
91
+ ),
92
+ ]
93
+ rate: Annotated[float, Field(description='Flat rate cost', ge=0.0)]
@@ -0,0 +1,61 @@
1
+ # generated by datamodel-codegen:
2
+ # filename: pricing_options/vcpm_auction_option.json
3
+ # timestamp: 2025-11-22T15:23:24+00:00
4
+
5
+ from __future__ import annotations
6
+
7
+ from typing import Annotated, Literal
8
+
9
+ from adcp.types.base import AdCPBaseModel
10
+ from pydantic import ConfigDict, Field
11
+
12
+
13
+ class PriceGuidance(AdCPBaseModel):
14
+ floor: Annotated[float, Field(description='Minimum acceptable bid price', ge=0.0)]
15
+ p25: Annotated[
16
+ float | None, Field(description='25th percentile of recent winning bids', ge=0.0)
17
+ ] = None
18
+ p50: Annotated[float | None, Field(description='Median of recent winning bids', ge=0.0)] = None
19
+ p75: Annotated[
20
+ float | None, Field(description='75th percentile of recent winning bids', ge=0.0)
21
+ ] = None
22
+ p90: Annotated[
23
+ float | None, Field(description='90th percentile of recent winning bids', ge=0.0)
24
+ ] = None
25
+
26
+
27
+ class VcpmAuctionPricingOption(AdCPBaseModel):
28
+ model_config = ConfigDict(
29
+ extra='forbid',
30
+ )
31
+ currency: Annotated[
32
+ str,
33
+ Field(
34
+ description='ISO 4217 currency code',
35
+ examples=['USD', 'EUR', 'GBP', 'JPY'],
36
+ pattern='^[A-Z]{3}$',
37
+ ),
38
+ ]
39
+ is_fixed: Annotated[
40
+ Literal[False],
41
+ Field(description='Whether this is a fixed rate (true) or auction-based (false)'),
42
+ ]
43
+ min_spend_per_package: Annotated[
44
+ float | None,
45
+ Field(
46
+ description='Minimum spend requirement per package using this pricing option, in the specified currency',
47
+ ge=0.0,
48
+ ),
49
+ ] = None
50
+ price_guidance: Annotated[
51
+ PriceGuidance, Field(description='Statistical guidance for auction pricing')
52
+ ]
53
+ pricing_model: Annotated[
54
+ Literal['vcpm'], Field(description='Cost per 1,000 viewable impressions (MRC standard)')
55
+ ]
56
+ pricing_option_id: Annotated[
57
+ str,
58
+ Field(
59
+ description="Unique identifier for this pricing option within the product (e.g., 'vcpm_usd_auction')"
60
+ ),
61
+ ]
@@ -0,0 +1,47 @@
1
+ # generated by datamodel-codegen:
2
+ # filename: pricing_options/vcpm_fixed_option.json
3
+ # timestamp: 2025-11-22T15:23:24+00:00
4
+
5
+ from __future__ import annotations
6
+
7
+ from typing import Annotated, Literal
8
+
9
+ from adcp.types.base import AdCPBaseModel
10
+ from pydantic import ConfigDict, Field
11
+
12
+
13
+ class VcpmFixedRatePricingOption(AdCPBaseModel):
14
+ model_config = ConfigDict(
15
+ extra='forbid',
16
+ )
17
+ currency: Annotated[
18
+ str,
19
+ Field(
20
+ description='ISO 4217 currency code',
21
+ examples=['USD', 'EUR', 'GBP', 'JPY'],
22
+ pattern='^[A-Z]{3}$',
23
+ ),
24
+ ]
25
+ is_fixed: Annotated[
26
+ Literal[True],
27
+ Field(description='Whether this is a fixed rate (true) or auction-based (false)'),
28
+ ]
29
+ min_spend_per_package: Annotated[
30
+ float | None,
31
+ Field(
32
+ description='Minimum spend requirement per package using this pricing option, in the specified currency',
33
+ ge=0.0,
34
+ ),
35
+ ] = None
36
+ pricing_model: Annotated[
37
+ Literal['vcpm'], Field(description='Cost per 1,000 viewable impressions (MRC standard)')
38
+ ]
39
+ pricing_option_id: Annotated[
40
+ str,
41
+ Field(
42
+ description="Unique identifier for this pricing option within the product (e.g., 'vcpm_usd_guaranteed')"
43
+ ),
44
+ ]
45
+ rate: Annotated[
46
+ float, Field(description='Fixed vCPM rate (cost per 1,000 viewable impressions)', ge=0.0)
47
+ ]
@@ -0,0 +1,3 @@
1
+ # generated by datamodel-codegen:
2
+ # filename: .schema_temp
3
+ # timestamp: 2025-11-22T16:02:47+00:00
@@ -0,0 +1,37 @@
1
+ # generated by datamodel-codegen:
2
+ # filename: protocols/adcp_extension.json
3
+ # timestamp: 2025-11-22T16:02:47+00:00
4
+
5
+ from __future__ import annotations
6
+
7
+ from enum import Enum
8
+ from typing import Annotated
9
+
10
+ from adcp.types.base import AdCPBaseModel
11
+ from pydantic import ConfigDict, Field
12
+
13
+
14
+ class ProtocolsSupportedEnum(Enum):
15
+ media_buy = 'media_buy'
16
+ creative = 'creative'
17
+ signals = 'signals'
18
+
19
+
20
+ class AdcpAgentCardExtension(AdCPBaseModel):
21
+ model_config = ConfigDict(
22
+ extra='forbid',
23
+ )
24
+ adcp_version: Annotated[
25
+ str,
26
+ Field(
27
+ description="Semantic version of the AdCP specification this agent implements (e.g., '2.4.0')",
28
+ pattern='^\\d+\\.\\d+\\.\\d+$',
29
+ ),
30
+ ]
31
+ protocols_supported: Annotated[
32
+ list[ProtocolsSupportedEnum],
33
+ Field(
34
+ description='AdCP protocol domains supported by this agent. At least one must be specified.',
35
+ min_length=1,
36
+ ),
37
+ ]
@@ -0,0 +1,3 @@
1
+ # generated by datamodel-codegen:
2
+ # filename: .schema_temp
3
+ # timestamp: 2025-11-22T15:23:24+00:00
@@ -0,0 +1,32 @@
1
+ # generated by datamodel-codegen:
2
+ # filename: signals/activate_signal_request.json
3
+ # timestamp: 2025-11-22T15:23:24+00:00
4
+
5
+ from __future__ import annotations
6
+
7
+ from typing import Annotated
8
+
9
+ from adcp.types.base import AdCPBaseModel
10
+ from pydantic import ConfigDict, Field
11
+
12
+ from ..core import context as context_1
13
+ from ..core import destination
14
+ from ..core import ext as ext_1
15
+
16
+
17
+ class ActivateSignalRequest(AdCPBaseModel):
18
+ model_config = ConfigDict(
19
+ extra='forbid',
20
+ )
21
+ context: context_1.ContextObject | None = None
22
+ deployments: Annotated[
23
+ list[destination.Destination1 | destination.Destination2],
24
+ Field(
25
+ description='Target deployment(s) for activation. If the authenticated caller matches one of these deployment targets, activation keys will be included in the response.',
26
+ min_length=1,
27
+ ),
28
+ ]
29
+ ext: ext_1.ExtensionObject | None = None
30
+ signal_agent_segment_id: Annotated[
31
+ str, Field(description='The universal identifier for the signal to activate')
32
+ ]
@@ -0,0 +1,51 @@
1
+ # generated by datamodel-codegen:
2
+ # filename: signals/activate_signal_response.json
3
+ # timestamp: 2025-11-22T19:16:02+00:00
4
+
5
+ from __future__ import annotations
6
+
7
+ from typing import Annotated
8
+
9
+ from adcp.types.base import AdCPBaseModel
10
+ from pydantic import ConfigDict, Field, RootModel
11
+
12
+ from ..core import context as context_1
13
+ from ..core import deployment, error
14
+ from ..core import ext as ext_1
15
+
16
+
17
+ class ActivateSignalResponse1(AdCPBaseModel):
18
+ model_config = ConfigDict(
19
+ extra='forbid',
20
+ )
21
+ context: context_1.ContextObject | None = None
22
+ deployments: Annotated[
23
+ list[deployment.Deployment1 | deployment.Deployment2],
24
+ Field(description='Array of deployment results for each deployment target'),
25
+ ]
26
+ ext: ext_1.ExtensionObject | None = None
27
+
28
+
29
+ class ActivateSignalResponse2(AdCPBaseModel):
30
+ model_config = ConfigDict(
31
+ extra='forbid',
32
+ )
33
+ context: context_1.ContextObject | None = None
34
+ errors: Annotated[
35
+ list[error.Error],
36
+ Field(
37
+ description='Array of errors explaining why activation failed (e.g., platform connectivity issues, signal definition problems, authentication failures)',
38
+ min_length=1,
39
+ ),
40
+ ]
41
+ ext: ext_1.ExtensionObject | None = None
42
+
43
+
44
+ class ActivateSignalResponse(RootModel[ActivateSignalResponse1 | ActivateSignalResponse2]):
45
+ root: Annotated[
46
+ ActivateSignalResponse1 | ActivateSignalResponse2,
47
+ Field(
48
+ description='Response payload for activate_signal task. Returns either complete success data OR error information, never both. This enforces atomic operation semantics - the signal is either fully activated or not activated at all.',
49
+ title='Activate Signal Response',
50
+ ),
51
+ ]
@@ -0,0 +1,53 @@
1
+ # generated by datamodel-codegen:
2
+ # filename: signals/get_signals_request.json
3
+ # timestamp: 2025-11-22T15:23:24+00:00
4
+
5
+ from __future__ import annotations
6
+
7
+ from typing import Annotated
8
+
9
+ from adcp.types.base import AdCPBaseModel
10
+ from pydantic import ConfigDict, Field, RootModel
11
+
12
+ from ..core import context as context_1
13
+ from ..core import destination
14
+ from ..core import ext as ext_1
15
+ from ..core import signal_filters
16
+
17
+
18
+ class Country(RootModel[str]):
19
+ root: Annotated[str, Field(pattern='^[A-Z]{2}$')]
20
+
21
+
22
+ class DeliverTo(AdCPBaseModel):
23
+ model_config = ConfigDict(
24
+ extra='forbid',
25
+ )
26
+ countries: Annotated[
27
+ list[Country], Field(description='Countries where signals will be used (ISO codes)')
28
+ ]
29
+ deployments: Annotated[
30
+ list[destination.Destination1 | destination.Destination2],
31
+ Field(
32
+ description='List of deployment targets (DSPs, sales agents, etc.). If the authenticated caller matches one of these deployment targets, activation keys will be included in the response.',
33
+ min_length=1,
34
+ ),
35
+ ]
36
+
37
+
38
+ class GetSignalsRequest(AdCPBaseModel):
39
+ model_config = ConfigDict(
40
+ extra='forbid',
41
+ )
42
+ context: context_1.ContextObject | None = None
43
+ deliver_to: Annotated[
44
+ DeliverTo, Field(description='Deployment targets where signals need to be activated')
45
+ ]
46
+ ext: ext_1.ExtensionObject | None = None
47
+ filters: signal_filters.SignalFilters | None = None
48
+ max_results: Annotated[
49
+ int | None, Field(description='Maximum number of results to return', ge=1)
50
+ ] = None
51
+ signal_spec: Annotated[
52
+ str, Field(description='Natural language description of the desired signals')
53
+ ]
@@ -0,0 +1,59 @@
1
+ # generated by datamodel-codegen:
2
+ # filename: signals/get_signals_response.json
3
+ # timestamp: 2025-11-22T15:23:24+00:00
4
+
5
+ from __future__ import annotations
6
+
7
+ from typing import Annotated
8
+
9
+ from adcp.types.base import AdCPBaseModel
10
+ from pydantic import ConfigDict, Field
11
+
12
+ from ..core import context as context_1
13
+ from ..core import deployment, error
14
+ from ..core import ext as ext_1
15
+ from ..enums import signal_catalog_type
16
+
17
+
18
+ class Pricing(AdCPBaseModel):
19
+ model_config = ConfigDict(
20
+ extra='forbid',
21
+ )
22
+ cpm: Annotated[float, Field(description='Cost per thousand impressions', ge=0.0)]
23
+ currency: Annotated[str, Field(description='Currency code', pattern='^[A-Z]{3}$')]
24
+
25
+
26
+ class Signal(AdCPBaseModel):
27
+ model_config = ConfigDict(
28
+ extra='forbid',
29
+ )
30
+ coverage_percentage: Annotated[
31
+ float, Field(description='Percentage of audience coverage', ge=0.0, le=100.0)
32
+ ]
33
+ data_provider: Annotated[str, Field(description='Name of the data provider')]
34
+ deployments: Annotated[
35
+ list[deployment.Deployment1 | deployment.Deployment2],
36
+ Field(description='Array of deployment targets'),
37
+ ]
38
+ description: Annotated[str, Field(description='Detailed signal description')]
39
+ name: Annotated[str, Field(description='Human-readable signal name')]
40
+ pricing: Annotated[Pricing, Field(description='Pricing information')]
41
+ signal_agent_segment_id: Annotated[str, Field(description='Unique identifier for the signal')]
42
+ signal_type: Annotated[
43
+ signal_catalog_type.SignalCatalogType, Field(description='Type of signal')
44
+ ]
45
+
46
+
47
+ class GetSignalsResponse(AdCPBaseModel):
48
+ model_config = ConfigDict(
49
+ extra='forbid',
50
+ )
51
+ context: context_1.ContextObject | None = None
52
+ errors: Annotated[
53
+ list[error.Error] | None,
54
+ Field(
55
+ description='Task-specific errors and warnings (e.g., signal discovery or pricing issues)'
56
+ ),
57
+ ] = None
58
+ ext: ext_1.ExtensionObject | None = None
59
+ signals: Annotated[list[Signal], Field(description='Array of matching signals')]
adcp/utils/__init__.py ADDED
@@ -0,0 +1,7 @@
1
+ from __future__ import annotations
2
+
3
+ """Utility functions."""
4
+
5
+ from adcp.utils.operation_id import create_operation_id
6
+
7
+ __all__ = ["create_operation_id"]
@@ -0,0 +1,15 @@
1
+ from __future__ import annotations
2
+
3
+ """Operation ID generation utilities."""
4
+
5
+ from uuid import uuid4
6
+
7
+
8
+ def create_operation_id() -> str:
9
+ """
10
+ Generate a unique operation ID.
11
+
12
+ Returns:
13
+ A unique operation ID in the format 'op_{hex}'
14
+ """
15
+ return f"op_{uuid4().hex[:12]}"