diff --git a/schemas/cache/1.0.0/asset-type.json b/schemas/cache/1.0.0/asset-type.json deleted file mode 100644 index 5508ec88..00000000 --- a/schemas/cache/1.0.0/asset-type.json +++ /dev/null @@ -1,168 +0,0 @@ -{ - "$id": "/schemas/v1/core/asset-type.json", - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, - "description": "Schema for describing asset requirements in creative formats", - "properties": { - "asset_role": { - "description": "Role or purpose of this asset in the creative (e.g., 'hero_image', 'logo', 'cta_button')", - "type": "string" - }, - "constraints": { - "description": "Additional constraints or requirements (human-readable)", - "items": { - "type": "string" - }, - "type": "array" - }, - "examples": { - "description": "Example values or descriptions for this asset", - "items": { - "type": "string" - }, - "type": "array" - }, - "required": { - "default": true, - "description": "Whether this asset is mandatory for the format", - "type": "boolean" - }, - "requirements": { - "additionalProperties": false, - "description": "Technical requirements for this asset type", - "properties": { - "content_length": { - "properties": { - "max_characters": { - "minimum": 1, - "type": "integer" - }, - "max_words": { - "minimum": 1, - "type": "integer" - }, - "min_characters": { - "minimum": 0, - "type": "integer" - }, - "min_words": { - "minimum": 0, - "type": "integer" - } - }, - "type": "object" - }, - "dimensions": { - "properties": { - "aspect_ratio": { - "type": "string" - }, - "height": { - "minimum": 1, - "type": "integer" - }, - "max_height": { - "minimum": 1, - "type": "integer" - }, - "max_width": { - "minimum": 1, - "type": "integer" - }, - "min_height": { - "minimum": 1, - "type": "integer" - }, - "min_width": { - "minimum": 1, - "type": "integer" - }, - "width": { - "minimum": 1, - "type": "integer" - } - }, - "type": "object" - }, - "duration": { - "properties": { - "exact_seconds": { - "minimum": 0, - "type": "number" - }, - "max_seconds": { - "minimum": 0, - "type": "number" - }, - "min_seconds": { - "minimum": 0, - "type": "number" - } - }, - "type": "object" - }, - "file_formats": { - "description": "Acceptable file formats (e.g., ['jpg', 'png'] for images)", - "items": { - "type": "string" - }, - "type": "array" - }, - "file_size": { - "properties": { - "max_bytes": { - "minimum": 1, - "type": "integer" - }, - "min_bytes": { - "minimum": 0, - "type": "integer" - } - }, - "type": "object" - }, - "quality": { - "properties": { - "max_bitrate_kbps": { - "minimum": 1, - "type": "integer" - }, - "min_bitrate_kbps": { - "minimum": 1, - "type": "integer" - }, - "min_resolution_dpi": { - "minimum": 72, - "type": "integer" - } - }, - "type": "object" - } - }, - "type": "object" - }, - "type": { - "description": "Type of asset", - "enum": [ - "image", - "video", - "audio", - "text", - "html", - "css", - "javascript", - "vast", - "daast", - "promoted_offerings", - "url" - ], - "type": "string" - } - }, - "required": [ - "asset_role", - "type" - ], - "title": "Asset Type Schema", - "type": "object" -} \ No newline at end of file diff --git a/schemas/cache/1.0.0/core/asset-type.json b/schemas/cache/1.0.0/core/asset-type.json deleted file mode 100644 index ca35b0e9..00000000 --- a/schemas/cache/1.0.0/core/asset-type.json +++ /dev/null @@ -1,91 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "$id": "/schemas/v1/core/asset-type.json", - "title": "Asset Type Schema", - "description": "Schema for describing asset requirements in creative formats", - "type": "object", - "properties": { - "asset_role": { - "type": "string", - "description": "Role or purpose of this asset in the creative (e.g., 'hero_image', 'logo', 'cta_button')" - }, - "type": { - "type": "string", - "enum": ["image", "video", "audio", "text", "html", "css", "javascript", "vast", "daast", "promoted_offerings", "url"], - "description": "Type of asset" - }, - "required": { - "type": "boolean", - "default": true, - "description": "Whether this asset is mandatory for the format" - }, - "requirements": { - "type": "object", - "description": "Technical requirements for this asset type", - "properties": { - "dimensions": { - "type": "object", - "properties": { - "width": {"type": "integer", "minimum": 1}, - "height": {"type": "integer", "minimum": 1}, - "aspect_ratio": {"type": "string"}, - "min_width": {"type": "integer", "minimum": 1}, - "max_width": {"type": "integer", "minimum": 1}, - "min_height": {"type": "integer", "minimum": 1}, - "max_height": {"type": "integer", "minimum": 1} - } - }, - "duration": { - "type": "object", - "properties": { - "min_seconds": {"type": "number", "minimum": 0}, - "max_seconds": {"type": "number", "minimum": 0}, - "exact_seconds": {"type": "number", "minimum": 0} - } - }, - "file_size": { - "type": "object", - "properties": { - "min_bytes": {"type": "integer", "minimum": 0}, - "max_bytes": {"type": "integer", "minimum": 1} - } - }, - "file_formats": { - "type": "array", - "items": {"type": "string"}, - "description": "Acceptable file formats (e.g., ['jpg', 'png'] for images)" - }, - "content_length": { - "type": "object", - "properties": { - "min_characters": {"type": "integer", "minimum": 0}, - "max_characters": {"type": "integer", "minimum": 1}, - "min_words": {"type": "integer", "minimum": 0}, - "max_words": {"type": "integer", "minimum": 1} - } - }, - "quality": { - "type": "object", - "properties": { - "min_bitrate_kbps": {"type": "integer", "minimum": 1}, - "max_bitrate_kbps": {"type": "integer", "minimum": 1}, - "min_resolution_dpi": {"type": "integer", "minimum": 72} - } - } - }, - "additionalProperties": false - }, - "constraints": { - "type": "array", - "items": {"type": "string"}, - "description": "Additional constraints or requirements (human-readable)" - }, - "examples": { - "type": "array", - "items": {"type": "string"}, - "description": "Example values or descriptions for this asset" - } - }, - "required": ["asset_role", "type"], - "additionalProperties": false -} \ No newline at end of file diff --git a/scripts/sync_schemas.py b/scripts/sync_schemas.py index 657618f6..219a1ead 100755 --- a/scripts/sync_schemas.py +++ b/scripts/sync_schemas.py @@ -6,6 +6,12 @@ not just those listed in index.json. This ensures we get all schemas including asset types (vast-asset.json, daast-asset.json) with discriminators from PR #189. +Features: +- Content-based change detection (only updates files when content changes) +- Automatic cleanup of orphaned schemas (files removed upstream) +- Preserves directory structure from upstream +- Symlink to latest version for convenience + Usage: python scripts/sync_schemas.py # Normal sync (uses content hashing) python scripts/sync_schemas.py --force # Force re-download all schemas @@ -207,6 +213,7 @@ def main(): print("Downloading schemas:") updated_count = 0 cached_count = 0 + removed_count = 0 for url in schema_urls: was_updated, new_hash = download_schema_file(url, version, hash_cache, force=args.force) @@ -219,6 +226,37 @@ def main(): if new_hash: updated_hashes[url] = new_hash + # Clean up orphaned schemas (files that exist locally but not upstream) + version_dir = CACHE_DIR / version + if version_dir.exists(): + # Get list of expected filenames from URLs + expected_files = {url.split("/")[-1] for url in schema_urls} + # Also allow the hash cache file + expected_files.add(".hashes.json") + + # Find orphaned JSON files + orphaned_files = [] + for json_file in version_dir.rglob("*.json"): + if json_file.name not in expected_files and json_file.name != ".hashes.json": + orphaned_files.append(json_file) + + # Remove orphaned files + if orphaned_files: + print("\nCleaning up orphaned schemas:") + for orphan in orphaned_files: + rel_path = orphan.relative_to(version_dir) + print(f" āœ— {rel_path} (removed - no longer in upstream)") + orphan.unlink() + removed_count += 1 + + # Remove empty directories + parent = orphan.parent + try: + if parent != version_dir and not any(parent.iterdir()): + parent.rmdir() + except OSError: + pass + # Save updated hash cache if updated_hashes: save_hash_cache(updated_hashes) @@ -237,6 +275,8 @@ def main(): print(f" Location: {version_dir}") print(f" Updated: {updated_count}") print(f" Cached: {cached_count}") + if removed_count > 0: + print(f" Removed: {removed_count} (orphaned)") except Exception as e: print(f"\nāœ— Error syncing schemas: {e}", file=sys.stderr) diff --git a/src/adcp/__init__.py b/src/adcp/__init__.py index 9f19b9db..d474fb56 100644 --- a/src/adcp/__init__.py +++ b/src/adcp/__init__.py @@ -108,6 +108,8 @@ # Audience & Targeting ActivateSignalRequest, ActivateSignalResponse, + # Type enums from PR #222 + AssetContentType, # Core domain types BrandManifest, # Creative Operations @@ -131,6 +133,7 @@ Error, FlatRatePricingOption, Format, + FormatCategory, FormatId, GetMediaBuyDeliveryRequest, GetMediaBuyDeliveryResponse, @@ -218,6 +221,9 @@ "Error", "Format", "FormatId", + # New type enums from PR #222 + "AssetContentType", + "FormatCategory", "Product", "Property", # Core domain types (from stable API) diff --git a/src/adcp/types/__init__.py b/src/adcp/types/__init__.py index e3fa830b..a2e34543 100644 --- a/src/adcp/types/__init__.py +++ b/src/adcp/types/__init__.py @@ -107,7 +107,6 @@ AssetSelectors, AssetsRequired, AssetType, - AssetTypeSchema, AssignedPackage, Assignments, AudioAsset, @@ -125,7 +124,6 @@ CoBranding, Colors, Contact, - ContentLength, Country, CpcPricingOption, CpcvPricingOption, @@ -150,19 +148,16 @@ DeliveryMetrics, DeliveryType, Details, - Dimensions, Direction, Disclaimer, Domain, DomainBreakdown, DoohMetrics, - Duration, Embedding, Error, FeedbackSource, FeedFormat, FieldModel, - FileSize, Filters, FlatRatePricingOption, Fonts, @@ -243,7 +238,6 @@ PublisherDomain, PublisherIdentifierTypes, PushNotificationConfig, - Quality, QuartileData, QuerySummary, Render, @@ -253,7 +247,6 @@ ReportingWebhook, Request, RequestedMetric, - Requirements, Response, ResponseType, Responsive, @@ -333,7 +326,6 @@ "Asset", "AssetSelectors", "AssetType", - "AssetTypeSchema", "AssetsRequired", "AssignedPackage", "Assignments", @@ -360,7 +352,6 @@ "CoBranding", "Colors", "Contact", - "ContentLength", "Country", "CpcPricingOption", "CpcvPricingOption", @@ -389,19 +380,16 @@ "Deployment", "Destination", "Details", - "Dimensions", "Direction", "Disclaimer", "Domain", "DomainBreakdown", "DoohMetrics", - "Duration", "Embedding", "Error", "FeedFormat", "FeedbackSource", "FieldModel", - "FileSize", "Filters", "FlatRatePricingOption", "Fonts", @@ -502,7 +490,6 @@ "PublisherPropertiesById", "PublisherPropertiesByTag", "PushNotificationConfig", - "Quality", "QuartileData", "QuerySummary", "Render", @@ -512,7 +499,6 @@ "ReportingWebhook", "Request", "RequestedMetric", - "Requirements", "Response", "ResponseType", "Responsive", diff --git a/src/adcp/types/_generated.py b/src/adcp/types/_generated.py index e7c52900..2fda3668 100644 --- a/src/adcp/types/_generated.py +++ b/src/adcp/types/_generated.py @@ -10,7 +10,7 @@ DO NOT EDIT MANUALLY. Generated from: https://github.com/adcontextprotocol/adcp/tree/main/schemas -Generation date: 2025-11-20 17:15:08 UTC +Generation date: 2025-11-20 21:00:13 UTC """ # ruff: noqa: E501, I001 from __future__ import annotations @@ -21,7 +21,6 @@ from adcp.types.generated_poc.activation_key import ActivationKey1, ActivationKey2 from adcp.types.generated_poc.adagents import AuthorizedAgents, AuthorizedAgents1, AuthorizedAgents2, AuthorizedAgents3, AuthorizedSalesAgents, Contact, PropertyId, PropertyTag, Tags from adcp.types.generated_poc.asset_content_type import AssetContentType -from adcp.types.generated_poc.asset_type import AssetTypeSchema, ContentLength, Dimensions, Duration, FileSize, Quality, Requirements, Type from adcp.types.generated_poc.audio_asset import AudioAsset from adcp.types.generated_poc.brand_manifest import Asset, BrandManifest, Colors, Disclaimer, FeedFormat, Fonts, Logo, Metadata, ProductCatalog, UpdateFrequency from adcp.types.generated_poc.build_creative_request import BuildCreativeRequest @@ -48,7 +47,7 @@ from adcp.types.generated_poc.destination import Destination1, Destination2 from adcp.types.generated_poc.error import Error from adcp.types.generated_poc.flat_rate_option import FlatRatePricingOption -from adcp.types.generated_poc.format import AssetsRequired, AssetsRequired1, Format, FormatCard, FormatCardDetailed, Render, Responsive, Unit +from adcp.types.generated_poc.format import AssetsRequired, AssetsRequired1, Dimensions, Format, FormatCard, FormatCardDetailed, Render, Responsive, Unit from adcp.types.generated_poc.format_category import FormatCategory from adcp.types.generated_poc.format_id import FormatId from adcp.types.generated_poc.frequency_cap import FrequencyCap @@ -102,7 +101,7 @@ from adcp.types.generated_poc.task_status import TaskStatus from adcp.types.generated_poc.task_type import TaskType from adcp.types.generated_poc.tasks_get_request import TasksGetRequest -from adcp.types.generated_poc.tasks_get_response import Details, Domain, HistoryItem, Progress, TasksGetResponse +from adcp.types.generated_poc.tasks_get_response import Details, Domain, HistoryItem, Progress, TasksGetResponse, Type from adcp.types.generated_poc.tasks_list_request import TasksListRequest from adcp.types.generated_poc.tasks_list_response import DomainBreakdown, Task, TasksListResponse from adcp.types.generated_poc.text_asset import TextAsset @@ -127,26 +126,26 @@ "Action", "ActivateSignalRequest", "ActivateSignalResponse", "ActivateSignalResponse1", "ActivateSignalResponse2", "ActivationKey1", "ActivationKey2", "AdvertisingChannels", "AggregatedTotals", "Asset", "AssetContentType", "AssetSelectors", "AssetType", - "AssetTypeSchema", "AssetsRequired", "AssetsRequired1", "AssignedPackage", "Assignments", - "AudioAsset", "Authentication", "AuthorizedAgents", "AuthorizedAgents1", "AuthorizedAgents2", + "AssetsRequired", "AssetsRequired1", "AssignedPackage", "Assignments", "AudioAsset", + "Authentication", "AuthorizedAgents", "AuthorizedAgents1", "AuthorizedAgents2", "AuthorizedAgents3", "AuthorizedSalesAgents", "AvailableMetric", "AvailableReportingFrequency", "BrandManifest", "BuildCreativeRequest", "BuildCreativeResponse", "BuildCreativeResponse1", "BuildCreativeResponse2", "ByPackageItem", "Capability", "CatalogType", "Channels", - "CoBranding", "Colors", "Contact", "ContentLength", "Country", "CpcPricingOption", - "CpcvPricingOption", "CpmAuctionPricingOption", "CpmFixedRatePricingOption", - "CppPricingOption", "CpvPricingOption", "CreateMediaBuyRequest", "CreateMediaBuyResponse", - "CreateMediaBuyResponse1", "CreateMediaBuyResponse2", "Creative", "CreativeAgent", - "CreativeAsset", "CreativeAssignment", "CreativeManifest", "CreativePolicy", "CreativeStatus", - "CssAsset", "DaastAsset1", "DaastAsset2", "DaastVersion", "DailyBreakdownItem", "DeliverTo", - "DeliveryMeasurement", "DeliveryMetrics", "DeliveryType", "Deployment1", "Deployment2", - "Destination1", "Destination2", "Details", "Dimensions", "Direction", "Disclaimer", "Domain", - "DomainBreakdown", "DoohMetrics", "Duration", "Embedding", "Error", "FeedFormat", - "FeedbackSource", "Field1", "FieldModel", "FileSize", "Filters", "FlatRatePricingOption", - "Fonts", "Format", "FormatCard", "FormatCardDetailed", "FormatCategory", "FormatId", - "FormatType", "FrequencyCap", "FrequencyCapScope", "GeoCountryAnyOfItem", - "GetMediaBuyDeliveryRequest", "GetMediaBuyDeliveryResponse", "GetProductsRequest", - "GetProductsResponse", "GetSignalsRequest", "GetSignalsResponse", "HistoryItem", "HtmlAsset", - "Identifier", "ImageAsset", "Input", "Input2", "Input4", "JavascriptAsset", "LandingPage", + "CoBranding", "Colors", "Contact", "Country", "CpcPricingOption", "CpcvPricingOption", + "CpmAuctionPricingOption", "CpmFixedRatePricingOption", "CppPricingOption", "CpvPricingOption", + "CreateMediaBuyRequest", "CreateMediaBuyResponse", "CreateMediaBuyResponse1", + "CreateMediaBuyResponse2", "Creative", "CreativeAgent", "CreativeAsset", "CreativeAssignment", + "CreativeManifest", "CreativePolicy", "CreativeStatus", "CssAsset", "DaastAsset1", + "DaastAsset2", "DaastVersion", "DailyBreakdownItem", "DeliverTo", "DeliveryMeasurement", + "DeliveryMetrics", "DeliveryType", "Deployment1", "Deployment2", "Destination1", + "Destination2", "Details", "Dimensions", "Direction", "Disclaimer", "Domain", + "DomainBreakdown", "DoohMetrics", "Embedding", "Error", "FeedFormat", "FeedbackSource", + "Field1", "FieldModel", "Filters", "FlatRatePricingOption", "Fonts", "Format", "FormatCard", + "FormatCardDetailed", "FormatCategory", "FormatId", "FormatType", "FrequencyCap", + "FrequencyCapScope", "GeoCountryAnyOfItem", "GetMediaBuyDeliveryRequest", + "GetMediaBuyDeliveryResponse", "GetProductsRequest", "GetProductsResponse", + "GetSignalsRequest", "GetSignalsResponse", "HistoryItem", "HtmlAsset", "Identifier", + "ImageAsset", "Input", "Input2", "Input4", "JavascriptAsset", "LandingPage", "ListAuthorizedPropertiesRequest", "ListAuthorizedPropertiesResponse", "ListCreativeFormatsRequest", "ListCreativeFormatsResponse", "ListCreativesRequest", "ListCreativesResponse", "Logo", "MarkdownAsset", "MarkdownFlavor", "Measurement", @@ -164,18 +163,18 @@ "ProvidePerformanceFeedbackResponse", "ProvidePerformanceFeedbackResponse1", "ProvidePerformanceFeedbackResponse2", "PublisherDomain", "PublisherIdentifierTypes", "PublisherPropertySelector1", "PublisherPropertySelector2", "PublisherPropertySelector3", - "PushNotificationConfig", "Quality", "QuartileData", "QuerySummary", "Render", - "ReportingCapabilities", "ReportingFrequency", "ReportingPeriod", "ReportingWebhook", - "Request", "RequestedMetric", "Requirements", "Response", "Response1", "ResponseType", - "Responsive", "Results", "Results1", "Scheme", "Security", "Signal", "SignalType", "Sort", - "SortApplied", "StandardFormatIds", "Status", "StatusFilter", "StatusFilterEnum", - "StatusSummary", "SubAsset1", "SubAsset2", "SyncCreativesRequest", "SyncCreativesResponse", - "SyncCreativesResponse1", "SyncCreativesResponse2", "Tag", "Tags", "TargetingOverlay", "Task", - "TaskStatus", "TaskType", "TasksGetRequest", "TasksGetResponse", "TasksListRequest", - "TasksListResponse", "TextAsset", "Totals", "TrackingEvent", "Type", "Unit", "UpdateFrequency", - "UpdateMediaBuyRequest", "UpdateMediaBuyRequest1", "UpdateMediaBuyRequest2", - "UpdateMediaBuyResponse", "UpdateMediaBuyResponse1", "UpdateMediaBuyResponse2", "UrlAsset", - "UrlType", "ValidationMode", "VastAsset1", "VastAsset2", "VastVersion", - "VcpmAuctionPricingOption", "VcpmFixedRatePricingOption", "VenueBreakdownItem", "VideoAsset", - "ViewThreshold", "ViewThreshold1", "WebhookAsset", "WebhookPayload", "_PackageFromPackage" + "PushNotificationConfig", "QuartileData", "QuerySummary", "Render", "ReportingCapabilities", + "ReportingFrequency", "ReportingPeriod", "ReportingWebhook", "Request", "RequestedMetric", + "Response", "Response1", "ResponseType", "Responsive", "Results", "Results1", "Scheme", + "Security", "Signal", "SignalType", "Sort", "SortApplied", "StandardFormatIds", "Status", + "StatusFilter", "StatusFilterEnum", "StatusSummary", "SubAsset1", "SubAsset2", + "SyncCreativesRequest", "SyncCreativesResponse", "SyncCreativesResponse1", + "SyncCreativesResponse2", "Tag", "Tags", "TargetingOverlay", "Task", "TaskStatus", "TaskType", + "TasksGetRequest", "TasksGetResponse", "TasksListRequest", "TasksListResponse", "TextAsset", + "Totals", "TrackingEvent", "Type", "Unit", "UpdateFrequency", "UpdateMediaBuyRequest", + "UpdateMediaBuyRequest1", "UpdateMediaBuyRequest2", "UpdateMediaBuyResponse", + "UpdateMediaBuyResponse1", "UpdateMediaBuyResponse2", "UrlAsset", "UrlType", "ValidationMode", + "VastAsset1", "VastAsset2", "VastVersion", "VcpmAuctionPricingOption", + "VcpmFixedRatePricingOption", "VenueBreakdownItem", "VideoAsset", "ViewThreshold", + "ViewThreshold1", "WebhookAsset", "WebhookPayload", "_PackageFromPackage" ] diff --git a/src/adcp/types/aliases.py b/src/adcp/types/aliases.py index 5c150e7f..87b28e6b 100644 --- a/src/adcp/types/aliases.py +++ b/src/adcp/types/aliases.py @@ -100,10 +100,11 @@ PublisherPropertySelector3 as PublisherPropertiesByTagInternal, ) -# Import all generated types that need semantic aliases -from adcp.types._generated import ( - _PackageFromPackage as FullPackageInternal, -) +# Note: Package collision resolved by PR #223 +# Both create_media_buy and update_media_buy now return full Package objects +# No more separate reference type needed +# Import Package from _generated (still uses qualified name for internal reasons) +from adcp.types._generated import _PackageFromPackage as Package # ============================================================================ # RESPONSE TYPE ALIASES - Success/Error Discriminated Unions @@ -238,31 +239,11 @@ # - Used in MediaBuy, update operations, and package management # - Has 12+ fields for full package configuration # -# 2. Created Package (from create-media-buy-response.json schema): -# - Minimal response type with only IDs (buyer_ref, package_id) -# - Used in CreateMediaBuy success responses -# - Only 2 fields - represents newly created package references -# -# The code generator's "first wins" collision handling exports the Created Package -# as "Package", shadowing the Full Package. These semantic aliases provide clear, -# unambiguous names for both types. - -Package = FullPackageInternal -"""Complete package configuration with all operational fields. - -This is the canonical Package type used throughout AdCP for package management. - -Used in: -- MediaBuy.packages (list of full package details) -- Update operations (modifying existing packages) -- Package management (creating/configuring packages) - -Fields include: budget, pricing_option_id, product_id, status, bid_price, -creative_assignments, format_ids_to_provide, impressions, pacing, targeting_overlay -""" - -# Note: CreatedPackageReference was removed as the schema now uses the canonical -# Package type everywhere. Use `Package` directly instead. +# Package collision resolved by PR #223: +# - create-media-buy-response.json now returns full Package objects (not minimal refs) +# - update-media-buy-response.json already returned full Package objects +# - Both operations return identical Package structures +# - Single Package type imported above, no aliases needed # ============================================================================ # PUBLISHER PROPERTIES ALIASES - Selection Type Discriminated Unions diff --git a/src/adcp/types/generated_poc/activate_signal_request.py b/src/adcp/types/generated_poc/activate_signal_request.py index 8e4b491a..831e0a78 100644 --- a/src/adcp/types/generated_poc/activate_signal_request.py +++ b/src/adcp/types/generated_poc/activate_signal_request.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: activate-signal-request.json -# timestamp: 2025-11-20T17:15:07+00:00 +# timestamp: 2025-11-20T20:44:40+00:00 from __future__ import annotations diff --git a/src/adcp/types/generated_poc/activate_signal_response.py b/src/adcp/types/generated_poc/activate_signal_response.py index 17d099df..6255d05c 100644 --- a/src/adcp/types/generated_poc/activate_signal_response.py +++ b/src/adcp/types/generated_poc/activate_signal_response.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: activate-signal-response.json -# timestamp: 2025-11-20T17:15:07+00:00 +# timestamp: 2025-11-20T20:44:40+00:00 from __future__ import annotations diff --git a/src/adcp/types/generated_poc/asset_content_type.py b/src/adcp/types/generated_poc/asset_content_type.py index 9ce44d04..413a06ee 100644 --- a/src/adcp/types/generated_poc/asset_content_type.py +++ b/src/adcp/types/generated_poc/asset_content_type.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: asset-content-type.json -# timestamp: 2025-11-20T17:15:07+00:00 +# timestamp: 2025-11-20T11:58:34+00:00 from __future__ import annotations diff --git a/src/adcp/types/generated_poc/asset_type.py b/src/adcp/types/generated_poc/asset_type.py deleted file mode 100644 index 4ab4d371..00000000 --- a/src/adcp/types/generated_poc/asset_type.py +++ /dev/null @@ -1,100 +0,0 @@ -# generated by datamodel-codegen: -# filename: asset-type.json -# timestamp: 2025-11-18T03:35:10+00:00 - -from __future__ import annotations - -from enum import Enum -from typing import Annotated - -from adcp.types.base import AdCPBaseModel -from pydantic import ConfigDict, Field - - -class ContentLength(AdCPBaseModel): - max_characters: Annotated[int | None, Field(ge=1)] = None - max_words: Annotated[int | None, Field(ge=1)] = None - min_characters: Annotated[int | None, Field(ge=0)] = None - min_words: Annotated[int | None, Field(ge=0)] = None - - -class Dimensions(AdCPBaseModel): - aspect_ratio: str | None = None - height: Annotated[int | None, Field(ge=1)] = None - max_height: Annotated[int | None, Field(ge=1)] = None - max_width: Annotated[int | None, Field(ge=1)] = None - min_height: Annotated[int | None, Field(ge=1)] = None - min_width: Annotated[int | None, Field(ge=1)] = None - width: Annotated[int | None, Field(ge=1)] = None - - -class Duration(AdCPBaseModel): - exact_seconds: Annotated[float | None, Field(ge=0.0)] = None - max_seconds: Annotated[float | None, Field(ge=0.0)] = None - min_seconds: Annotated[float | None, Field(ge=0.0)] = None - - -class FileSize(AdCPBaseModel): - max_bytes: Annotated[int | None, Field(ge=1)] = None - min_bytes: Annotated[int | None, Field(ge=0)] = None - - -class Quality(AdCPBaseModel): - max_bitrate_kbps: Annotated[int | None, Field(ge=1)] = None - min_bitrate_kbps: Annotated[int | None, Field(ge=1)] = None - min_resolution_dpi: Annotated[int | None, Field(ge=72)] = None - - -class Requirements(AdCPBaseModel): - model_config = ConfigDict( - extra='forbid', - ) - content_length: ContentLength | None = None - dimensions: Dimensions | None = None - duration: Duration | None = None - file_formats: Annotated[ - list[str] | None, - Field(description="Acceptable file formats (e.g., ['jpg', 'png'] for images)"), - ] = None - file_size: FileSize | None = None - quality: Quality | None = None - - -class Type(Enum): - image = 'image' - video = 'video' - audio = 'audio' - text = 'text' - html = 'html' - css = 'css' - javascript = 'javascript' - vast = 'vast' - daast = 'daast' - promoted_offerings = 'promoted_offerings' - url = 'url' - - -class AssetTypeSchema(AdCPBaseModel): - model_config = ConfigDict( - extra='forbid', - ) - asset_role: Annotated[ - str, - Field( - description="Role or purpose of this asset in the creative (e.g., 'hero_image', 'logo', 'cta_button')" - ), - ] - constraints: Annotated[ - list[str] | None, - Field(description='Additional constraints or requirements (human-readable)'), - ] = None - examples: Annotated[ - list[str] | None, Field(description='Example values or descriptions for this asset') - ] = None - required: Annotated[ - bool | None, Field(description='Whether this asset is mandatory for the format') - ] = True - requirements: Annotated[ - Requirements | None, Field(description='Technical requirements for this asset type') - ] = None - type: Annotated[Type, Field(description='Type of asset')] diff --git a/src/adcp/types/generated_poc/brand_manifest.py b/src/adcp/types/generated_poc/brand_manifest.py index 5dbb17d9..cafcb1fd 100644 --- a/src/adcp/types/generated_poc/brand_manifest.py +++ b/src/adcp/types/generated_poc/brand_manifest.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: brand-manifest.json -# timestamp: 2025-11-20T17:15:07+00:00 +# timestamp: 2025-11-20T11:58:34+00:00 from __future__ import annotations diff --git a/src/adcp/types/generated_poc/create_media_buy_response.py b/src/adcp/types/generated_poc/create_media_buy_response.py index ee4bcef6..31451fc5 100644 --- a/src/adcp/types/generated_poc/create_media_buy_response.py +++ b/src/adcp/types/generated_poc/create_media_buy_response.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: create-media-buy-response.json -# timestamp: 2025-11-20T17:15:07+00:00 +# timestamp: 2025-11-20T11:58:34+00:00 from __future__ import annotations diff --git a/src/adcp/types/generated_poc/deployment.py b/src/adcp/types/generated_poc/deployment.py index 0042226d..7bd1db13 100644 --- a/src/adcp/types/generated_poc/deployment.py +++ b/src/adcp/types/generated_poc/deployment.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: deployment.json -# timestamp: 2025-11-20T17:15:07+00:00 +# timestamp: 2025-11-20T20:44:40+00:00 from __future__ import annotations diff --git a/src/adcp/types/generated_poc/destination.py b/src/adcp/types/generated_poc/destination.py index d4817608..78656f8b 100644 --- a/src/adcp/types/generated_poc/destination.py +++ b/src/adcp/types/generated_poc/destination.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: destination.json -# timestamp: 2025-11-20T17:15:07+00:00 +# timestamp: 2025-11-20T20:44:40+00:00 from __future__ import annotations diff --git a/src/adcp/types/generated_poc/format.py b/src/adcp/types/generated_poc/format.py index 804ca2cb..f0563759 100644 --- a/src/adcp/types/generated_poc/format.py +++ b/src/adcp/types/generated_poc/format.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: format.json -# timestamp: 2025-11-20T17:15:07+00:00 +# timestamp: 2025-11-20T11:58:34+00:00 from __future__ import annotations diff --git a/src/adcp/types/generated_poc/format_category.py b/src/adcp/types/generated_poc/format_category.py index 2e7f2ba5..12e5bfa3 100644 --- a/src/adcp/types/generated_poc/format_category.py +++ b/src/adcp/types/generated_poc/format_category.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: format-category.json -# timestamp: 2025-11-20T17:15:07+00:00 +# timestamp: 2025-11-20T11:58:34+00:00 from __future__ import annotations diff --git a/src/adcp/types/generated_poc/get_signals_request.py b/src/adcp/types/generated_poc/get_signals_request.py index 141519ad..34935068 100644 --- a/src/adcp/types/generated_poc/get_signals_request.py +++ b/src/adcp/types/generated_poc/get_signals_request.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: get-signals-request.json -# timestamp: 2025-11-20T17:15:07+00:00 +# timestamp: 2025-11-20T20:44:40+00:00 from __future__ import annotations diff --git a/src/adcp/types/generated_poc/get_signals_response.py b/src/adcp/types/generated_poc/get_signals_response.py index c6b1698c..8f69d8de 100644 --- a/src/adcp/types/generated_poc/get_signals_response.py +++ b/src/adcp/types/generated_poc/get_signals_response.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: get-signals-response.json -# timestamp: 2025-11-20T17:15:07+00:00 +# timestamp: 2025-11-20T20:44:40+00:00 from __future__ import annotations diff --git a/src/adcp/types/generated_poc/list_creative_formats_request.py b/src/adcp/types/generated_poc/list_creative_formats_request.py index ec364b94..ef434434 100644 --- a/src/adcp/types/generated_poc/list_creative_formats_request.py +++ b/src/adcp/types/generated_poc/list_creative_formats_request.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: list-creative-formats-request.json -# timestamp: 2025-11-20T17:15:07+00:00 +# timestamp: 2025-11-20T11:58:34+00:00 from __future__ import annotations diff --git a/src/adcp/types/generated_poc/update_media_buy_response.py b/src/adcp/types/generated_poc/update_media_buy_response.py index 80b40209..3cc4a351 100644 --- a/src/adcp/types/generated_poc/update_media_buy_response.py +++ b/src/adcp/types/generated_poc/update_media_buy_response.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: update-media-buy-response.json -# timestamp: 2025-11-20T17:15:07+00:00 +# timestamp: 2025-11-20T11:58:34+00:00 from __future__ import annotations diff --git a/src/adcp/types/stable.py b/src/adcp/types/stable.py index 8dad698d..2d477f9a 100644 --- a/src/adcp/types/stable.py +++ b/src/adcp/types/stable.py @@ -29,10 +29,9 @@ AggregatedTotals, # Assets Asset, + AssetContentType, # New from PR #222: consolidated asset content types AssetSelectors, AssetsRequired, - AssetType, - AssetTypeSchema, AssignedPackage, Assignments, AudioAsset, @@ -51,7 +50,6 @@ CoBranding, Colors, Contact, - ContentLength, Country, # Pricing options CpcPricingOption, @@ -78,25 +76,23 @@ DeliveryMetrics, DeliveryType, Details, - Dimensions, Direction, Disclaimer, Domain, DomainBreakdown, DoohMetrics, - Duration, Embedding, Error, FeedbackSource, FeedFormat, FieldModel, - FileSize, Filters, FlatRatePricingOption, Fonts, Format, FormatCard, FormatCardDetailed, + FormatCategory, # New from PR #222: format categories (display, video, native, etc.) FormatId, FormatType, FrequencyCap, @@ -170,7 +166,6 @@ PublisherDomain, PublisherIdentifierTypes, PushNotificationConfig, - Quality, QuartileData, QuerySummary, Render, @@ -180,7 +175,6 @@ ReportingWebhook, Request, RequestedMetric, - Requirements, Response, ResponseType, Responsive, @@ -228,10 +222,10 @@ WebhookAsset, WebhookPayload, ) - -# Import all generated types from internal consolidated module -# Import Package from _generated (uses qualified name to avoid collision) -from adcp.types._generated import _PackageFromPackage as Package +from adcp.types._generated import ( + # PR #223 unified responses, no more collision + _PackageFromPackage as Package, +) # Note: BrandManifest is currently split into BrandManifest1/2 due to upstream schema # using anyOf incorrectly. This will be fixed upstream to create a single BrandManifest type. @@ -240,6 +234,11 @@ # Note: BrandManifest is now a single clean type # Re-export BrandManifest directly (no alias needed) +# Backward compatibility notes: +# - AssetType is maintained as an alias to AssetContentType for backward compatibility +# - Will be removed in 3.0.0 +# - Package collision resolved by PR #223 (unified responses) + # Re-export all stable types __all__ = [ # Request/Response types @@ -293,8 +292,9 @@ # Domain types "Asset", "AssetSelectors", - "AssetType", - "AssetTypeSchema", + "AssetContentType", # New canonical name from PR #222 + "AssetType", # Deprecated alias for AssetContentType + "FormatCategory", # New from PR #222 "AssetsRequired", "AssignedPackage", "Assignments", @@ -369,18 +369,14 @@ "VcpmFixedRatePricingOption", # Status enums & simple types "CatalogType", - "ContentLength", "Country", "CreativeStatus", "DaastVersion", "DeliverTo", "DeliveryType", - "Dimensions", "Direction", - "Duration", "FeedbackSource", "FieldModel", - "FileSize", "FormatType", "FrequencyCap", "FrequencyCapScope", @@ -403,7 +399,6 @@ "PropertyType", "PublisherDomain", "PublisherIdentifierTypes", - "Quality", "ResponseType", "Responsive", "SignalType", @@ -434,7 +429,6 @@ "ReportingPeriod", "ReportingWebhook", "RequestedMetric", - "Requirements", "Scheme", "Security", # Assets @@ -450,3 +444,6 @@ "WebhookAsset", "WebhookPayload", ] + +# Deprecated aliases for backward compatibility - will be removed in 3.0.0 +AssetType = AssetContentType # Use AssetContentType instead diff --git a/tests/test_type_aliases.py b/tests/test_type_aliases.py index fd81cb5e..1a76a5d4 100644 --- a/tests/test_type_aliases.py +++ b/tests/test_type_aliases.py @@ -284,78 +284,6 @@ def test_semantic_aliases_can_be_imported_from_main_package(): assert MainTextSubAsset is TextSubAsset -def test_package_type_aliases_imports(): - """Test that Package type alias can be imported.""" - from adcp import Package - from adcp.types import Package as TypesPackage - from adcp.types.aliases import Package as AliasPackage - - # Verify all import paths work - assert Package is TypesPackage - assert Package is AliasPackage - - -def test_package_type_aliases_point_to_correct_modules(): - """Test that Package alias points to the correct generated type.""" - from adcp import Package - from adcp.types._generated import _PackageFromPackage - - # Package should point to the full domain package - assert Package is _PackageFromPackage - - -def test_package_type_aliases_have_correct_fields(): - """Test that Package type alias has the expected fields.""" - from adcp import Package - - # Package should have all operational fields - package_fields = set(Package.__annotations__.keys()) - expected_package_fields = { - "bid_price", - "budget", - "buyer_ref", - "creative_assignments", - "format_ids_to_provide", - "impressions", - "pacing", - "package_id", - "pricing_option_id", - "product_id", - "status", - "targeting_overlay", - } - assert package_fields == expected_package_fields, ( - f"Package fields mismatch. " - f"Expected: {expected_package_fields}, Got: {package_fields}" - ) - - -def test_package_type_aliases_in_exports(): - """Test that Package type alias is properly exported.""" - import adcp - import adcp.types.aliases as aliases_module - - # Check main package exports - assert hasattr(adcp, "Package") - assert "Package" in adcp.__all__ - - # Check aliases module exports - assert hasattr(aliases_module, "Package") - assert "Package" in aliases_module.__all__ - - -def test_package_aliases_can_instantiate(): - """Test that Package type alias can be used to create instances.""" - from adcp import Package - from adcp.types import PackageStatus - - # Create a Package (all required fields) - pkg = Package(package_id="pkg-789", status=PackageStatus.draft) - assert pkg.package_id == "pkg-789" - assert pkg.status == PackageStatus.draft - assert pkg.buyer_ref is None # Optional field - - def test_stable_package_export_is_full_package(): """Test that stable.py exports the Package as Package.""" from adcp.types.stable import Package as StablePackage